From 815ae539f57b7ced245a562c4566162c6ff7b83c Mon Sep 17 00:00:00 2001 From: louis Date: Tue, 28 Apr 2026 21:04:35 +0200 Subject: [PATCH 001/135] Fix meta comment --- nf_core/assets/EDAM_1.25.csv | 3474 ++++++++++++++++++++++++++++++ nf_core/modules/lint/__init__.py | 28 +- nf_core/modules/modules_utils.py | 18 +- 3 files changed, 3506 insertions(+), 14 deletions(-) create mode 100644 nf_core/assets/EDAM_1.25.csv diff --git a/nf_core/assets/EDAM_1.25.csv b/nf_core/assets/EDAM_1.25.csv new file mode 100644 index 0000000000..497367c8f9 --- /dev/null +++ b/nf_core/assets/EDAM_1.25.csv @@ -0,0 +1,3474 @@ +Class ID,Preferred Label,File extension +http://edamontology.org/data_0005,Resource type, +http://edamontology.org/data_0006,Data, +http://edamontology.org/data_0007,Tool, +http://edamontology.org/data_0581,Database, +http://edamontology.org/data_0582,Ontology, +http://edamontology.org/data_0583,Directory metadata, +http://edamontology.org/data_0831,MeSH vocabulary, +http://edamontology.org/data_0832,HGNC vocabulary, +http://edamontology.org/data_0835,UMLS vocabulary, +http://edamontology.org/data_0842,Identifier, +http://edamontology.org/data_0843,Database entry, +http://edamontology.org/data_0844,Molecular mass, +http://edamontology.org/data_0845,Molecular charge, +http://edamontology.org/data_0846,Chemical formula, +http://edamontology.org/data_0847,QSAR descriptor, +http://edamontology.org/data_0848,Raw sequence, +http://edamontology.org/data_0849,Sequence record, +http://edamontology.org/data_0850,Sequence set, +http://edamontology.org/data_0851,Sequence mask character, +http://edamontology.org/data_0852,Sequence mask type, +http://edamontology.org/data_0853,DNA sense specification, +http://edamontology.org/data_0854,Sequence length specification, +http://edamontology.org/data_0855,Sequence metadata, +http://edamontology.org/data_0856,Sequence feature source, +http://edamontology.org/data_0857,Sequence search results, +http://edamontology.org/data_0858,Sequence signature matches, +http://edamontology.org/data_0859,Sequence signature model, +http://edamontology.org/data_0860,Sequence signature data, +http://edamontology.org/data_0861,Sequence alignment (words), +http://edamontology.org/data_0862,Dotplot, +http://edamontology.org/data_0863,Sequence alignment, +http://edamontology.org/data_0864,Sequence alignment parameter, +http://edamontology.org/data_0865,Sequence similarity score, +http://edamontology.org/data_0866,Sequence alignment metadata, +http://edamontology.org/data_0867,Sequence alignment report, +http://edamontology.org/data_0868,Profile-profile alignment, +http://edamontology.org/data_0869,Sequence-profile alignment, +http://edamontology.org/data_0870,Sequence distance matrix, +http://edamontology.org/data_0871,Phylogenetic character data, +http://edamontology.org/data_0872,Phylogenetic tree, +http://edamontology.org/data_0874,Comparison matrix, +http://edamontology.org/data_0875,Protein topology, +http://edamontology.org/data_0876,Protein features report (secondary structure), +http://edamontology.org/data_0877,Protein features report (super-secondary), +http://edamontology.org/data_0878,Protein secondary structure alignment, +http://edamontology.org/data_0879,Secondary structure alignment metadata (protein), +http://edamontology.org/data_0880,RNA secondary structure, +http://edamontology.org/data_0881,RNA secondary structure alignment, +http://edamontology.org/data_0882,Secondary structure alignment metadata (RNA), +http://edamontology.org/data_0883,Structure, +http://edamontology.org/data_0884,Tertiary structure record, +http://edamontology.org/data_0885,Structure database search results, +http://edamontology.org/data_0886,Structure alignment, +http://edamontology.org/data_0887,Structure alignment report, +http://edamontology.org/data_0888,Structure similarity score, +http://edamontology.org/data_0889,Structural profile, +http://edamontology.org/data_0890,Structural (3D) profile alignment, +http://edamontology.org/data_0891,Sequence-3D profile alignment, +http://edamontology.org/data_0892,Protein sequence-structure scoring matrix, +http://edamontology.org/data_0893,Sequence-structure alignment, +http://edamontology.org/data_0894,Amino acid annotation, +http://edamontology.org/data_0895,Peptide annotation, +http://edamontology.org/data_0896,Protein report, +http://edamontology.org/data_0897,Protein property, +http://edamontology.org/data_0899,Protein structural motifs and surfaces, +http://edamontology.org/data_0900,Protein domain classification, +http://edamontology.org/data_0901,Protein features report (domains), +http://edamontology.org/data_0902,Protein architecture report, +http://edamontology.org/data_0903,Protein folding report, +http://edamontology.org/data_0904,Protein features (mutation), +http://edamontology.org/data_0905,Protein interaction raw data, +http://edamontology.org/data_0906,Protein interaction data, +http://edamontology.org/data_0907,Protein family report, +http://edamontology.org/data_0909,Vmax, +http://edamontology.org/data_0910,Km, +http://edamontology.org/data_0911,Nucleotide base annotation, +http://edamontology.org/data_0912,Nucleic acid property, +http://edamontology.org/data_0914,Codon usage data, +http://edamontology.org/data_0916,Gene report, +http://edamontology.org/data_0917,Gene classification, +http://edamontology.org/data_0918,DNA variation, +http://edamontology.org/data_0919,Chromosome report, +http://edamontology.org/data_0920,Genotype/phenotype report, +http://edamontology.org/data_0923,PCR experiment report, +http://edamontology.org/data_0924,Sequence trace, +http://edamontology.org/data_0925,Sequence assembly, +http://edamontology.org/data_0926,RH scores, +http://edamontology.org/data_0927,Genetic linkage report, +http://edamontology.org/data_0928,Gene expression profile, +http://edamontology.org/data_0931,Microarray experiment report, +http://edamontology.org/data_0932,Oligonucleotide probe data, +http://edamontology.org/data_0933,SAGE experimental data, +http://edamontology.org/data_0934,MPSS experimental data, +http://edamontology.org/data_0935,SBS experimental data, +http://edamontology.org/data_0936,Sequence tag profile (with gene assignment), +http://edamontology.org/data_0937,Electron density map, +http://edamontology.org/data_0938,Raw NMR data, +http://edamontology.org/data_0939,CD spectra, +http://edamontology.org/data_0940,Volume map, +http://edamontology.org/data_0941,Electron microscopy model, +http://edamontology.org/data_0942,2D PAGE image, +http://edamontology.org/data_0943,Mass spectrum, +http://edamontology.org/data_0944,Peptide mass fingerprint, +http://edamontology.org/data_0945,Peptide identification, +http://edamontology.org/data_0946,Pathway or network annotation, +http://edamontology.org/data_0947,Biological pathway map, +http://edamontology.org/data_0948,Data resource definition, +http://edamontology.org/data_0949,Workflow metadata, +http://edamontology.org/data_0950,Mathematical model, +http://edamontology.org/data_0951,Statistical estimate score, +http://edamontology.org/data_0952,EMBOSS database resource definition, +http://edamontology.org/data_0953,Version information, +http://edamontology.org/data_0954,Database cross-mapping, +http://edamontology.org/data_0955,Data index, +http://edamontology.org/data_0956,Data index report, +http://edamontology.org/data_0957,Database metadata, +http://edamontology.org/data_0958,Tool metadata, +http://edamontology.org/data_0959,Job metadata, +http://edamontology.org/data_0960,User metadata, +http://edamontology.org/data_0962,Small molecule report, +http://edamontology.org/data_0963,Cell line report, +http://edamontology.org/data_0964,Scent annotation, +http://edamontology.org/data_0966,Ontology term, +http://edamontology.org/data_0967,Ontology concept data, +http://edamontology.org/data_0968,Keyword, +http://edamontology.org/data_0970,Citation, +http://edamontology.org/data_0971,Article, +http://edamontology.org/data_0972,Text mining report, +http://edamontology.org/data_0974,Entity identifier, +http://edamontology.org/data_0975,Data resource identifier, +http://edamontology.org/data_0976,Identifier (by type of data), +http://edamontology.org/data_0977,Tool identifier, +http://edamontology.org/data_0978,Discrete entity identifier, +http://edamontology.org/data_0979,Entity feature identifier, +http://edamontology.org/data_0980,Entity collection identifier, +http://edamontology.org/data_0981,Phenomenon identifier, +http://edamontology.org/data_0982,Molecule identifier, +http://edamontology.org/data_0983,Atom ID, +http://edamontology.org/data_0984,Molecule name, +http://edamontology.org/data_0985,Molecule type, +http://edamontology.org/data_0986,Chemical identifier, +http://edamontology.org/data_0987,Chromosome name, +http://edamontology.org/data_0988,Peptide identifier, +http://edamontology.org/data_0989,Protein identifier, +http://edamontology.org/data_0990,Compound name, +http://edamontology.org/data_0991,Chemical registry number, +http://edamontology.org/data_0992,Ligand identifier, +http://edamontology.org/data_0993,Drug identifier, +http://edamontology.org/data_0994,Amino acid identifier, +http://edamontology.org/data_0995,Nucleotide identifier, +http://edamontology.org/data_0996,Monosaccharide identifier, +http://edamontology.org/data_0997,Chemical name (ChEBI), +http://edamontology.org/data_0998,Chemical name (IUPAC), +http://edamontology.org/data_0999,Chemical name (INN), +http://edamontology.org/data_1000,Chemical name (brand), +http://edamontology.org/data_1001,Chemical name (synonymous), +http://edamontology.org/data_1002,CAS number, +http://edamontology.org/data_1003,Chemical registry number (Beilstein), +http://edamontology.org/data_1004,Chemical registry number (Gmelin), +http://edamontology.org/data_1005,HET group name, +http://edamontology.org/data_1006,Amino acid name, +http://edamontology.org/data_1007,Nucleotide code, +http://edamontology.org/data_1008,Polypeptide chain ID, +http://edamontology.org/data_1009,Protein name, +http://edamontology.org/data_1010,Enzyme identifier, +http://edamontology.org/data_1011,EC number, +http://edamontology.org/data_1012,Enzyme name, +http://edamontology.org/data_1013,Restriction enzyme name, +http://edamontology.org/data_1014,Sequence position specification, +http://edamontology.org/data_1015,Sequence feature ID, +http://edamontology.org/data_1016,Sequence position, +http://edamontology.org/data_1017,Sequence range, +http://edamontology.org/data_1018,Nucleic acid feature identifier, +http://edamontology.org/data_1019,Protein feature identifier, +http://edamontology.org/data_1020,Sequence feature key, +http://edamontology.org/data_1021,Sequence feature qualifier, +http://edamontology.org/data_1022,Sequence feature label, +http://edamontology.org/data_1023,EMBOSS Uniform Feature Object, +http://edamontology.org/data_1024,Codon name, +http://edamontology.org/data_1025,Gene identifier, +http://edamontology.org/data_1026,Gene symbol, +http://edamontology.org/data_1027,Gene ID (NCBI), +http://edamontology.org/data_1028,Gene identifier (NCBI RefSeq), +http://edamontology.org/data_1029,Gene identifier (NCBI UniGene), +http://edamontology.org/data_1030,Gene identifier (Entrez), +http://edamontology.org/data_1031,Gene ID (CGD), +http://edamontology.org/data_1032,Gene ID (DictyBase), +http://edamontology.org/data_1033,Ensembl gene ID, +http://edamontology.org/data_1034,Gene ID (SGD), +http://edamontology.org/data_1035,Gene ID (GeneDB), +http://edamontology.org/data_1036,TIGR identifier, +http://edamontology.org/data_1037,TAIR accession (gene), +http://edamontology.org/data_1038,Protein domain ID, +http://edamontology.org/data_1039,SCOP domain identifier, +http://edamontology.org/data_1040,CATH domain ID, +http://edamontology.org/data_1041,SCOP concise classification string (sccs), +http://edamontology.org/data_1042,SCOP sunid, +http://edamontology.org/data_1043,CATH node ID, +http://edamontology.org/data_1044,Kingdom name, +http://edamontology.org/data_1045,Species name, +http://edamontology.org/data_1046,Strain name, +http://edamontology.org/data_1047,URI, +http://edamontology.org/data_1048,Database ID, +http://edamontology.org/data_1049,Directory name, +http://edamontology.org/data_1050,File name, +http://edamontology.org/data_1051,Ontology name, +http://edamontology.org/data_1052,URL, +http://edamontology.org/data_1053,URN, +http://edamontology.org/data_1055,LSID, +http://edamontology.org/data_1056,Database name, +http://edamontology.org/data_1057,Sequence database name, +http://edamontology.org/data_1058,Enumerated file name, +http://edamontology.org/data_1059,File name extension, +http://edamontology.org/data_1060,File base name, +http://edamontology.org/data_1061,QSAR descriptor name, +http://edamontology.org/data_1062,Database entry identifier, +http://edamontology.org/data_1063,Sequence identifier, +http://edamontology.org/data_1064,Sequence set ID, +http://edamontology.org/data_1065,Sequence signature identifier, +http://edamontology.org/data_1066,Sequence alignment ID, +http://edamontology.org/data_1067,Phylogenetic distance matrix identifier, +http://edamontology.org/data_1068,Phylogenetic tree ID, +http://edamontology.org/data_1069,Comparison matrix identifier, +http://edamontology.org/data_1070,Structure ID, +http://edamontology.org/data_1071,Structural (3D) profile ID, +http://edamontology.org/data_1072,Structure alignment ID, +http://edamontology.org/data_1073,Amino acid index ID, +http://edamontology.org/data_1074,Protein interaction ID, +http://edamontology.org/data_1075,Protein family identifier, +http://edamontology.org/data_1076,Codon usage table name, +http://edamontology.org/data_1077,Transcription factor identifier, +http://edamontology.org/data_1078,Experiment annotation ID, +http://edamontology.org/data_1079,Electron microscopy model ID, +http://edamontology.org/data_1080,Gene expression report ID, +http://edamontology.org/data_1081,Genotype and phenotype annotation ID, +http://edamontology.org/data_1082,Pathway or network identifier, +http://edamontology.org/data_1083,Workflow ID, +http://edamontology.org/data_1084,Data resource definition ID, +http://edamontology.org/data_1085,Biological model ID, +http://edamontology.org/data_1086,Compound identifier, +http://edamontology.org/data_1087,Ontology concept ID, +http://edamontology.org/data_1088,Article ID, +http://edamontology.org/data_1089,FlyBase ID, +http://edamontology.org/data_1091,WormBase name, +http://edamontology.org/data_1092,WormBase class, +http://edamontology.org/data_1093,Sequence accession, +http://edamontology.org/data_1094,Sequence type, +http://edamontology.org/data_1095,EMBOSS Uniform Sequence Address, +http://edamontology.org/data_1096,Sequence accession (protein), +http://edamontology.org/data_1097,Sequence accession (nucleic acid), +http://edamontology.org/data_1098,RefSeq accession, +http://edamontology.org/data_1099,UniProt accession (extended), +http://edamontology.org/data_1100,PIR identifier, +http://edamontology.org/data_1101,TREMBL accession, +http://edamontology.org/data_1102,Gramene primary identifier, +http://edamontology.org/data_1103,EMBL/GenBank/DDBJ ID, +http://edamontology.org/data_1104,Sequence cluster ID (UniGene), +http://edamontology.org/data_1105,dbEST accession, +http://edamontology.org/data_1106,dbSNP ID, +http://edamontology.org/data_1110,EMBOSS sequence type, +http://edamontology.org/data_1111,EMBOSS listfile, +http://edamontology.org/data_1112,Sequence cluster ID, +http://edamontology.org/data_1113,Sequence cluster ID (COG), +http://edamontology.org/data_1114,Sequence motif identifier, +http://edamontology.org/data_1115,Sequence profile ID, +http://edamontology.org/data_1116,ELM ID, +http://edamontology.org/data_1117,Prosite accession number, +http://edamontology.org/data_1118,HMMER hidden Markov model ID, +http://edamontology.org/data_1119,JASPAR profile ID, +http://edamontology.org/data_1120,Sequence alignment type, +http://edamontology.org/data_1121,BLAST sequence alignment type, +http://edamontology.org/data_1122,Phylogenetic tree type, +http://edamontology.org/data_1123,TreeBASE study accession number, +http://edamontology.org/data_1124,TreeFam accession number, +http://edamontology.org/data_1125,Comparison matrix type, +http://edamontology.org/data_1126,Comparison matrix name, +http://edamontology.org/data_1127,PDB ID, +http://edamontology.org/data_1128,AAindex ID, +http://edamontology.org/data_1129,BIND accession number, +http://edamontology.org/data_1130,IntAct accession number, +http://edamontology.org/data_1131,Protein family name, +http://edamontology.org/data_1132,InterPro entry name, +http://edamontology.org/data_1133,InterPro accession, +http://edamontology.org/data_1134,InterPro secondary accession, +http://edamontology.org/data_1135,Gene3D ID, +http://edamontology.org/data_1136,PIRSF ID, +http://edamontology.org/data_1137,PRINTS code, +http://edamontology.org/data_1138,Pfam accession number, +http://edamontology.org/data_1139,SMART accession number, +http://edamontology.org/data_1140,Superfamily hidden Markov model number, +http://edamontology.org/data_1141,TIGRFam ID, +http://edamontology.org/data_1142,ProDom accession number, +http://edamontology.org/data_1143,TRANSFAC accession number, +http://edamontology.org/data_1144,ArrayExpress accession number, +http://edamontology.org/data_1145,PRIDE experiment accession number, +http://edamontology.org/data_1146,EMDB ID, +http://edamontology.org/data_1147,GEO accession number, +http://edamontology.org/data_1148,GermOnline ID, +http://edamontology.org/data_1149,EMAGE ID, +http://edamontology.org/data_1150,Disease ID, +http://edamontology.org/data_1151,HGVbase ID, +http://edamontology.org/data_1152,HIVDB identifier, +http://edamontology.org/data_1153,OMIM ID, +http://edamontology.org/data_1154,KEGG object identifier, +http://edamontology.org/data_1155,Pathway ID (reactome), +http://edamontology.org/data_1156,Pathway ID (aMAZE), +http://edamontology.org/data_1157,Pathway ID (BioCyc), +http://edamontology.org/data_1158,Pathway ID (INOH), +http://edamontology.org/data_1159,Pathway ID (PATIKA), +http://edamontology.org/data_1160,Pathway ID (CPDB), +http://edamontology.org/data_1161,Pathway ID (Panther), +http://edamontology.org/data_1162,MIRIAM identifier, +http://edamontology.org/data_1163,MIRIAM data type name, +http://edamontology.org/data_1164,MIRIAM URI, +http://edamontology.org/data_1165,MIRIAM data type primary name, +http://edamontology.org/data_1166,MIRIAM data type synonymous name, +http://edamontology.org/data_1167,Taverna workflow ID, +http://edamontology.org/data_1170,Biological model name, +http://edamontology.org/data_1171,BioModel ID, +http://edamontology.org/data_1172,PubChem CID, +http://edamontology.org/data_1173,ChemSpider ID, +http://edamontology.org/data_1174,ChEBI ID, +http://edamontology.org/data_1175,BioPax concept ID, +http://edamontology.org/data_1176,GO concept ID, +http://edamontology.org/data_1177,MeSH concept ID, +http://edamontology.org/data_1178,HGNC concept ID, +http://edamontology.org/data_1179,NCBI taxonomy ID, +http://edamontology.org/data_1180,Plant Ontology concept ID, +http://edamontology.org/data_1181,UMLS concept ID, +http://edamontology.org/data_1182,FMA concept ID, +http://edamontology.org/data_1183,EMAP concept ID, +http://edamontology.org/data_1184,ChEBI concept ID, +http://edamontology.org/data_1185,MGED concept ID, +http://edamontology.org/data_1186,myGrid concept ID, +http://edamontology.org/data_1187,PubMed ID, +http://edamontology.org/data_1188,DOI, +http://edamontology.org/data_1189,Medline UI, +http://edamontology.org/data_1190,Tool name, +http://edamontology.org/data_1191,Tool name (signature), +http://edamontology.org/data_1192,Tool name (BLAST), +http://edamontology.org/data_1193,Tool name (FASTA), +http://edamontology.org/data_1194,Tool name (EMBOSS), +http://edamontology.org/data_1195,Tool name (EMBASSY package), +http://edamontology.org/data_1201,QSAR descriptor (constitutional), +http://edamontology.org/data_1202,QSAR descriptor (electronic), +http://edamontology.org/data_1203,QSAR descriptor (geometrical), +http://edamontology.org/data_1204,QSAR descriptor (topological), +http://edamontology.org/data_1205,QSAR descriptor (molecular), +http://edamontology.org/data_1233,Sequence set (protein), +http://edamontology.org/data_1234,Sequence set (nucleic acid), +http://edamontology.org/data_1235,Sequence cluster, +http://edamontology.org/data_1236,Psiblast checkpoint file, +http://edamontology.org/data_1237,HMMER synthetic sequences set, +http://edamontology.org/data_1238,Proteolytic digest, +http://edamontology.org/data_1239,Restriction digest, +http://edamontology.org/data_1240,PCR primers, +http://edamontology.org/data_1241,vectorstrip cloning vector definition file, +http://edamontology.org/data_1242,Primer3 internal oligo mishybridizing library, +http://edamontology.org/data_1243,Primer3 mispriming library file, +http://edamontology.org/data_1244,primersearch primer pairs sequence record, +http://edamontology.org/data_1245,Sequence cluster (protein), +http://edamontology.org/data_1246,Sequence cluster (nucleic acid), +http://edamontology.org/data_1249,Sequence length, +http://edamontology.org/data_1250,Word size, +http://edamontology.org/data_1251,Window size, +http://edamontology.org/data_1252,Sequence length range, +http://edamontology.org/data_1253,Sequence information report, +http://edamontology.org/data_1254,Sequence property, +http://edamontology.org/data_1255,Sequence features, +http://edamontology.org/data_1256,Sequence features (comparative), +http://edamontology.org/data_1257,Sequence property (protein), +http://edamontology.org/data_1258,Sequence property (nucleic acid), +http://edamontology.org/data_1259,Sequence complexity report, +http://edamontology.org/data_1260,Sequence ambiguity report, +http://edamontology.org/data_1261,Sequence composition report, +http://edamontology.org/data_1262,Peptide molecular weight hits, +http://edamontology.org/data_1263,Base position variability plot, +http://edamontology.org/data_1264,Sequence composition table, +http://edamontology.org/data_1265,Base frequencies table, +http://edamontology.org/data_1266,Base word frequencies table, +http://edamontology.org/data_1267,Amino acid frequencies table, +http://edamontology.org/data_1268,Amino acid word frequencies table, +http://edamontology.org/data_1269,DAS sequence feature annotation, +http://edamontology.org/data_1270,Feature table, +http://edamontology.org/data_1274,Map, +http://edamontology.org/data_1276,Nucleic acid features, +http://edamontology.org/data_1277,Protein features, +http://edamontology.org/data_1278,Genetic map, +http://edamontology.org/data_1279,Sequence map, +http://edamontology.org/data_1280,Physical map, +http://edamontology.org/data_1281,Sequence signature map, +http://edamontology.org/data_1283,Cytogenetic map, +http://edamontology.org/data_1284,DNA transduction map, +http://edamontology.org/data_1285,Gene map, +http://edamontology.org/data_1286,Plasmid map, +http://edamontology.org/data_1288,Genome map, +http://edamontology.org/data_1289,Restriction map, +http://edamontology.org/data_1290,InterPro compact match image, +http://edamontology.org/data_1291,InterPro detailed match image, +http://edamontology.org/data_1292,InterPro architecture image, +http://edamontology.org/data_1293,SMART protein schematic, +http://edamontology.org/data_1294,GlobPlot domain image, +http://edamontology.org/data_1298,Sequence motif matches, +http://edamontology.org/data_1299,Sequence features (repeats), +http://edamontology.org/data_1300,Gene and transcript structure (report), +http://edamontology.org/data_1301,Mobile genetic elements, +http://edamontology.org/data_1303,Nucleic acid features (quadruplexes), +http://edamontology.org/data_1306,Nucleosome exclusion sequences, +http://edamontology.org/data_1309,Gene features (exonic splicing enhancer), +http://edamontology.org/data_1310,Nucleic acid features (microRNA), +http://edamontology.org/data_1313,Coding region, +http://edamontology.org/data_1314,Gene features (SECIS element), +http://edamontology.org/data_1315,Transcription factor binding sites, +http://edamontology.org/data_1321,Protein features (sites), +http://edamontology.org/data_1322,Protein features report (signal peptides), +http://edamontology.org/data_1323,Protein features report (cleavage sites), +http://edamontology.org/data_1324,Protein features (post-translation modifications), +http://edamontology.org/data_1325,Protein features report (active sites), +http://edamontology.org/data_1326,Protein features report (binding sites), +http://edamontology.org/data_1327,Protein features (epitopes), +http://edamontology.org/data_1328,Protein features report (nucleic acid binding sites), +http://edamontology.org/data_1329,MHC Class I epitopes report, +http://edamontology.org/data_1330,MHC Class II epitopes report, +http://edamontology.org/data_1331,Protein features (PEST sites), +http://edamontology.org/data_1338,Sequence database hits scores list, +http://edamontology.org/data_1339,Sequence database hits alignments list, +http://edamontology.org/data_1340,Sequence database hits evaluation data, +http://edamontology.org/data_1344,MEME motif alphabet, +http://edamontology.org/data_1345,MEME background frequencies file, +http://edamontology.org/data_1346,MEME motifs directive file, +http://edamontology.org/data_1347,Dirichlet distribution, +http://edamontology.org/data_1348,HMM emission and transition counts, +http://edamontology.org/data_1352,Regular expression, +http://edamontology.org/data_1353,Sequence motif, +http://edamontology.org/data_1354,Sequence profile, +http://edamontology.org/data_1355,Protein signature, +http://edamontology.org/data_1358,Prosite nucleotide pattern, +http://edamontology.org/data_1359,Prosite protein pattern, +http://edamontology.org/data_1361,Position frequency matrix, +http://edamontology.org/data_1362,Position weight matrix, +http://edamontology.org/data_1363,Information content matrix, +http://edamontology.org/data_1364,Hidden Markov model, +http://edamontology.org/data_1365,Fingerprint, +http://edamontology.org/data_1368,Domainatrix signature, +http://edamontology.org/data_1371,HMMER NULL hidden Markov model, +http://edamontology.org/data_1372,Protein family signature, +http://edamontology.org/data_1373,Protein domain signature, +http://edamontology.org/data_1374,Protein region signature, +http://edamontology.org/data_1375,Protein repeat signature, +http://edamontology.org/data_1376,Protein site signature, +http://edamontology.org/data_1377,Protein conserved site signature, +http://edamontology.org/data_1378,Protein active site signature, +http://edamontology.org/data_1379,Protein binding site signature, +http://edamontology.org/data_1380,Protein post-translational modification signature, +http://edamontology.org/data_1381,Pair sequence alignment, +http://edamontology.org/data_1382,Sequence alignment (multiple), +http://edamontology.org/data_1383,Nucleic acid sequence alignment, +http://edamontology.org/data_1384,Protein sequence alignment, +http://edamontology.org/data_1385,Hybrid sequence alignment, +http://edamontology.org/data_1386,Sequence alignment (nucleic acid pair), +http://edamontology.org/data_1387,Sequence alignment (protein pair), +http://edamontology.org/data_1388,Hybrid sequence alignment (pair), +http://edamontology.org/data_1389,Multiple nucleotide sequence alignment, +http://edamontology.org/data_1390,Multiple protein sequence alignment, +http://edamontology.org/data_1394,Alignment score or penalty, +http://edamontology.org/data_1395,Score end gaps control, +http://edamontology.org/data_1396,Aligned sequence order, +http://edamontology.org/data_1397,Gap opening penalty, +http://edamontology.org/data_1398,Gap extension penalty, +http://edamontology.org/data_1399,Gap separation penalty, +http://edamontology.org/data_1400,Terminal gap penalty, +http://edamontology.org/data_1401,Match reward score, +http://edamontology.org/data_1402,Mismatch penalty score, +http://edamontology.org/data_1403,Drop off score, +http://edamontology.org/data_1404,Gap opening penalty (integer), +http://edamontology.org/data_1405,Gap opening penalty (float), +http://edamontology.org/data_1406,Gap extension penalty (integer), +http://edamontology.org/data_1407,Gap extension penalty (float), +http://edamontology.org/data_1408,Gap separation penalty (integer), +http://edamontology.org/data_1409,Gap separation penalty (float), +http://edamontology.org/data_1410,Terminal gap opening penalty, +http://edamontology.org/data_1411,Terminal gap extension penalty, +http://edamontology.org/data_1412,Sequence identity, +http://edamontology.org/data_1413,Sequence similarity, +http://edamontology.org/data_1414,Sequence alignment metadata (quality report), +http://edamontology.org/data_1415,Sequence alignment report (site conservation), +http://edamontology.org/data_1416,Sequence alignment report (site correlation), +http://edamontology.org/data_1417,Sequence-profile alignment (Domainatrix signature), +http://edamontology.org/data_1418,Sequence-profile alignment (HMM), +http://edamontology.org/data_1420,Sequence-profile alignment (fingerprint), +http://edamontology.org/data_1426,Phylogenetic continuous quantitative data, +http://edamontology.org/data_1427,Phylogenetic discrete data, +http://edamontology.org/data_1428,Phylogenetic character cliques, +http://edamontology.org/data_1429,Phylogenetic invariants, +http://edamontology.org/data_1438,Phylogenetic report, +http://edamontology.org/data_1439,DNA substitution model, +http://edamontology.org/data_1440,Phylogenetic tree report (tree shape), +http://edamontology.org/data_1441,Phylogenetic tree report (tree evaluation), +http://edamontology.org/data_1442,Phylogenetic tree distances, +http://edamontology.org/data_1443,Phylogenetic tree report (tree stratigraphic), +http://edamontology.org/data_1444,Phylogenetic character contrasts, +http://edamontology.org/data_1446,Comparison matrix (integers), +http://edamontology.org/data_1447,Comparison matrix (floats), +http://edamontology.org/data_1448,Comparison matrix (nucleotide), +http://edamontology.org/data_1449,Comparison matrix (amino acid), +http://edamontology.org/data_1450,Nucleotide comparison matrix (integers), +http://edamontology.org/data_1451,Nucleotide comparison matrix (floats), +http://edamontology.org/data_1452,Amino acid comparison matrix (integers), +http://edamontology.org/data_1453,Amino acid comparison matrix (floats), +http://edamontology.org/data_1459,Nucleic acid structure, +http://edamontology.org/data_1460,Protein structure, +http://edamontology.org/data_1461,Protein-ligand complex, +http://edamontology.org/data_1462,Carbohydrate structure, +http://edamontology.org/data_1463,Small molecule structure, +http://edamontology.org/data_1464,DNA structure, +http://edamontology.org/data_1465,RNA structure, +http://edamontology.org/data_1466,tRNA structure, +http://edamontology.org/data_1467,Protein chain, +http://edamontology.org/data_1468,Protein domain, +http://edamontology.org/data_1469,Protein structure (all atoms), +http://edamontology.org/data_1470,C-alpha trace, +http://edamontology.org/data_1471,Protein chain (all atoms), +http://edamontology.org/data_1472,Protein chain (C-alpha atoms), +http://edamontology.org/data_1473,Protein domain (all atoms), +http://edamontology.org/data_1474,Protein domain (C-alpha atoms), +http://edamontology.org/data_1479,Structure alignment (pair), +http://edamontology.org/data_1480,Structure alignment (multiple), +http://edamontology.org/data_1481,Protein structure alignment, +http://edamontology.org/data_1482,Nucleic acid structure alignment, +http://edamontology.org/data_1483,Structure alignment (protein pair), +http://edamontology.org/data_1484,Multiple protein tertiary structure alignment, +http://edamontology.org/data_1485,Structure alignment (protein all atoms), +http://edamontology.org/data_1486,Structure alignment (protein C-alpha atoms), +http://edamontology.org/data_1487,Pairwise protein tertiary structure alignment (all atoms), +http://edamontology.org/data_1488,Pairwise protein tertiary structure alignment (C-alpha atoms), +http://edamontology.org/data_1489,Multiple protein tertiary structure alignment (all atoms), +http://edamontology.org/data_1490,Multiple protein tertiary structure alignment (C-alpha atoms), +http://edamontology.org/data_1491,Structure alignment (nucleic acid pair), +http://edamontology.org/data_1492,Multiple nucleic acid tertiary structure alignment, +http://edamontology.org/data_1493,RNA structure alignment, +http://edamontology.org/data_1494,Structural transformation matrix, +http://edamontology.org/data_1495,DaliLite hit table, +http://edamontology.org/data_1496,Molecular similarity score, +http://edamontology.org/data_1497,Root-mean-square deviation, +http://edamontology.org/data_1498,Tanimoto similarity score, +http://edamontology.org/data_1499,3D-1D scoring matrix, +http://edamontology.org/data_1501,Amino acid index, +http://edamontology.org/data_1502,Amino acid index (chemical classes), +http://edamontology.org/data_1503,Amino acid pair-wise contact potentials, +http://edamontology.org/data_1505,Amino acid index (molecular weight), +http://edamontology.org/data_1506,Amino acid index (hydropathy), +http://edamontology.org/data_1507,Amino acid index (White-Wimley data), +http://edamontology.org/data_1508,Amino acid index (van der Waals radii), +http://edamontology.org/data_1509,Enzyme report, +http://edamontology.org/data_1517,Restriction enzyme report, +http://edamontology.org/data_1519,Peptide molecular weights, +http://edamontology.org/data_1520,Peptide hydrophobic moment, +http://edamontology.org/data_1521,Protein aliphatic index, +http://edamontology.org/data_1522,Protein sequence hydropathy plot, +http://edamontology.org/data_1523,Protein charge plot, +http://edamontology.org/data_1524,Protein solubility, +http://edamontology.org/data_1525,Protein crystallizability, +http://edamontology.org/data_1526,Protein globularity, +http://edamontology.org/data_1527,Protein titration curve, +http://edamontology.org/data_1528,Protein isoelectric point, +http://edamontology.org/data_1529,Protein pKa value, +http://edamontology.org/data_1530,Protein hydrogen exchange rate, +http://edamontology.org/data_1531,Protein extinction coefficient, +http://edamontology.org/data_1532,Protein optical density, +http://edamontology.org/data_1533,Protein subcellular localisation, +http://edamontology.org/data_1534,Peptide immunogenicity data, +http://edamontology.org/data_1536,MHC peptide immunogenicity report, +http://edamontology.org/data_1537,Protein structure report, +http://edamontology.org/data_1539,Protein structural quality report, +http://edamontology.org/data_1540,Protein non-covalent interactions report, +http://edamontology.org/data_1541,Protein flexibility or motion report, +http://edamontology.org/data_1542,Protein solvent accessibility, +http://edamontology.org/data_1543,Protein surface report, +http://edamontology.org/data_1544,Ramachandran plot, +http://edamontology.org/data_1545,Protein dipole moment, +http://edamontology.org/data_1546,Protein distance matrix, +http://edamontology.org/data_1547,Protein contact map, +http://edamontology.org/data_1548,Protein residue 3D cluster, +http://edamontology.org/data_1549,Protein hydrogen bonds, +http://edamontology.org/data_1550,Protein non-canonical interactions, +http://edamontology.org/data_1553,CATH node, +http://edamontology.org/data_1554,SCOP node, +http://edamontology.org/data_1555,EMBASSY domain classification, +http://edamontology.org/data_1556,CATH class, +http://edamontology.org/data_1557,CATH architecture, +http://edamontology.org/data_1558,CATH topology, +http://edamontology.org/data_1559,CATH homologous superfamily, +http://edamontology.org/data_1560,CATH structurally similar group, +http://edamontology.org/data_1561,CATH functional category, +http://edamontology.org/data_1564,Protein fold recognition report, +http://edamontology.org/data_1565,Protein-protein interaction report, +http://edamontology.org/data_1566,Protein-ligand interaction report, +http://edamontology.org/data_1567,Protein-nucleic acid interactions report, +http://edamontology.org/data_1583,Nucleic acid melting profile, +http://edamontology.org/data_1584,Nucleic acid enthalpy, +http://edamontology.org/data_1585,Nucleic acid entropy, +http://edamontology.org/data_1586,Nucleic acid melting temperature, +http://edamontology.org/data_1587,Nucleic acid stitch profile, +http://edamontology.org/data_1588,DNA base pair stacking energies data, +http://edamontology.org/data_1589,DNA base pair twist angle data, +http://edamontology.org/data_1590,DNA base trimer roll angles data, +http://edamontology.org/data_1591,Vienna RNA parameters, +http://edamontology.org/data_1592,Vienna RNA structure constraints, +http://edamontology.org/data_1593,Vienna RNA concentration data, +http://edamontology.org/data_1594,Vienna RNA calculated energy, +http://edamontology.org/data_1595,Base pairing probability matrix dotplot, +http://edamontology.org/data_1596,Nucleic acid folding report, +http://edamontology.org/data_1597,Codon usage table, +http://edamontology.org/data_1598,Genetic code, +http://edamontology.org/data_1599,Codon adaptation index, +http://edamontology.org/data_1600,Codon usage bias plot, +http://edamontology.org/data_1601,Nc statistic, +http://edamontology.org/data_1602,Codon usage fraction difference, +http://edamontology.org/data_1621,Pharmacogenomic test report, +http://edamontology.org/data_1622,Disease report, +http://edamontology.org/data_1634,Linkage disequilibrium (report), +http://edamontology.org/data_1636,Heat map, +http://edamontology.org/data_1642,Affymetrix probe sets library file, +http://edamontology.org/data_1643,Affymetrix probe sets information library file, +http://edamontology.org/data_1646,Molecular weights standard fingerprint, +http://edamontology.org/data_1656,Metabolic pathway report, +http://edamontology.org/data_1657,Genetic information processing pathway report, +http://edamontology.org/data_1658,Environmental information processing pathway report, +http://edamontology.org/data_1659,Signal transduction pathway report, +http://edamontology.org/data_1660,Cellular process pathways report, +http://edamontology.org/data_1661,Disease pathway or network report, +http://edamontology.org/data_1662,Drug structure relationship map, +http://edamontology.org/data_1663,Protein interaction networks, +http://edamontology.org/data_1664,MIRIAM datatype, +http://edamontology.org/data_1667,E-value, +http://edamontology.org/data_1668,Z-value, +http://edamontology.org/data_1669,P-value, +http://edamontology.org/data_1670,Database version information, +http://edamontology.org/data_1671,Tool version information, +http://edamontology.org/data_1672,CATH version information, +http://edamontology.org/data_1673,Swiss-Prot to PDB mapping, +http://edamontology.org/data_1674,Sequence database cross-references, +http://edamontology.org/data_1675,Job status, +http://edamontology.org/data_1676,Job ID, +http://edamontology.org/data_1677,Job type, +http://edamontology.org/data_1678,Tool log, +http://edamontology.org/data_1679,DaliLite log file, +http://edamontology.org/data_1680,STRIDE log file, +http://edamontology.org/data_1681,NACCESS log file, +http://edamontology.org/data_1682,EMBOSS wordfinder log file, +http://edamontology.org/data_1683,EMBOSS domainatrix log file, +http://edamontology.org/data_1684,EMBOSS sites log file, +http://edamontology.org/data_1685,EMBOSS supermatcher error file, +http://edamontology.org/data_1686,EMBOSS megamerger log file, +http://edamontology.org/data_1687,EMBOSS whichdb log file, +http://edamontology.org/data_1688,EMBOSS vectorstrip log file, +http://edamontology.org/data_1689,Username, +http://edamontology.org/data_1690,Password, +http://edamontology.org/data_1691,Email address, +http://edamontology.org/data_1692,Person name, +http://edamontology.org/data_1693,Number of iterations, +http://edamontology.org/data_1694,Number of output entities, +http://edamontology.org/data_1695,Hit sort order, +http://edamontology.org/data_1696,Drug report, +http://edamontology.org/data_1707,Phylogenetic tree image, +http://edamontology.org/data_1708,RNA secondary structure image, +http://edamontology.org/data_1709,Protein secondary structure image, +http://edamontology.org/data_1710,Structure image, +http://edamontology.org/data_1711,Sequence alignment image, +http://edamontology.org/data_1712,Chemical structure image, +http://edamontology.org/data_1713,Fate map, +http://edamontology.org/data_1714,Microarray spots image, +http://edamontology.org/data_1715,BioPax term, +http://edamontology.org/data_1716,GO, +http://edamontology.org/data_1717,MeSH, +http://edamontology.org/data_1718,HGNC, +http://edamontology.org/data_1719,NCBI taxonomy vocabulary, +http://edamontology.org/data_1720,Plant ontology term, +http://edamontology.org/data_1721,UMLS, +http://edamontology.org/data_1722,FMA, +http://edamontology.org/data_1723,EMAP, +http://edamontology.org/data_1724,ChEBI, +http://edamontology.org/data_1725,MGED, +http://edamontology.org/data_1726,myGrid, +http://edamontology.org/data_1727,GO (biological process), +http://edamontology.org/data_1728,GO (molecular function), +http://edamontology.org/data_1729,GO (cellular component), +http://edamontology.org/data_1730,Ontology relation type, +http://edamontology.org/data_1731,Ontology concept definition, +http://edamontology.org/data_1732,Ontology concept comment, +http://edamontology.org/data_1733,Ontology concept reference, +http://edamontology.org/data_1738,doc2loc document information, +http://edamontology.org/data_1742,PDB residue number, +http://edamontology.org/data_1743,Atomic coordinate, +http://edamontology.org/data_1744,Atomic x coordinate, +http://edamontology.org/data_1745,Atomic y coordinate, +http://edamontology.org/data_1746,Atomic z coordinate, +http://edamontology.org/data_1748,PDB atom name, +http://edamontology.org/data_1755,Protein atom, +http://edamontology.org/data_1756,Protein residue, +http://edamontology.org/data_1757,Atom name, +http://edamontology.org/data_1758,PDB residue name, +http://edamontology.org/data_1759,PDB model number, +http://edamontology.org/data_1762,CATH domain report, +http://edamontology.org/data_1764,CATH representative domain sequences (ATOM), +http://edamontology.org/data_1765,CATH representative domain sequences (COMBS), +http://edamontology.org/data_1766,CATH domain sequences (ATOM), +http://edamontology.org/data_1767,CATH domain sequences (COMBS), +http://edamontology.org/data_1771,Sequence version, +http://edamontology.org/data_1772,Score, +http://edamontology.org/data_1776,Protein report (function), +http://edamontology.org/data_1783,Gene name (ASPGD), +http://edamontology.org/data_1784,Gene name (CGD), +http://edamontology.org/data_1785,Gene name (dictyBase), +http://edamontology.org/data_1786,Gene name (EcoGene primary), +http://edamontology.org/data_1787,Gene name (MaizeGDB), +http://edamontology.org/data_1788,Gene name (SGD), +http://edamontology.org/data_1789,Gene name (TGD), +http://edamontology.org/data_1790,Gene name (CGSC), +http://edamontology.org/data_1791,Gene name (HGNC), +http://edamontology.org/data_1792,Gene name (MGD), +http://edamontology.org/data_1793,Gene name (Bacillus subtilis), +http://edamontology.org/data_1794,Gene ID (PlasmoDB), +http://edamontology.org/data_1795,Gene ID (EcoGene), +http://edamontology.org/data_1796,Gene ID (FlyBase), +http://edamontology.org/data_1797,Gene ID (GeneDB Glossina morsitans), +http://edamontology.org/data_1798,Gene ID (GeneDB Leishmania major), +http://edamontology.org/data_1799,Gene ID (GeneDB Plasmodium falciparum), +http://edamontology.org/data_1800,Gene ID (GeneDB Schizosaccharomyces pombe), +http://edamontology.org/data_1801,Gene ID (GeneDB Trypanosoma brucei), +http://edamontology.org/data_1802,Gene ID (Gramene), +http://edamontology.org/data_1803,Gene ID (Virginia microbial), +http://edamontology.org/data_1804,Gene ID (SGN), +http://edamontology.org/data_1805,Gene ID (WormBase), +http://edamontology.org/data_1806,Gene synonym, +http://edamontology.org/data_1807,ORF name, +http://edamontology.org/data_1852,Sequence assembly component, +http://edamontology.org/data_1853,Chromosome annotation (aberration), +http://edamontology.org/data_1855,Clone ID, +http://edamontology.org/data_1856,PDB insertion code, +http://edamontology.org/data_1857,Atomic occupancy, +http://edamontology.org/data_1858,Isotropic B factor, +http://edamontology.org/data_1859,Deletion map, +http://edamontology.org/data_1860,QTL map, +http://edamontology.org/data_1863,Haplotype map, +http://edamontology.org/data_1864,Map set data, +http://edamontology.org/data_1865,Map feature, +http://edamontology.org/data_1866,Map type, +http://edamontology.org/data_1867,Protein fold name, +http://edamontology.org/data_1868,Taxon, +http://edamontology.org/data_1869,Organism identifier, +http://edamontology.org/data_1870,Genus name, +http://edamontology.org/data_1872,Taxonomic classification, +http://edamontology.org/data_1873,iHOP organism ID, +http://edamontology.org/data_1874,Genbank common name, +http://edamontology.org/data_1875,NCBI taxon, +http://edamontology.org/data_1877,Synonym, +http://edamontology.org/data_1878,Misspelling, +http://edamontology.org/data_1879,Acronym, +http://edamontology.org/data_1880,Misnomer, +http://edamontology.org/data_1881,Author ID, +http://edamontology.org/data_1882,DragonDB author identifier, +http://edamontology.org/data_1883,Annotated URI, +http://edamontology.org/data_1884,UniProt keywords, +http://edamontology.org/data_1885,Gene ID (GeneFarm), +http://edamontology.org/data_1886,Blattner number, +http://edamontology.org/data_1887,Gene ID (MIPS Maize), +http://edamontology.org/data_1888,Gene ID (MIPS Medicago), +http://edamontology.org/data_1889,Gene name (DragonDB), +http://edamontology.org/data_1890,Gene name (Arabidopsis), +http://edamontology.org/data_1891,iHOP symbol, +http://edamontology.org/data_1892,Gene name (GeneFarm), +http://edamontology.org/data_1893,Locus ID, +http://edamontology.org/data_1895,Locus ID (AGI), +http://edamontology.org/data_1896,Locus ID (ASPGD), +http://edamontology.org/data_1897,Locus ID (MGG), +http://edamontology.org/data_1898,Locus ID (CGD), +http://edamontology.org/data_1899,Locus ID (CMR), +http://edamontology.org/data_1900,NCBI locus tag, +http://edamontology.org/data_1901,Locus ID (SGD), +http://edamontology.org/data_1902,Locus ID (MMP), +http://edamontology.org/data_1903,Locus ID (DictyBase), +http://edamontology.org/data_1904,Locus ID (EntrezGene), +http://edamontology.org/data_1905,Locus ID (MaizeGDB), +http://edamontology.org/data_1906,Quantitative trait locus, +http://edamontology.org/data_1907,Gene ID (KOME), +http://edamontology.org/data_1908,Locus ID (Tropgene), +http://edamontology.org/data_1916,Alignment, +http://edamontology.org/data_1917,Atomic property, +http://edamontology.org/data_2007,UniProt keyword, +http://edamontology.org/data_2009,Ordered locus name, +http://edamontology.org/data_2012,Sequence coordinates, +http://edamontology.org/data_2016,Amino acid property, +http://edamontology.org/data_2018,Annotation, +http://edamontology.org/data_2019,Map data, +http://edamontology.org/data_2022,Vienna RNA structural data, +http://edamontology.org/data_2023,Sequence mask parameter, +http://edamontology.org/data_2024,Enzyme kinetics data, +http://edamontology.org/data_2025,Michaelis Menten plot, +http://edamontology.org/data_2026,Hanes Woolf plot, +http://edamontology.org/data_2028,Experimental data, +http://edamontology.org/data_2041,Genome version information, +http://edamontology.org/data_2042,Evidence, +http://edamontology.org/data_2043,Sequence record lite, +http://edamontology.org/data_2044,Sequence, +http://edamontology.org/data_2046,Nucleic acid sequence record (lite), +http://edamontology.org/data_2047,Protein sequence record (lite), +http://edamontology.org/data_2048,Report, +http://edamontology.org/data_2050,Molecular property (general), +http://edamontology.org/data_2053,Structural data, +http://edamontology.org/data_2070,Sequence motif (nucleic acid), +http://edamontology.org/data_2071,Sequence motif (protein), +http://edamontology.org/data_2079,Search parameter, +http://edamontology.org/data_2080,Database search results, +http://edamontology.org/data_2081,Secondary structure, +http://edamontology.org/data_2082,Matrix, +http://edamontology.org/data_2083,Alignment data, +http://edamontology.org/data_2084,Nucleic acid report, +http://edamontology.org/data_2085,Structure report, +http://edamontology.org/data_2086,Nucleic acid structure data, +http://edamontology.org/data_2087,Molecular property, +http://edamontology.org/data_2088,DNA base structural data, +http://edamontology.org/data_2090,Database entry version information, +http://edamontology.org/data_2091,Accession, +http://edamontology.org/data_2092,SNP, +http://edamontology.org/data_2093,Data reference, +http://edamontology.org/data_2098,Job identifier, +http://edamontology.org/data_2099,Name, +http://edamontology.org/data_2100,Type, +http://edamontology.org/data_2101,User ID, +http://edamontology.org/data_2102,KEGG organism code, +http://edamontology.org/data_2103,Gene name (KEGG GENES), +http://edamontology.org/data_2104,BioCyc ID, +http://edamontology.org/data_2105,Compound ID (BioCyc), +http://edamontology.org/data_2106,Reaction ID (BioCyc), +http://edamontology.org/data_2107,Enzyme ID (BioCyc), +http://edamontology.org/data_2108,Reaction ID, +http://edamontology.org/data_2109,Identifier (hybrid), +http://edamontology.org/data_2110,Molecular property identifier, +http://edamontology.org/data_2111,Codon usage table ID, +http://edamontology.org/data_2112,FlyBase primary identifier, +http://edamontology.org/data_2113,WormBase identifier, +http://edamontology.org/data_2114,WormBase wormpep ID, +http://edamontology.org/data_2116,Nucleic acid features (codon), +http://edamontology.org/data_2117,Map identifier, +http://edamontology.org/data_2118,Person identifier, +http://edamontology.org/data_2119,Nucleic acid identifier, +http://edamontology.org/data_2126,Translation frame specification, +http://edamontology.org/data_2127,Genetic code identifier, +http://edamontology.org/data_2128,Genetic code name, +http://edamontology.org/data_2129,File format name, +http://edamontology.org/data_2130,Sequence profile type, +http://edamontology.org/data_2131,Operating system name, +http://edamontology.org/data_2132,Mutation type, +http://edamontology.org/data_2133,Logical operator, +http://edamontology.org/data_2134,Results sort order, +http://edamontology.org/data_2135,Toggle, +http://edamontology.org/data_2136,Sequence width, +http://edamontology.org/data_2137,Gap penalty, +http://edamontology.org/data_2139,Nucleic acid melting temperature, +http://edamontology.org/data_2140,Concentration, +http://edamontology.org/data_2141,Window step size, +http://edamontology.org/data_2142,EMBOSS graph, +http://edamontology.org/data_2143,EMBOSS report, +http://edamontology.org/data_2145,Sequence offset, +http://edamontology.org/data_2146,Threshold, +http://edamontology.org/data_2147,Protein report (transcription factor), +http://edamontology.org/data_2149,Database category name, +http://edamontology.org/data_2150,Sequence profile name, +http://edamontology.org/data_2151,Color, +http://edamontology.org/data_2152,Rendering parameter, +http://edamontology.org/data_2154,Sequence name, +http://edamontology.org/data_2156,Date, +http://edamontology.org/data_2157,Word composition, +http://edamontology.org/data_2160,Fickett testcode plot, +http://edamontology.org/data_2161,Sequence similarity plot, +http://edamontology.org/data_2162,Helical wheel, +http://edamontology.org/data_2163,Helical net, +http://edamontology.org/data_2164,Protein sequence properties plot, +http://edamontology.org/data_2165,Protein ionisation curve, +http://edamontology.org/data_2166,Sequence composition plot, +http://edamontology.org/data_2167,Nucleic acid density plot, +http://edamontology.org/data_2168,Sequence trace image, +http://edamontology.org/data_2169,Nucleic acid features (siRNA), +http://edamontology.org/data_2173,Sequence set (stream), +http://edamontology.org/data_2174,FlyBase secondary identifier, +http://edamontology.org/data_2176,Cardinality, +http://edamontology.org/data_2177,Exactly 1, +http://edamontology.org/data_2178,1 or more, +http://edamontology.org/data_2179,Exactly 2, +http://edamontology.org/data_2180,2 or more, +http://edamontology.org/data_2190,Sequence checksum, +http://edamontology.org/data_2191,Protein features report (chemical modifications), +http://edamontology.org/data_2192,Error, +http://edamontology.org/data_2193,Database entry metadata, +http://edamontology.org/data_2198,Gene cluster, +http://edamontology.org/data_2201,Sequence record full, +http://edamontology.org/data_2208,Plasmid identifier, +http://edamontology.org/data_2209,Mutation ID, +http://edamontology.org/data_2212,Mutation annotation (basic), +http://edamontology.org/data_2213,Mutation annotation (prevalence), +http://edamontology.org/data_2214,Mutation annotation (prognostic), +http://edamontology.org/data_2215,Mutation annotation (functional), +http://edamontology.org/data_2216,Codon number, +http://edamontology.org/data_2217,Tumor annotation, +http://edamontology.org/data_2218,Server metadata, +http://edamontology.org/data_2219,Database field name, +http://edamontology.org/data_2220,Sequence cluster ID (SYSTERS), +http://edamontology.org/data_2223,Ontology metadata, +http://edamontology.org/data_2235,Raw SCOP domain classification, +http://edamontology.org/data_2236,Raw CATH domain classification, +http://edamontology.org/data_2240,Heterogen annotation, +http://edamontology.org/data_2242,Phylogenetic property values, +http://edamontology.org/data_2245,Sequence set (bootstrapped), +http://edamontology.org/data_2247,Phylogenetic consensus tree, +http://edamontology.org/data_2248,Schema, +http://edamontology.org/data_2249,DTD, +http://edamontology.org/data_2250,XML Schema, +http://edamontology.org/data_2251,Relax-NG schema, +http://edamontology.org/data_2252,XSLT stylesheet, +http://edamontology.org/data_2253,Data resource definition name, +http://edamontology.org/data_2254,OBO file format name, +http://edamontology.org/data_2285,Gene ID (MIPS), +http://edamontology.org/data_2288,Sequence identifier (protein), +http://edamontology.org/data_2289,Sequence identifier (nucleic acid), +http://edamontology.org/data_2290,EMBL accession, +http://edamontology.org/data_2291,UniProt ID, +http://edamontology.org/data_2292,GenBank accession, +http://edamontology.org/data_2293,Gramene secondary identifier, +http://edamontology.org/data_2294,Sequence variation ID, +http://edamontology.org/data_2295,Gene ID, +http://edamontology.org/data_2296,Gene name (AceView), +http://edamontology.org/data_2297,Gene ID (ECK), +http://edamontology.org/data_2298,Gene ID (HGNC), +http://edamontology.org/data_2299,Gene name, +http://edamontology.org/data_2300,Gene name (NCBI), +http://edamontology.org/data_2301,SMILES string, +http://edamontology.org/data_2302,STRING ID, +http://edamontology.org/data_2307,Virus annotation, +http://edamontology.org/data_2308,Virus annotation (taxonomy), +http://edamontology.org/data_2309,Reaction ID (SABIO-RK), +http://edamontology.org/data_2313,Carbohydrate report, +http://edamontology.org/data_2314,GI number, +http://edamontology.org/data_2315,NCBI version, +http://edamontology.org/data_2316,Cell line name, +http://edamontology.org/data_2317,Cell line name (exact), +http://edamontology.org/data_2318,Cell line name (truncated), +http://edamontology.org/data_2319,Cell line name (no punctuation), +http://edamontology.org/data_2320,Cell line name (assonant), +http://edamontology.org/data_2321,Enzyme ID, +http://edamontology.org/data_2325,REBASE enzyme number, +http://edamontology.org/data_2326,DrugBank ID, +http://edamontology.org/data_2327,GI number (protein), +http://edamontology.org/data_2335,Bit score, +http://edamontology.org/data_2336,Translation phase specification, +http://edamontology.org/data_2337,Resource metadata, +http://edamontology.org/data_2338,Ontology identifier, +http://edamontology.org/data_2339,Ontology concept name, +http://edamontology.org/data_2340,Genome build identifier, +http://edamontology.org/data_2342,Pathway or network name, +http://edamontology.org/data_2343,Pathway ID (KEGG), +http://edamontology.org/data_2344,Pathway ID (NCI-Nature), +http://edamontology.org/data_2345,Pathway ID (ConsensusPathDB), +http://edamontology.org/data_2346,Sequence cluster ID (UniRef), +http://edamontology.org/data_2347,Sequence cluster ID (UniRef100), +http://edamontology.org/data_2348,Sequence cluster ID (UniRef90), +http://edamontology.org/data_2349,Sequence cluster ID (UniRef50), +http://edamontology.org/data_2353,Ontology data, +http://edamontology.org/data_2354,RNA family report, +http://edamontology.org/data_2355,RNA family identifier, +http://edamontology.org/data_2356,RFAM accession, +http://edamontology.org/data_2357,Protein signature type, +http://edamontology.org/data_2358,Domain-nucleic acid interaction report, +http://edamontology.org/data_2359,Domain-domain interactions, +http://edamontology.org/data_2360,Domain-domain interaction (indirect), +http://edamontology.org/data_2362,Sequence accession (hybrid), +http://edamontology.org/data_2363,2D PAGE data, +http://edamontology.org/data_2364,2D PAGE report, +http://edamontology.org/data_2365,Pathway or network accession, +http://edamontology.org/data_2366,Secondary structure alignment, +http://edamontology.org/data_2367,ASTD ID, +http://edamontology.org/data_2368,ASTD ID (exon), +http://edamontology.org/data_2369,ASTD ID (intron), +http://edamontology.org/data_2370,ASTD ID (polya), +http://edamontology.org/data_2371,ASTD ID (tss), +http://edamontology.org/data_2372,2D PAGE spot report, +http://edamontology.org/data_2373,Spot ID, +http://edamontology.org/data_2374,Spot serial number, +http://edamontology.org/data_2375,Spot ID (HSC-2DPAGE), +http://edamontology.org/data_2378,Protein-motif interaction, +http://edamontology.org/data_2379,Strain identifier, +http://edamontology.org/data_2380,CABRI accession, +http://edamontology.org/data_2381,Experiment report (genotyping), +http://edamontology.org/data_2382,Genotype experiment ID, +http://edamontology.org/data_2383,EGA accession, +http://edamontology.org/data_2384,IPI protein ID, +http://edamontology.org/data_2385,RefSeq accession (protein), +http://edamontology.org/data_2386,EPD ID, +http://edamontology.org/data_2387,TAIR accession, +http://edamontology.org/data_2388,TAIR accession (At gene), +http://edamontology.org/data_2389,UniSTS accession, +http://edamontology.org/data_2390,UNITE accession, +http://edamontology.org/data_2391,UTR accession, +http://edamontology.org/data_2392,UniParc accession, +http://edamontology.org/data_2393,mFLJ/mKIAA number, +http://edamontology.org/data_2395,Fungi annotation, +http://edamontology.org/data_2396,Fungi annotation (anamorph), +http://edamontology.org/data_2398,Ensembl protein ID, +http://edamontology.org/data_2400,Toxin annotation, +http://edamontology.org/data_2401,Protein report (membrane protein), +http://edamontology.org/data_2402,Protein-drug interaction report, +http://edamontology.org/data_2522,Map data, +http://edamontology.org/data_2523,Phylogenetic data, +http://edamontology.org/data_2524,Protein data, +http://edamontology.org/data_2525,Nucleic acid data, +http://edamontology.org/data_2526,Text data, +http://edamontology.org/data_2527,Parameter, +http://edamontology.org/data_2528,Molecular data, +http://edamontology.org/data_2529,Molecule report, +http://edamontology.org/data_2530,Organism report, +http://edamontology.org/data_2531,Protocol, +http://edamontology.org/data_2534,Sequence attribute, +http://edamontology.org/data_2535,Sequence tag profile, +http://edamontology.org/data_2536,Mass spectrometry data, +http://edamontology.org/data_2537,Protein structure raw data, +http://edamontology.org/data_2538,Mutation identifier, +http://edamontology.org/data_2539,Alignment data, +http://edamontology.org/data_2540,Data index data, +http://edamontology.org/data_2563,Amino acid name (single letter), +http://edamontology.org/data_2564,Amino acid name (three letter), +http://edamontology.org/data_2565,Amino acid name (full name), +http://edamontology.org/data_2576,Toxin identifier, +http://edamontology.org/data_2578,ArachnoServer ID, +http://edamontology.org/data_2579,Expressed gene list, +http://edamontology.org/data_2580,BindingDB Monomer ID, +http://edamontology.org/data_2581,GO concept name, +http://edamontology.org/data_2582,GO concept ID (biological process), +http://edamontology.org/data_2583,GO concept ID (molecular function), +http://edamontology.org/data_2584,GO concept name (cellular component), +http://edamontology.org/data_2586,Northern blot image, +http://edamontology.org/data_2587,Blot ID, +http://edamontology.org/data_2588,BlotBase blot ID, +http://edamontology.org/data_2589,Hierarchy, +http://edamontology.org/data_2590,Hierarchy identifier, +http://edamontology.org/data_2591,Brite hierarchy ID, +http://edamontology.org/data_2592,Cancer type, +http://edamontology.org/data_2593,BRENDA organism ID, +http://edamontology.org/data_2594,UniGene taxon, +http://edamontology.org/data_2595,UTRdb taxon, +http://edamontology.org/data_2596,Catalogue ID, +http://edamontology.org/data_2597,CABRI catalogue name, +http://edamontology.org/data_2598,Secondary structure alignment metadata, +http://edamontology.org/data_2599,Molecule interaction report, +http://edamontology.org/data_2600,Pathway or network, +http://edamontology.org/data_2601,Small molecule data, +http://edamontology.org/data_2602,Genotype and phenotype data, +http://edamontology.org/data_2603,Expression data, +http://edamontology.org/data_2605,Compound ID (KEGG), +http://edamontology.org/data_2606,RFAM name, +http://edamontology.org/data_2608,Reaction ID (KEGG), +http://edamontology.org/data_2609,Drug ID (KEGG), +http://edamontology.org/data_2610,Ensembl ID, +http://edamontology.org/data_2611,ICD identifier, +http://edamontology.org/data_2612,Sequence cluster ID (CluSTr), +http://edamontology.org/data_2613,KEGG Glycan ID, +http://edamontology.org/data_2614,TCDB ID, +http://edamontology.org/data_2615,MINT ID, +http://edamontology.org/data_2616,DIP ID, +http://edamontology.org/data_2617,Signaling Gateway protein ID, +http://edamontology.org/data_2618,Protein modification ID, +http://edamontology.org/data_2619,RESID ID, +http://edamontology.org/data_2620,RGD ID, +http://edamontology.org/data_2621,TAIR accession (protein), +http://edamontology.org/data_2622,Compound ID (HMDB), +http://edamontology.org/data_2625,LIPID MAPS ID, +http://edamontology.org/data_2626,PeptideAtlas ID, +http://edamontology.org/data_2627,Molecular interaction ID, +http://edamontology.org/data_2628,BioGRID interaction ID, +http://edamontology.org/data_2629,Enzyme ID (MEROPS), +http://edamontology.org/data_2630,Mobile genetic element ID, +http://edamontology.org/data_2631,ACLAME ID, +http://edamontology.org/data_2632,SGD ID, +http://edamontology.org/data_2633,Book ID, +http://edamontology.org/data_2634,ISBN, +http://edamontology.org/data_2635,Compound ID (3DMET), +http://edamontology.org/data_2636,MatrixDB interaction ID, +http://edamontology.org/data_2637,cPath ID, +http://edamontology.org/data_2638,PubChem bioassay ID, +http://edamontology.org/data_2639,PubChem ID, +http://edamontology.org/data_2641,Reaction ID (MACie), +http://edamontology.org/data_2642,Gene ID (miRBase), +http://edamontology.org/data_2643,Gene ID (ZFIN), +http://edamontology.org/data_2644,Reaction ID (Rhea), +http://edamontology.org/data_2645,Pathway ID (Unipathway), +http://edamontology.org/data_2646,Compound ID (ChEMBL), +http://edamontology.org/data_2647,LGICdb identifier, +http://edamontology.org/data_2648,Reaction kinetics ID (SABIO-RK), +http://edamontology.org/data_2649,PharmGKB ID, +http://edamontology.org/data_2650,Pathway ID (PharmGKB), +http://edamontology.org/data_2651,Disease ID (PharmGKB), +http://edamontology.org/data_2652,Drug ID (PharmGKB), +http://edamontology.org/data_2653,Drug ID (TTD), +http://edamontology.org/data_2654,Target ID (TTD), +http://edamontology.org/data_2655,Cell type identifier, +http://edamontology.org/data_2656,NeuronDB ID, +http://edamontology.org/data_2657,NeuroMorpho ID, +http://edamontology.org/data_2658,Compound ID (ChemIDplus), +http://edamontology.org/data_2659,Pathway ID (SMPDB), +http://edamontology.org/data_2660,BioNumbers ID, +http://edamontology.org/data_2662,T3DB ID, +http://edamontology.org/data_2663,Carbohydrate identifier, +http://edamontology.org/data_2664,GlycomeDB ID, +http://edamontology.org/data_2665,LipidBank ID, +http://edamontology.org/data_2666,CDD ID, +http://edamontology.org/data_2667,MMDB ID, +http://edamontology.org/data_2668,iRefIndex ID, +http://edamontology.org/data_2669,ModelDB ID, +http://edamontology.org/data_2670,Pathway ID (DQCS), +http://edamontology.org/data_2671,Ensembl ID (Homo sapiens), +http://edamontology.org/data_2672,Ensembl ID ('Bos taurus'), +http://edamontology.org/data_2673,Ensembl ID ('Canis familiaris'), +http://edamontology.org/data_2674,Ensembl ID ('Cavia porcellus'), +http://edamontology.org/data_2675,Ensembl ID ('Ciona intestinalis'), +http://edamontology.org/data_2676,Ensembl ID ('Ciona savignyi'), +http://edamontology.org/data_2677,Ensembl ID ('Danio rerio'), +http://edamontology.org/data_2678,Ensembl ID ('Dasypus novemcinctus'), +http://edamontology.org/data_2679,Ensembl ID ('Echinops telfairi'), +http://edamontology.org/data_2680,Ensembl ID ('Erinaceus europaeus'), +http://edamontology.org/data_2681,Ensembl ID ('Felis catus'), +http://edamontology.org/data_2682,Ensembl ID ('Gallus gallus'), +http://edamontology.org/data_2683,Ensembl ID ('Gasterosteus aculeatus'), +http://edamontology.org/data_2684,Ensembl ID ('Homo sapiens'), +http://edamontology.org/data_2685,Ensembl ID ('Loxodonta africana'), +http://edamontology.org/data_2686,Ensembl ID ('Macaca mulatta'), +http://edamontology.org/data_2687,Ensembl ID ('Monodelphis domestica'), +http://edamontology.org/data_2688,Ensembl ID ('Mus musculus'), +http://edamontology.org/data_2689,Ensembl ID ('Myotis lucifugus'), +http://edamontology.org/data_2690,"Ensembl ID (""Ornithorhynchus anatinus\"")", +http://edamontology.org/data_2691,Ensembl ID ('Oryctolagus cuniculus'), +http://edamontology.org/data_2692,Ensembl ID ('Oryzias latipes'), +http://edamontology.org/data_2693,Ensembl ID ('Otolemur garnettii'), +http://edamontology.org/data_2694,Ensembl ID ('Pan troglodytes'), +http://edamontology.org/data_2695,Ensembl ID ('Rattus norvegicus'), +http://edamontology.org/data_2696,Ensembl ID ('Spermophilus tridecemlineatus'), +http://edamontology.org/data_2697,Ensembl ID ('Takifugu rubripes'), +http://edamontology.org/data_2698,Ensembl ID ('Tupaia belangeri'), +http://edamontology.org/data_2699,Ensembl ID ('Xenopus tropicalis'), +http://edamontology.org/data_2700,CATH identifier, +http://edamontology.org/data_2701,CATH node ID (family), +http://edamontology.org/data_2702,Enzyme ID (CAZy), +http://edamontology.org/data_2704,Clone ID (IMAGE), +http://edamontology.org/data_2705,GO concept ID (cellular component), +http://edamontology.org/data_2706,Chromosome name (BioCyc), +http://edamontology.org/data_2709,CleanEx entry name, +http://edamontology.org/data_2710,CleanEx dataset code, +http://edamontology.org/data_2711,Genome report, +http://edamontology.org/data_2713,Protein ID (CORUM), +http://edamontology.org/data_2714,CDD PSSM-ID, +http://edamontology.org/data_2715,Protein ID (CuticleDB), +http://edamontology.org/data_2716,DBD ID, +http://edamontology.org/data_2717,Oligonucleotide probe annotation, +http://edamontology.org/data_2718,Oligonucleotide ID, +http://edamontology.org/data_2719,dbProbe ID, +http://edamontology.org/data_2720,Dinucleotide property, +http://edamontology.org/data_2721,DiProDB ID, +http://edamontology.org/data_2722,Protein features report (disordered structure), +http://edamontology.org/data_2723,Protein ID (DisProt), +http://edamontology.org/data_2724,Embryo report, +http://edamontology.org/data_2725,Ensembl transcript ID, +http://edamontology.org/data_2726,Inhibitor annotation, +http://edamontology.org/data_2727,Promoter ID, +http://edamontology.org/data_2728,EST accession, +http://edamontology.org/data_2729,COGEME EST ID, +http://edamontology.org/data_2730,COGEME unisequence ID, +http://edamontology.org/data_2731,Protein family ID (GeneFarm), +http://edamontology.org/data_2732,Family name, +http://edamontology.org/data_2733,Genus name (virus), +http://edamontology.org/data_2734,Family name (virus), +http://edamontology.org/data_2735,Database name (SwissRegulon), +http://edamontology.org/data_2736,Sequence feature ID (SwissRegulon), +http://edamontology.org/data_2737,FIG ID, +http://edamontology.org/data_2738,Gene ID (Xenbase), +http://edamontology.org/data_2739,Gene ID (Genolist), +http://edamontology.org/data_2740,Gene name (Genolist), +http://edamontology.org/data_2741,ABS ID, +http://edamontology.org/data_2742,AraC-XylS ID, +http://edamontology.org/data_2743,Gene name (HUGO), +http://edamontology.org/data_2744,Locus ID (PseudoCAP), +http://edamontology.org/data_2745,Locus ID (UTR), +http://edamontology.org/data_2746,MonosaccharideDB ID, +http://edamontology.org/data_2747,Database name (CMD), +http://edamontology.org/data_2748,Database name (Osteogenesis), +http://edamontology.org/data_2749,Genome identifier, +http://edamontology.org/data_2751,GenomeReviews ID, +http://edamontology.org/data_2752,GlycoMap ID, +http://edamontology.org/data_2753,Carbohydrate conformational map, +http://edamontology.org/data_2755,Transcription factor name, +http://edamontology.org/data_2756,TCID, +http://edamontology.org/data_2757,Pfam domain name, +http://edamontology.org/data_2758,Pfam clan ID, +http://edamontology.org/data_2759,Gene ID (VectorBase), +http://edamontology.org/data_2761,UTRSite ID, +http://edamontology.org/data_2762,Sequence signature report, +http://edamontology.org/data_2763,Locus annotation, +http://edamontology.org/data_2764,Protein name (UniProt), +http://edamontology.org/data_2765,Term ID list, +http://edamontology.org/data_2766,HAMAP ID, +http://edamontology.org/data_2767,Identifier with metadata, +http://edamontology.org/data_2768,Gene symbol annotation, +http://edamontology.org/data_2769,Transcript ID, +http://edamontology.org/data_2770,HIT ID, +http://edamontology.org/data_2771,HIX ID, +http://edamontology.org/data_2772,HPA antibody id, +http://edamontology.org/data_2773,IMGT/HLA ID, +http://edamontology.org/data_2774,Gene ID (JCVI), +http://edamontology.org/data_2775,Kinase name, +http://edamontology.org/data_2776,ConsensusPathDB entity ID, +http://edamontology.org/data_2777,ConsensusPathDB entity name, +http://edamontology.org/data_2778,CCAP strain number, +http://edamontology.org/data_2779,Stock number, +http://edamontology.org/data_2780,Stock number (TAIR), +http://edamontology.org/data_2781,REDIdb ID, +http://edamontology.org/data_2782,SMART domain name, +http://edamontology.org/data_2783,Protein family ID (PANTHER), +http://edamontology.org/data_2784,RNAVirusDB ID, +http://edamontology.org/data_2785,Virus ID, +http://edamontology.org/data_2786,NCBI Genome Project ID, +http://edamontology.org/data_2787,NCBI genome accession, +http://edamontology.org/data_2788,Sequence profile data, +http://edamontology.org/data_2789,Protein ID (TopDB), +http://edamontology.org/data_2790,Gel ID, +http://edamontology.org/data_2791,Reference map name (SWISS-2DPAGE), +http://edamontology.org/data_2792,Protein ID (PeroxiBase), +http://edamontology.org/data_2793,SISYPHUS ID, +http://edamontology.org/data_2794,ORF ID, +http://edamontology.org/data_2795,ORF identifier, +http://edamontology.org/data_2796,Linucs ID, +http://edamontology.org/data_2797,Protein ID (LGICdb), +http://edamontology.org/data_2798,MaizeDB ID, +http://edamontology.org/data_2799,Gene ID (MfunGD), +http://edamontology.org/data_2800,Orpha number, +http://edamontology.org/data_2802,Protein ID (EcID), +http://edamontology.org/data_2803,Clone ID (RefSeq), +http://edamontology.org/data_2804,Protein ID (ConoServer), +http://edamontology.org/data_2805,GeneSNP ID, +http://edamontology.org/data_2812,Lipid identifier, +http://edamontology.org/data_2831,Databank, +http://edamontology.org/data_2832,Web portal, +http://edamontology.org/data_2835,Gene ID (VBASE2), +http://edamontology.org/data_2836,DPVweb ID, +http://edamontology.org/data_2837,Pathway ID (BioSystems), +http://edamontology.org/data_2838,Experimental data (proteomics), +http://edamontology.org/data_2849,Abstract, +http://edamontology.org/data_2850,Lipid structure, +http://edamontology.org/data_2851,Drug structure, +http://edamontology.org/data_2852,Toxin structure, +http://edamontology.org/data_2854,Position-specific scoring matrix, +http://edamontology.org/data_2855,Distance matrix, +http://edamontology.org/data_2856,Structural distance matrix, +http://edamontology.org/data_2857,Article metadata, +http://edamontology.org/data_2858,Ontology concept, +http://edamontology.org/data_2865,Codon usage bias, +http://edamontology.org/data_2866,Northern blot report, +http://edamontology.org/data_2870,Radiation hybrid map, +http://edamontology.org/data_2872,ID list, +http://edamontology.org/data_2873,Phylogenetic gene frequencies data, +http://edamontology.org/data_2874,Sequence set (polymorphic), +http://edamontology.org/data_2875,DRCAT resource, +http://edamontology.org/data_2877,Protein complex, +http://edamontology.org/data_2878,Protein structural motif, +http://edamontology.org/data_2879,Lipid report, +http://edamontology.org/data_2880,Secondary structure image, +http://edamontology.org/data_2881,Secondary structure report, +http://edamontology.org/data_2882,DNA features, +http://edamontology.org/data_2883,RNA features report, +http://edamontology.org/data_2884,Plot, +http://edamontology.org/data_2886,Protein sequence record, +http://edamontology.org/data_2887,Nucleic acid sequence record, +http://edamontology.org/data_2888,Protein sequence record (full), +http://edamontology.org/data_2889,Nucleic acid sequence record (full), +http://edamontology.org/data_2891,Biological model accession, +http://edamontology.org/data_2892,Cell type name, +http://edamontology.org/data_2893,Cell type accession, +http://edamontology.org/data_2894,Compound accession, +http://edamontology.org/data_2895,Drug accession, +http://edamontology.org/data_2896,Toxin name, +http://edamontology.org/data_2897,Toxin accession, +http://edamontology.org/data_2898,Monosaccharide accession, +http://edamontology.org/data_2899,Drug name, +http://edamontology.org/data_2900,Carbohydrate accession, +http://edamontology.org/data_2901,Molecule accession, +http://edamontology.org/data_2902,Data resource definition accession, +http://edamontology.org/data_2903,Genome accession, +http://edamontology.org/data_2904,Map accession, +http://edamontology.org/data_2905,Lipid accession, +http://edamontology.org/data_2906,Peptide ID, +http://edamontology.org/data_2907,Protein accession, +http://edamontology.org/data_2908,Organism accession, +http://edamontology.org/data_2909,Organism name, +http://edamontology.org/data_2910,Protein family accession, +http://edamontology.org/data_2911,Transcription factor accession, +http://edamontology.org/data_2912,Strain accession, +http://edamontology.org/data_2913,Virus identifier, +http://edamontology.org/data_2914,Sequence features metadata, +http://edamontology.org/data_2915,Gramene identifier, +http://edamontology.org/data_2916,DDBJ accession, +http://edamontology.org/data_2917,ConsensusPathDB identifier, +http://edamontology.org/data_2925,Sequence data, +http://edamontology.org/data_2927,Codon usage, +http://edamontology.org/data_2954,Article report, +http://edamontology.org/data_2955,Sequence report, +http://edamontology.org/data_2956,Protein secondary structure, +http://edamontology.org/data_2957,Hopp and Woods plot, +http://edamontology.org/data_2958,Nucleic acid melting curve, +http://edamontology.org/data_2959,Nucleic acid probability profile, +http://edamontology.org/data_2960,Nucleic acid temperature profile, +http://edamontology.org/data_2961,Gene regulatory network report, +http://edamontology.org/data_2965,2D PAGE gel report, +http://edamontology.org/data_2966,Oligonucleotide probe sets annotation, +http://edamontology.org/data_2967,Microarray image, +http://edamontology.org/data_2968,Image, +http://edamontology.org/data_2969,Sequence image, +http://edamontology.org/data_2970,Protein hydropathy data, +http://edamontology.org/data_2971,Workflow data, +http://edamontology.org/data_2972,Workflow, +http://edamontology.org/data_2973,Secondary structure data, +http://edamontology.org/data_2974,Protein sequence (raw), +http://edamontology.org/data_2975,Nucleic acid sequence (raw), +http://edamontology.org/data_2976,Protein sequence, +http://edamontology.org/data_2977,Nucleic acid sequence, +http://edamontology.org/data_2978,Reaction data, +http://edamontology.org/data_2979,Peptide property, +http://edamontology.org/data_2980,Protein classification, +http://edamontology.org/data_2981,Sequence motif data, +http://edamontology.org/data_2982,Sequence profile data, +http://edamontology.org/data_2983,Pathway or network data, +http://edamontology.org/data_2984,Pathway or network report, +http://edamontology.org/data_2985,Nucleic acid thermodynamic data, +http://edamontology.org/data_2986,Nucleic acid classification, +http://edamontology.org/data_2987,Classification report, +http://edamontology.org/data_2989,Protein features report (key folding sites), +http://edamontology.org/data_2991,Protein geometry data, +http://edamontology.org/data_2992,Protein structure image, +http://edamontology.org/data_2994,Phylogenetic character weights, +http://edamontology.org/data_3002,Annotation track, +http://edamontology.org/data_3021,UniProt accession, +http://edamontology.org/data_3022,NCBI genetic code ID, +http://edamontology.org/data_3025,Ontology concept identifier, +http://edamontology.org/data_3026,GO concept name (biological process), +http://edamontology.org/data_3027,GO concept name (molecular function), +http://edamontology.org/data_3028,Taxonomy, +http://edamontology.org/data_3029,Protein ID (EMBL/GenBank/DDBJ), +http://edamontology.org/data_3031,Core data, +http://edamontology.org/data_3034,Sequence feature identifier, +http://edamontology.org/data_3035,Structure identifier, +http://edamontology.org/data_3036,Matrix identifier, +http://edamontology.org/data_3085,Protein sequence composition, +http://edamontology.org/data_3086,Nucleic acid sequence composition (report), +http://edamontology.org/data_3101,Protein domain classification node, +http://edamontology.org/data_3102,CAS number, +http://edamontology.org/data_3103,ATC code, +http://edamontology.org/data_3104,UNII, +http://edamontology.org/data_3105,Geotemporal metadata, +http://edamontology.org/data_3106,System metadata, +http://edamontology.org/data_3107,Sequence feature name, +http://edamontology.org/data_3108,Experimental measurement, +http://edamontology.org/data_3110,Raw microarray data, +http://edamontology.org/data_3111,Processed microarray data, +http://edamontology.org/data_3112,Gene expression matrix, +http://edamontology.org/data_3113,Sample annotation, +http://edamontology.org/data_3115,Microarray metadata, +http://edamontology.org/data_3116,Microarray protocol annotation, +http://edamontology.org/data_3117,Microarray hybridisation data, +http://edamontology.org/data_3119,Sequence features (compositionally-biased regions), +http://edamontology.org/data_3122,Nucleic acid features (difference and change), +http://edamontology.org/data_3128,Nucleic acid structure report, +http://edamontology.org/data_3129,Protein features report (repeats), +http://edamontology.org/data_3130,Sequence motif matches (protein), +http://edamontology.org/data_3131,Sequence motif matches (nucleic acid), +http://edamontology.org/data_3132,Nucleic acid features (d-loop), +http://edamontology.org/data_3133,Nucleic acid features (stem loop), +http://edamontology.org/data_3134,Gene transcript report, +http://edamontology.org/data_3137,Non-coding RNA, +http://edamontology.org/data_3138,Transcriptional features (report), +http://edamontology.org/data_3140,Nucleic acid features (immunoglobulin gene structure), +http://edamontology.org/data_3141,SCOP class, +http://edamontology.org/data_3142,SCOP fold, +http://edamontology.org/data_3143,SCOP superfamily, +http://edamontology.org/data_3144,SCOP family, +http://edamontology.org/data_3145,SCOP protein, +http://edamontology.org/data_3146,SCOP species, +http://edamontology.org/data_3147,Mass spectrometry experiment, +http://edamontology.org/data_3148,Gene family report, +http://edamontology.org/data_3153,Protein image, +http://edamontology.org/data_3154,Protein alignment, +http://edamontology.org/data_3165,NGS experiment, +http://edamontology.org/data_3181,Sequence assembly report, +http://edamontology.org/data_3210,Genome index, +http://edamontology.org/data_3231,GWAS report, +http://edamontology.org/data_3236,Cytoband position, +http://edamontology.org/data_3238,Cell type ontology ID, +http://edamontology.org/data_3241,Kinetic model, +http://edamontology.org/data_3264,COSMIC ID, +http://edamontology.org/data_3265,HGMD ID, +http://edamontology.org/data_3266,Sequence assembly ID, +http://edamontology.org/data_3268,Sequence feature type, +http://edamontology.org/data_3269,Gene homology (report), +http://edamontology.org/data_3270,Ensembl gene tree ID, +http://edamontology.org/data_3271,Gene tree, +http://edamontology.org/data_3272,Species tree, +http://edamontology.org/data_3273,Sample ID, +http://edamontology.org/data_3274,MGI accession, +http://edamontology.org/data_3275,Phenotype name, +http://edamontology.org/data_3354,Transition matrix, +http://edamontology.org/data_3355,Emission matrix, +http://edamontology.org/data_3356,Hidden Markov model, +http://edamontology.org/data_3358,Format identifier, +http://edamontology.org/data_3424,Raw image, +http://edamontology.org/data_3425,Carbohydrate property, +http://edamontology.org/data_3426,Proteomics experiment report, +http://edamontology.org/data_3427,RNAi report, +http://edamontology.org/data_3428,Simulation experiment report, +http://edamontology.org/data_3442,MRI image, +http://edamontology.org/data_3449,Cell migration track image, +http://edamontology.org/data_3451,Rate of association, +http://edamontology.org/data_3479,Gene order, +http://edamontology.org/data_3483,Spectrum, +http://edamontology.org/data_3488,NMR spectrum, +http://edamontology.org/data_3490,Chemical structure sketch, +http://edamontology.org/data_3492,Nucleic acid signature, +http://edamontology.org/data_3494,DNA sequence, +http://edamontology.org/data_3495,RNA sequence, +http://edamontology.org/data_3496,RNA sequence (raw), +http://edamontology.org/data_3497,DNA sequence (raw), +http://edamontology.org/data_3498,Sequence variations, +http://edamontology.org/data_3505,Bibliography, +http://edamontology.org/data_3509,Ontology mapping, +http://edamontology.org/data_3546,Image metadata, +http://edamontology.org/data_3558,Clinical trial report, +http://edamontology.org/data_3567,Reference sample report, +http://edamontology.org/data_3568,Gene Expression Atlas Experiment ID, +http://edamontology.org/data_3667,Disease identifier, +http://edamontology.org/data_3668,Disease name, +http://edamontology.org/data_3669,Training material, +http://edamontology.org/data_3670,Online course, +http://edamontology.org/data_3671,Text, +http://edamontology.org/data_3707,Biodiversity data, +http://edamontology.org/data_3716,Biosafety report, +http://edamontology.org/data_3717,Isolation report, +http://edamontology.org/data_3718,Pathogenicity report, +http://edamontology.org/data_3719,Biosafety classification, +http://edamontology.org/data_3720,Geographic location, +http://edamontology.org/data_3721,Isolation source, +http://edamontology.org/data_3722,Physiology parameter, +http://edamontology.org/data_3723,Morphology parameter, +http://edamontology.org/data_3724,Cultivation parameter, +http://edamontology.org/data_3732,Sequencing metadata name, +http://edamontology.org/data_3733,Flow cell identifier, +http://edamontology.org/data_3734,Lane identifier, +http://edamontology.org/data_3735,Run number, +http://edamontology.org/data_3736,Ecological data, +http://edamontology.org/data_3737,Alpha diversity data, +http://edamontology.org/data_3738,Beta diversity data, +http://edamontology.org/data_3739,Gamma diversity data, +http://edamontology.org/data_3743,Ordination plot, +http://edamontology.org/data_3753,Over-representation data, +http://edamontology.org/data_3754,GO-term enrichment data, +http://edamontology.org/data_3756,Localisation score, +http://edamontology.org/data_3757,Unimod ID, +http://edamontology.org/data_3759,ProteomeXchange ID, +http://edamontology.org/data_3768,Clustered expression profiles, +http://edamontology.org/data_3769,BRENDA ontology concept ID, +http://edamontology.org/data_3779,Annotated text, +http://edamontology.org/data_3786,Query script, +http://edamontology.org/data_3805,3D EM Map, +http://edamontology.org/data_3806,3D EM Mask, +http://edamontology.org/data_3807,EM Movie, +http://edamontology.org/data_3808,EM Micrograph, +http://edamontology.org/data_3842,Molecular simulation data, +http://edamontology.org/data_3856,RNA central ID, +http://edamontology.org/data_3861,Electronic health record, +http://edamontology.org/data_3869,Simulation, +http://edamontology.org/data_3870,Trajectory data, +http://edamontology.org/data_3871,Forcefield parameters, +http://edamontology.org/data_3872,Topology data, +http://edamontology.org/data_3905,Histogram, +http://edamontology.org/data_3914,Quality control report, +http://edamontology.org/data_3917,Count matrix, +http://edamontology.org/data_3924,DNA structure alignment, +http://edamontology.org/data_3932,Q-value, +http://edamontology.org/data_3949,Profile HMM, +http://edamontology.org/data_3952,Pathway ID (WikiPathways), +http://edamontology.org/data_3953,Pathway overrepresentation data, +http://edamontology.org/format_1196,SMILES, +http://edamontology.org/format_1197,InChI, +http://edamontology.org/format_1198,mf, +http://edamontology.org/format_1199,InChIKey, +http://edamontology.org/format_1200,smarts, +http://edamontology.org/format_1206,unambiguous pure, +http://edamontology.org/format_1207,nucleotide, +http://edamontology.org/format_1208,protein, +http://edamontology.org/format_1209,consensus, +http://edamontology.org/format_1210,pure nucleotide, +http://edamontology.org/format_1211,unambiguous pure nucleotide, +http://edamontology.org/format_1212,dna, +http://edamontology.org/format_1213,rna, +http://edamontology.org/format_1214,unambiguous pure dna, +http://edamontology.org/format_1215,pure dna, +http://edamontology.org/format_1216,unambiguous pure rna sequence, +http://edamontology.org/format_1217,pure rna, +http://edamontology.org/format_1218,unambiguous pure protein, +http://edamontology.org/format_1219,pure protein, +http://edamontology.org/format_1228,UniGene entry format, +http://edamontology.org/format_1247,COG sequence cluster format, +http://edamontology.org/format_1248,EMBL feature location, +http://edamontology.org/format_1295,quicktandem, +http://edamontology.org/format_1296,Sanger inverted repeats, +http://edamontology.org/format_1297,EMBOSS repeat, +http://edamontology.org/format_1316,est2genome format, +http://edamontology.org/format_1318,restrict format, +http://edamontology.org/format_1319,restover format, +http://edamontology.org/format_1320,REBASE restriction sites, +http://edamontology.org/format_1332,FASTA search results format, +http://edamontology.org/format_1333,BLAST results, +http://edamontology.org/format_1334,mspcrunch, +http://edamontology.org/format_1335,Smith-Waterman format, +http://edamontology.org/format_1336,dhf, +http://edamontology.org/format_1337,lhf, +http://edamontology.org/format_1341,InterPro hits format, +http://edamontology.org/format_1342,InterPro protein view report format, +http://edamontology.org/format_1343,InterPro match table format, +http://edamontology.org/format_1349,HMMER Dirichlet prior, +http://edamontology.org/format_1350,MEME Dirichlet prior, +http://edamontology.org/format_1351,HMMER emission and transition, +http://edamontology.org/format_1356,prosite-pattern, +http://edamontology.org/format_1357,EMBOSS sequence pattern, +http://edamontology.org/format_1360,meme-motif, +http://edamontology.org/format_1366,prosite-profile, +http://edamontology.org/format_1367,JASPAR format, +http://edamontology.org/format_1369,MEME background Markov model, +http://edamontology.org/format_1370,HMMER format, +http://edamontology.org/format_1391,HMMER-aln, +http://edamontology.org/format_1392,DIALIGN format, +http://edamontology.org/format_1393,daf, +http://edamontology.org/format_1419,Sequence-MEME profile alignment, +http://edamontology.org/format_1421,HMMER profile alignment (sequences versus HMMs), +http://edamontology.org/format_1422,HMMER profile alignment (HMM versus sequences), +http://edamontology.org/format_1423,Phylip distance matrix, +http://edamontology.org/format_1424,ClustalW dendrogram, +http://edamontology.org/format_1425,Phylip tree raw, +http://edamontology.org/format_1430,Phylip continuous quantitative characters, +http://edamontology.org/format_1431,Phylogenetic property values format, +http://edamontology.org/format_1432,Phylip character frequencies format, +http://edamontology.org/format_1433,Phylip discrete states format, +http://edamontology.org/format_1434,Phylip cliques format, +http://edamontology.org/format_1435,Phylip tree format, +http://edamontology.org/format_1436,TreeBASE format, +http://edamontology.org/format_1437,TreeFam format, +http://edamontology.org/format_1445,Phylip tree distance format, +http://edamontology.org/format_1454,dssp, +http://edamontology.org/format_1455,hssp, +http://edamontology.org/format_1457,Dot-bracket format, +http://edamontology.org/format_1458,Vienna local RNA secondary structure format, +http://edamontology.org/format_1475,PDB database entry format, +http://edamontology.org/format_1476,PDB, +http://edamontology.org/format_1477,mmCIF, +http://edamontology.org/format_1478,PDBML, +http://edamontology.org/format_1500,Domainatrix 3D-1D scoring matrix format, +http://edamontology.org/format_1504,aaindex, +http://edamontology.org/format_1511,IntEnz enzyme report format, +http://edamontology.org/format_1512,BRENDA enzyme report format, +http://edamontology.org/format_1513,KEGG REACTION enzyme report format, +http://edamontology.org/format_1514,KEGG ENZYME enzyme report format, +http://edamontology.org/format_1515,REBASE proto enzyme report format, +http://edamontology.org/format_1516,REBASE withrefm enzyme report format, +http://edamontology.org/format_1551,Pcons report format, +http://edamontology.org/format_1552,ProQ report format, +http://edamontology.org/format_1563,SMART domain assignment report format, +http://edamontology.org/format_1568,BIND entry format, +http://edamontology.org/format_1569,IntAct entry format, +http://edamontology.org/format_1570,InterPro entry format, +http://edamontology.org/format_1571,InterPro entry abstract format, +http://edamontology.org/format_1572,Gene3D entry format, +http://edamontology.org/format_1573,PIRSF entry format, +http://edamontology.org/format_1574,PRINTS entry format, +http://edamontology.org/format_1575,Panther Families and HMMs entry format, +http://edamontology.org/format_1576,Pfam entry format, +http://edamontology.org/format_1577,SMART entry format, +http://edamontology.org/format_1578,Superfamily entry format, +http://edamontology.org/format_1579,TIGRFam entry format, +http://edamontology.org/format_1580,ProDom entry format, +http://edamontology.org/format_1581,FSSP entry format, +http://edamontology.org/format_1582,findkm, +http://edamontology.org/format_1603,Ensembl gene report format, +http://edamontology.org/format_1604,DictyBase gene report format, +http://edamontology.org/format_1605,CGD gene report format, +http://edamontology.org/format_1606,DragonDB gene report format, +http://edamontology.org/format_1607,EcoCyc gene report format, +http://edamontology.org/format_1608,FlyBase gene report format, +http://edamontology.org/format_1609,Gramene gene report format, +http://edamontology.org/format_1610,KEGG GENES gene report format, +http://edamontology.org/format_1611,MaizeGDB gene report format, +http://edamontology.org/format_1612,MGD gene report format, +http://edamontology.org/format_1613,RGD gene report format, +http://edamontology.org/format_1614,SGD gene report format, +http://edamontology.org/format_1615,GeneDB gene report format, +http://edamontology.org/format_1616,TAIR gene report format, +http://edamontology.org/format_1617,WormBase gene report format, +http://edamontology.org/format_1618,ZFIN gene report format, +http://edamontology.org/format_1619,TIGR gene report format, +http://edamontology.org/format_1620,dbSNP polymorphism report format, +http://edamontology.org/format_1623,OMIM entry format, +http://edamontology.org/format_1624,HGVbase entry format, +http://edamontology.org/format_1625,HIVDB entry format, +http://edamontology.org/format_1626,KEGG DISEASE entry format, +http://edamontology.org/format_1627,Primer3 primer, +http://edamontology.org/format_1628,ABI, +http://edamontology.org/format_1629,mira, +http://edamontology.org/format_1630,CAF, +http://edamontology.org/format_1631,EXP, +http://edamontology.org/format_1632,SCF, +http://edamontology.org/format_1633,PHD, +http://edamontology.org/format_1637,dat, +http://edamontology.org/format_1638,cel, +http://edamontology.org/format_1639,affymetrix, +http://edamontology.org/format_1640,ArrayExpress entry format, +http://edamontology.org/format_1641,affymetrix-exp, +http://edamontology.org/format_1644,CHP, +http://edamontology.org/format_1645,EMDB entry format, +http://edamontology.org/format_1647,KEGG PATHWAY entry format, +http://edamontology.org/format_1648,MetaCyc entry format, +http://edamontology.org/format_1649,HumanCyc entry format, +http://edamontology.org/format_1650,INOH entry format, +http://edamontology.org/format_1651,PATIKA entry format, +http://edamontology.org/format_1652,Reactome entry format, +http://edamontology.org/format_1653,aMAZE entry format, +http://edamontology.org/format_1654,CPDB entry format, +http://edamontology.org/format_1655,Panther Pathways entry format, +http://edamontology.org/format_1665,Taverna workflow format, +http://edamontology.org/format_1666,BioModel mathematical model format, +http://edamontology.org/format_1697,KEGG LIGAND entry format, +http://edamontology.org/format_1698,KEGG COMPOUND entry format, +http://edamontology.org/format_1699,KEGG PLANT entry format, +http://edamontology.org/format_1700,KEGG GLYCAN entry format, +http://edamontology.org/format_1701,PubChem entry format, +http://edamontology.org/format_1702,ChemSpider entry format, +http://edamontology.org/format_1703,ChEBI entry format, +http://edamontology.org/format_1704,MSDchem ligand dictionary entry format, +http://edamontology.org/format_1705,HET group dictionary entry format, +http://edamontology.org/format_1706,KEGG DRUG entry format, +http://edamontology.org/format_1734,PubMed citation, +http://edamontology.org/format_1735,Medline Display Format, +http://edamontology.org/format_1736,CiteXplore-core, +http://edamontology.org/format_1737,CiteXplore-all, +http://edamontology.org/format_1739,pmc, +http://edamontology.org/format_1740,iHOP format, +http://edamontology.org/format_1741,OSCAR format, +http://edamontology.org/format_1747,PDB atom record format, +http://edamontology.org/format_1760,CATH chain report format, +http://edamontology.org/format_1761,CATH PDB report format, +http://edamontology.org/format_1782,NCBI gene report format, +http://edamontology.org/format_1808,GeneIlluminator gene report format, +http://edamontology.org/format_1809,BacMap gene card format, +http://edamontology.org/format_1810,ColiCard report format, +http://edamontology.org/format_1861,PlasMapper TextMap, +http://edamontology.org/format_1910,newick, +http://edamontology.org/format_1911,TreeCon format, +http://edamontology.org/format_1912,Nexus format, +http://edamontology.org/format_1915,Format, +http://edamontology.org/format_1918,Atomic data format, +http://edamontology.org/format_1919,Sequence record format, +http://edamontology.org/format_1920,Sequence feature annotation format, +http://edamontology.org/format_1921,Alignment format, +http://edamontology.org/format_1923,acedb, +http://edamontology.org/format_1924,clustal sequence format, +http://edamontology.org/format_1925,codata, +http://edamontology.org/format_1926,dbid, +http://edamontology.org/format_1927,EMBL format, +http://edamontology.org/format_1928,Staden experiment format, +http://edamontology.org/format_1929,FASTA, +http://edamontology.org/format_1930,FASTQ,fq|fastq +http://edamontology.org/format_1931,FASTQ-illumina, +http://edamontology.org/format_1932,FASTQ-sanger, +http://edamontology.org/format_1933,FASTQ-solexa, +http://edamontology.org/format_1934,fitch program, +http://edamontology.org/format_1935,GCG, +http://edamontology.org/format_1936,GenBank format, +http://edamontology.org/format_1937,genpept, +http://edamontology.org/format_1938,GFF2-seq, +http://edamontology.org/format_1939,GFF3-seq, +http://edamontology.org/format_1940,giFASTA format, +http://edamontology.org/format_1941,hennig86, +http://edamontology.org/format_1942,ig, +http://edamontology.org/format_1943,igstrict, +http://edamontology.org/format_1944,jackknifer, +http://edamontology.org/format_1945,mase format, +http://edamontology.org/format_1946,mega-seq, +http://edamontology.org/format_1947,GCG MSF, +http://edamontology.org/format_1948,nbrf/pir, +http://edamontology.org/format_1949,nexus-seq, +http://edamontology.org/format_1950,pdbatom, +http://edamontology.org/format_1951,pdbatomnuc, +http://edamontology.org/format_1952,pdbseqresnuc, +http://edamontology.org/format_1953,pdbseqres, +http://edamontology.org/format_1954,Pearson format, +http://edamontology.org/format_1955,phylip sequence format, +http://edamontology.org/format_1956,phylipnon sequence format, +http://edamontology.org/format_1957,raw, +http://edamontology.org/format_1958,refseqp, +http://edamontology.org/format_1959,selex sequence format, +http://edamontology.org/format_1960,Staden format, +http://edamontology.org/format_1961,Stockholm format, +http://edamontology.org/format_1962,strider format, +http://edamontology.org/format_1963,UniProtKB format, +http://edamontology.org/format_1964,plain text format (unformatted), +http://edamontology.org/format_1965,treecon sequence format, +http://edamontology.org/format_1966,ASN.1 sequence format, +http://edamontology.org/format_1967,DAS format, +http://edamontology.org/format_1968,dasdna, +http://edamontology.org/format_1969,debug-seq, +http://edamontology.org/format_1970,jackknifernon, +http://edamontology.org/format_1971,meganon sequence format, +http://edamontology.org/format_1972,NCBI format, +http://edamontology.org/format_1973,nexusnon, +http://edamontology.org/format_1974,GFF2, +http://edamontology.org/format_1975,GFF3, +http://edamontology.org/format_1976,pir, +http://edamontology.org/format_1977,swiss feature, +http://edamontology.org/format_1978,DASGFF, +http://edamontology.org/format_1979,debug-feat, +http://edamontology.org/format_1980,EMBL feature, +http://edamontology.org/format_1981,GenBank feature, +http://edamontology.org/format_1982,ClustalW format, +http://edamontology.org/format_1983,debug, +http://edamontology.org/format_1984,FASTA-aln, +http://edamontology.org/format_1985,markx0, +http://edamontology.org/format_1986,markx1, +http://edamontology.org/format_1987,markx10, +http://edamontology.org/format_1988,markx2, +http://edamontology.org/format_1989,markx3, +http://edamontology.org/format_1990,match, +http://edamontology.org/format_1991,mega, +http://edamontology.org/format_1992,meganon, +http://edamontology.org/format_1993,msf alignment format, +http://edamontology.org/format_1994,nexus alignment format, +http://edamontology.org/format_1995,nexusnon alignment format, +http://edamontology.org/format_1996,pair, +http://edamontology.org/format_1997,PHYLIP format, +http://edamontology.org/format_1998,PHYLIP sequential, +http://edamontology.org/format_1999,scores format, +http://edamontology.org/format_2000,selex, +http://edamontology.org/format_2001,EMBOSS simple format, +http://edamontology.org/format_2002,srs format, +http://edamontology.org/format_2003,srspair, +http://edamontology.org/format_2004,T-Coffee format, +http://edamontology.org/format_2005,TreeCon-seq, +http://edamontology.org/format_2006,Phylogenetic tree format, +http://edamontology.org/format_2013,Biological pathway or network format, +http://edamontology.org/format_2014,Sequence-profile alignment format, +http://edamontology.org/format_2015,Sequence-profile alignment (HMM) format, +http://edamontology.org/format_2017,Amino acid index format, +http://edamontology.org/format_2020,Article format, +http://edamontology.org/format_2021,Text mining report format, +http://edamontology.org/format_2027,Enzyme kinetics report format, +http://edamontology.org/format_2030,Chemical data format, +http://edamontology.org/format_2031,Gene annotation format, +http://edamontology.org/format_2032,Workflow format, +http://edamontology.org/format_2033,Tertiary structure format, +http://edamontology.org/format_2034,Biological model format, +http://edamontology.org/format_2035,Chemical formula format, +http://edamontology.org/format_2036,Phylogenetic character data format, +http://edamontology.org/format_2037,Phylogenetic continuous quantitative character format, +http://edamontology.org/format_2038,Phylogenetic discrete states format, +http://edamontology.org/format_2039,Phylogenetic tree report (cliques) format, +http://edamontology.org/format_2040,Phylogenetic tree report (invariants) format, +http://edamontology.org/format_2045,Electron microscopy model format, +http://edamontology.org/format_2049,Phylogenetic tree report (tree distances) format, +http://edamontology.org/format_2051,Polymorphism report format, +http://edamontology.org/format_2052,Protein family report format, +http://edamontology.org/format_2054,Protein interaction format, +http://edamontology.org/format_2055,Sequence assembly format, +http://edamontology.org/format_2056,Microarray experiment data format, +http://edamontology.org/format_2057,Sequence trace format, +http://edamontology.org/format_2058,Gene expression report format, +http://edamontology.org/format_2059,Genotype and phenotype annotation format, +http://edamontology.org/format_2060,Map format, +http://edamontology.org/format_2061,Nucleic acid features (primers) format, +http://edamontology.org/format_2062,Protein report format, +http://edamontology.org/format_2063,Protein report (enzyme) format, +http://edamontology.org/format_2064,3D-1D scoring matrix format, +http://edamontology.org/format_2065,Protein structure report (quality evaluation) format, +http://edamontology.org/format_2066,Database hits (sequence) format, +http://edamontology.org/format_2067,Sequence distance matrix format, +http://edamontology.org/format_2068,Sequence motif format, +http://edamontology.org/format_2069,Sequence profile format, +http://edamontology.org/format_2072,Hidden Markov model format, +http://edamontology.org/format_2074,Dirichlet distribution format, +http://edamontology.org/format_2075,HMM emission and transition counts format, +http://edamontology.org/format_2076,RNA secondary structure format, +http://edamontology.org/format_2077,Protein secondary structure format, +http://edamontology.org/format_2078,Sequence range format, +http://edamontology.org/format_2094,pure, +http://edamontology.org/format_2095,unpure, +http://edamontology.org/format_2096,unambiguous sequence, +http://edamontology.org/format_2097,ambiguous, +http://edamontology.org/format_2155,Sequence features (repeats) format, +http://edamontology.org/format_2158,Nucleic acid features (restriction sites) format, +http://edamontology.org/format_2159,Gene features (coding region) format, +http://edamontology.org/format_2170,Sequence cluster format, +http://edamontology.org/format_2171,Sequence cluster format (protein), +http://edamontology.org/format_2172,Sequence cluster format (nucleic acid), +http://edamontology.org/format_2175,Gene cluster format, +http://edamontology.org/format_2181,EMBL-like (text), +http://edamontology.org/format_2182,FASTQ-like format (text), +http://edamontology.org/format_2183,EMBLXML, +http://edamontology.org/format_2184,cdsxml, +http://edamontology.org/format_2185,insdxml, +http://edamontology.org/format_2186,geneseq, +http://edamontology.org/format_2187,UniProt-like (text), +http://edamontology.org/format_2188,UniProt format, +http://edamontology.org/format_2189,ipi, +http://edamontology.org/format_2194,medline, +http://edamontology.org/format_2195,Ontology format, +http://edamontology.org/format_2196,OBO format, +http://edamontology.org/format_2197,OWL format, +http://edamontology.org/format_2200,FASTA-like (text), +http://edamontology.org/format_2202,Sequence record full format, +http://edamontology.org/format_2203,Sequence record lite format, +http://edamontology.org/format_2204,EMBL format (XML), +http://edamontology.org/format_2205,GenBank-like format (text), +http://edamontology.org/format_2206,Sequence feature table format (text), +http://edamontology.org/format_2210,Strain data format, +http://edamontology.org/format_2211,CIP strain data format, +http://edamontology.org/format_2243,phylip property values, +http://edamontology.org/format_2303,STRING entry format (HTML), +http://edamontology.org/format_2304,STRING entry format (XML), +http://edamontology.org/format_2305,GFF, +http://edamontology.org/format_2306,GTF, +http://edamontology.org/format_2310,FASTA-HTML, +http://edamontology.org/format_2311,EMBL-HTML, +http://edamontology.org/format_2322,BioCyc enzyme report format, +http://edamontology.org/format_2323,ENZYME enzyme report format, +http://edamontology.org/format_2328,PseudoCAP gene report format, +http://edamontology.org/format_2329,GeneCards gene report format, +http://edamontology.org/format_2330,Textual format, +http://edamontology.org/format_2331,HTML, +http://edamontology.org/format_2332,XML,xml +http://edamontology.org/format_2333,Binary format, +http://edamontology.org/format_2334,URI format, +http://edamontology.org/format_2341,NCI-Nature pathway entry format, +http://edamontology.org/format_2350,Format (by type of data), +http://edamontology.org/format_2352,BioXSD (XML), +http://edamontology.org/format_2376,RDF format, +http://edamontology.org/format_2532,GenBank-HTML, +http://edamontology.org/format_2542,Protein features (domains) format, +http://edamontology.org/format_2543,EMBL-like format, +http://edamontology.org/format_2545,FASTQ-like format, +http://edamontology.org/format_2546,FASTA-like, +http://edamontology.org/format_2547,uniprotkb-like format, +http://edamontology.org/format_2548,Sequence feature table format, +http://edamontology.org/format_2549,OBO, +http://edamontology.org/format_2550,OBO-XML, +http://edamontology.org/format_2551,Sequence record format (text), +http://edamontology.org/format_2552,Sequence record format (XML), +http://edamontology.org/format_2553,Sequence feature table format (XML), +http://edamontology.org/format_2554,Alignment format (text), +http://edamontology.org/format_2555,Alignment format (XML), +http://edamontology.org/format_2556,Phylogenetic tree format (text), +http://edamontology.org/format_2557,Phylogenetic tree format (XML), +http://edamontology.org/format_2558,EMBL-like (XML), +http://edamontology.org/format_2559,GenBank-like format, +http://edamontology.org/format_2560,STRING entry format, +http://edamontology.org/format_2561,Sequence assembly format (text), +http://edamontology.org/format_2562,Amino acid identifier format, +http://edamontology.org/format_2566,completely unambiguous, +http://edamontology.org/format_2567,completely unambiguous pure, +http://edamontology.org/format_2568,completely unambiguous pure nucleotide, +http://edamontology.org/format_2569,completely unambiguous pure dna, +http://edamontology.org/format_2570,completely unambiguous pure rna sequence, +http://edamontology.org/format_2571,Raw sequence format, +http://edamontology.org/format_2572,BAM, +http://edamontology.org/format_2573,SAM, +http://edamontology.org/format_2585,SBML, +http://edamontology.org/format_2607,completely unambiguous pure protein, +http://edamontology.org/format_2848,Bibliographic reference format, +http://edamontology.org/format_2919,Sequence annotation track format, +http://edamontology.org/format_2920,Alignment format (pair only), +http://edamontology.org/format_2921,Sequence variation annotation format, +http://edamontology.org/format_2922,markx0 variant, +http://edamontology.org/format_2923,mega variant, +http://edamontology.org/format_2924,Phylip format variant, +http://edamontology.org/format_3000,AB1, +http://edamontology.org/format_3001,ACE, +http://edamontology.org/format_3003,BED, +http://edamontology.org/format_3004,bigBed, +http://edamontology.org/format_3005,WIG, +http://edamontology.org/format_3006,bigWig, +http://edamontology.org/format_3007,PSL, +http://edamontology.org/format_3008,MAF, +http://edamontology.org/format_3009,2bit, +http://edamontology.org/format_3010,.nib, +http://edamontology.org/format_3011,genePred, +http://edamontology.org/format_3012,pgSnp, +http://edamontology.org/format_3013,axt, +http://edamontology.org/format_3014,LAV, +http://edamontology.org/format_3015,Pileup, +http://edamontology.org/format_3016,VCF, +http://edamontology.org/format_3017,SRF, +http://edamontology.org/format_3018,ZTR, +http://edamontology.org/format_3019,GVF, +http://edamontology.org/format_3020,BCF, +http://edamontology.org/format_3033,Matrix format, +http://edamontology.org/format_3097,Protein domain classification format, +http://edamontology.org/format_3098,Raw SCOP domain classification format, +http://edamontology.org/format_3099,Raw CATH domain classification format, +http://edamontology.org/format_3100,CATH domain report format, +http://edamontology.org/format_3155,SBRML, +http://edamontology.org/format_3156,BioPAX, +http://edamontology.org/format_3157,EBI Application Result XML, +http://edamontology.org/format_3158,PSI MI XML (MIF), +http://edamontology.org/format_3159,phyloXML, +http://edamontology.org/format_3160,NeXML, +http://edamontology.org/format_3161,MAGE-ML, +http://edamontology.org/format_3162,MAGE-TAB, +http://edamontology.org/format_3163,GCDML, +http://edamontology.org/format_3164,GTrack, +http://edamontology.org/format_3166,Biological pathway or network report format, +http://edamontology.org/format_3167,Experiment annotation format, +http://edamontology.org/format_3235,Cytoband format, +http://edamontology.org/format_3239,CopasiML, +http://edamontology.org/format_3240,CellML, +http://edamontology.org/format_3242,PSI MI TAB (MITAB), +http://edamontology.org/format_3243,PSI-PAR, +http://edamontology.org/format_3244,mzML, +http://edamontology.org/format_3245,Mass spectrometry data format, +http://edamontology.org/format_3246,TraML, +http://edamontology.org/format_3247,mzIdentML, +http://edamontology.org/format_3248,mzQuantML, +http://edamontology.org/format_3249,GelML, +http://edamontology.org/format_3250,spML, +http://edamontology.org/format_3252,OWL Functional Syntax, +http://edamontology.org/format_3253,Manchester OWL Syntax, +http://edamontology.org/format_3254,KRSS2 Syntax, +http://edamontology.org/format_3255,Turtle, +http://edamontology.org/format_3256,N-Triples,nt +http://edamontology.org/format_3257,Notation3,n3 +http://edamontology.org/format_3261,RDF/XML,rdf +http://edamontology.org/format_3262,OWL/XML, +http://edamontology.org/format_3281,A2M, +http://edamontology.org/format_3284,SFF, +http://edamontology.org/format_3285,MAP, +http://edamontology.org/format_3286,PED, +http://edamontology.org/format_3287,Individual genetic data format, +http://edamontology.org/format_3288,PED/MAP, +http://edamontology.org/format_3309,CT, +http://edamontology.org/format_3310,SS, +http://edamontology.org/format_3311,RNAML, +http://edamontology.org/format_3312,GDE, +http://edamontology.org/format_3313,BLC, +http://edamontology.org/format_3326,Data index format, +http://edamontology.org/format_3327,BAI, +http://edamontology.org/format_3328,HMMER2, +http://edamontology.org/format_3329,HMMER3, +http://edamontology.org/format_3330,PO, +http://edamontology.org/format_3331,BLAST XML results format, +http://edamontology.org/format_3462,CRAM, +http://edamontology.org/format_3464,JSON,json +http://edamontology.org/format_3466,EPS, +http://edamontology.org/format_3467,GIF, +http://edamontology.org/format_3468,xls, +http://edamontology.org/format_3475,TSV,tsv|tab +http://edamontology.org/format_3476,Gene expression data format, +http://edamontology.org/format_3477,Cytoscape input file format, +http://edamontology.org/format_3484,ebwt, +http://edamontology.org/format_3485,RSF, +http://edamontology.org/format_3486,GCG format variant, +http://edamontology.org/format_3487,BSML, +http://edamontology.org/format_3491,ebwtl, +http://edamontology.org/format_3499,Ensembl variation file format, +http://edamontology.org/format_3506,docx, +http://edamontology.org/format_3507,Document format, +http://edamontology.org/format_3508,PDF, +http://edamontology.org/format_3547,Image format, +http://edamontology.org/format_3548,DICOM format, +http://edamontology.org/format_3549,nii, +http://edamontology.org/format_3550,mhd, +http://edamontology.org/format_3551,nrrd, +http://edamontology.org/format_3554,R file format, +http://edamontology.org/format_3555,SPSS, +http://edamontology.org/format_3556,MHTML,mhtml|mht|eml +http://edamontology.org/format_3578,IDAT, +http://edamontology.org/format_3579,JPG, +http://edamontology.org/format_3580,rcc, +http://edamontology.org/format_3581,arff, +http://edamontology.org/format_3582,afg, +http://edamontology.org/format_3583,bedgraph, +http://edamontology.org/format_3584,bedstrict, +http://edamontology.org/format_3585,bed6, +http://edamontology.org/format_3586,bed12, +http://edamontology.org/format_3587,chrominfo, +http://edamontology.org/format_3588,customtrack, +http://edamontology.org/format_3589,csfasta, +http://edamontology.org/format_3590,HDF5, +http://edamontology.org/format_3591,TIFF, +http://edamontology.org/format_3592,BMP, +http://edamontology.org/format_3593,im, +http://edamontology.org/format_3594,pcd, +http://edamontology.org/format_3595,pcx, +http://edamontology.org/format_3596,ppm, +http://edamontology.org/format_3597,psd, +http://edamontology.org/format_3598,xbm, +http://edamontology.org/format_3599,xpm, +http://edamontology.org/format_3600,rgb, +http://edamontology.org/format_3601,pbm, +http://edamontology.org/format_3602,pgm, +http://edamontology.org/format_3603,PNG, +http://edamontology.org/format_3604,SVG, +http://edamontology.org/format_3605,rast, +http://edamontology.org/format_3606,Sequence quality report format (text), +http://edamontology.org/format_3607,qual, +http://edamontology.org/format_3608,qualsolexa, +http://edamontology.org/format_3609,qualillumina, +http://edamontology.org/format_3610,qualsolid, +http://edamontology.org/format_3611,qual454, +http://edamontology.org/format_3612,ENCODE peak format, +http://edamontology.org/format_3613,ENCODE narrow peak format, +http://edamontology.org/format_3614,ENCODE broad peak format, +http://edamontology.org/format_3615,bgzip, +http://edamontology.org/format_3616,tabix, +http://edamontology.org/format_3617,Graph format, +http://edamontology.org/format_3618,xgmml, +http://edamontology.org/format_3619,sif, +http://edamontology.org/format_3620,xlsx, +http://edamontology.org/format_3621,SQLite format, +http://edamontology.org/format_3622,Gemini SQLite format, +http://edamontology.org/format_3623,Index format, +http://edamontology.org/format_3624,snpeffdb, +http://edamontology.org/format_3626,MAT, +http://edamontology.org/format_3650,netCDF, +http://edamontology.org/format_3651,MGF, +http://edamontology.org/format_3652,dta, +http://edamontology.org/format_3653,pkl, +http://edamontology.org/format_3654,mzXML, +http://edamontology.org/format_3655,pepXML, +http://edamontology.org/format_3657,GPML, +http://edamontology.org/format_3665,K-mer countgraph,oxlicg +http://edamontology.org/format_3681,mzTab, +http://edamontology.org/format_3682,imzML metadata file,imzML +http://edamontology.org/format_3683,qcML, +http://edamontology.org/format_3684,PRIDE XML, +http://edamontology.org/format_3685,SED-ML, +http://edamontology.org/format_3686,COMBINE OMEX, +http://edamontology.org/format_3687,ISA-TAB, +http://edamontology.org/format_3688,SBtab, +http://edamontology.org/format_3689,BCML, +http://edamontology.org/format_3690,BDML, +http://edamontology.org/format_3691,BEL, +http://edamontology.org/format_3692,SBGN-ML, +http://edamontology.org/format_3693,AGP, +http://edamontology.org/format_3696,PS, +http://edamontology.org/format_3698,SRA format, +http://edamontology.org/format_3699,VDB, +http://edamontology.org/format_3700,Tabix index file format, +http://edamontology.org/format_3701,Sequin format, +http://edamontology.org/format_3702,MSF, +http://edamontology.org/format_3706,Biodiversity data format, +http://edamontology.org/format_3708,ABCD format, +http://edamontology.org/format_3709,GCT/Res format, +http://edamontology.org/format_3710,WIFF format,wiff +http://edamontology.org/format_3711,X!Tandem XML, +http://edamontology.org/format_3712,Thermo RAW, +http://edamontology.org/format_3713,Mascot .dat file, +http://edamontology.org/format_3714,MaxQuant APL peaklist format, +http://edamontology.org/format_3725,SBOL, +http://edamontology.org/format_3726,PMML, +http://edamontology.org/format_3727,OME-TIFF, +http://edamontology.org/format_3728,LocARNA PP, +http://edamontology.org/format_3729,dbGaP format, +http://edamontology.org/format_3746,BIOM format,biom +http://edamontology.org/format_3747,protXML, +http://edamontology.org/format_3748,Linked data format, +http://edamontology.org/format_3749,JSON-LD,jsonld +http://edamontology.org/format_3750,YAML,yaml|yml +http://edamontology.org/format_3751,DSV, +http://edamontology.org/format_3752,CSV,csv +http://edamontology.org/format_3758,SEQUEST .out file, +http://edamontology.org/format_3764,idXML, +http://edamontology.org/format_3765,KNIME datatable format, +http://edamontology.org/format_3770,UniProtKB XML, +http://edamontology.org/format_3771,UniProtKB RDF, +http://edamontology.org/format_3772,BioJSON (BioXSD), +http://edamontology.org/format_3773,BioYAML, +http://edamontology.org/format_3774,BioJSON (Jalview), +http://edamontology.org/format_3775,GSuite, +http://edamontology.org/format_3776,BTrack, +http://edamontology.org/format_3777,MCPD, +http://edamontology.org/format_3780,Annotated text format, +http://edamontology.org/format_3781,PubAnnotation format, +http://edamontology.org/format_3782,BioC, +http://edamontology.org/format_3783,PubTator format, +http://edamontology.org/format_3784,Open Annotation format, +http://edamontology.org/format_3785,BioNLP Shared Task format, +http://edamontology.org/format_3787,Query language, +http://edamontology.org/format_3788,SQL,sql +http://edamontology.org/format_3789,XQuery,xq|xqy|xquery +http://edamontology.org/format_3790,SPARQL, +http://edamontology.org/format_3804,xsd, +http://edamontology.org/format_3811,XMFA, +http://edamontology.org/format_3812,GEN, +http://edamontology.org/format_3813,SAMPLE file format, +http://edamontology.org/format_3814,SDF, +http://edamontology.org/format_3815,Molfile, +http://edamontology.org/format_3816,Mol2, +http://edamontology.org/format_3817,latex, +http://edamontology.org/format_3818,ELAND format, +http://edamontology.org/format_3819,Relaxed PHYLIP Interleaved, +http://edamontology.org/format_3820,Relaxed PHYLIP Sequential, +http://edamontology.org/format_3821,VisML, +http://edamontology.org/format_3822,GML, +http://edamontology.org/format_3823,FASTG, +http://edamontology.org/format_3824,NMR data format, +http://edamontology.org/format_3825,nmrML, +http://edamontology.org/format_3826,proBAM, +http://edamontology.org/format_3827,proBED, +http://edamontology.org/format_3828,Raw microarray data format, +http://edamontology.org/format_3829,GPR, +http://edamontology.org/format_3830,ARB, +http://edamontology.org/format_3832,consensusXML, +http://edamontology.org/format_3833,featureXML, +http://edamontology.org/format_3834,mzData, +http://edamontology.org/format_3835,TIDE TXT, +http://edamontology.org/format_3836,BLAST XML v2 results format, +http://edamontology.org/format_3838,pptx, +http://edamontology.org/format_3839,ibd,ibd +http://edamontology.org/format_3841,NLP format, +http://edamontology.org/format_3843,BEAST, +http://edamontology.org/format_3844,Chado-XML, +http://edamontology.org/format_3845,HSAML, +http://edamontology.org/format_3846,InterProScan XML, +http://edamontology.org/format_3847,KGML, +http://edamontology.org/format_3848,PubMed XML, +http://edamontology.org/format_3849,MSAML, +http://edamontology.org/format_3850,OrthoXML, +http://edamontology.org/format_3851,PSDML, +http://edamontology.org/format_3852,SeqXML, +http://edamontology.org/format_3853,UniParc XML, +http://edamontology.org/format_3854,UniRef XML, +http://edamontology.org/format_3857,CWL,cwl +http://edamontology.org/format_3858,Waters RAW, +http://edamontology.org/format_3859,JCAMP-DX, +http://edamontology.org/format_3862,NLP annotation format, +http://edamontology.org/format_3863,NLP corpus format, +http://edamontology.org/format_3864,mirGFF3, +http://edamontology.org/format_3865,RNA annotation format, +http://edamontology.org/format_3866,Trajectory format, +http://edamontology.org/format_3867,Trajectory format (binary), +http://edamontology.org/format_3868,Trajectory format (text), +http://edamontology.org/format_3873,HDF, +http://edamontology.org/format_3874,PCAzip, +http://edamontology.org/format_3875,XTC, +http://edamontology.org/format_3876,TNG, +http://edamontology.org/format_3877,XYZ, +http://edamontology.org/format_3878,mdcrd, +http://edamontology.org/format_3879,Topology format, +http://edamontology.org/format_3880,GROMACS top, +http://edamontology.org/format_3881,AMBER top, +http://edamontology.org/format_3882,PSF, +http://edamontology.org/format_3883,GROMACS itp, +http://edamontology.org/format_3884,FF parameter format, +http://edamontology.org/format_3885,BinPos, +http://edamontology.org/format_3886,RST, +http://edamontology.org/format_3887,CHARMM rtf, +http://edamontology.org/format_3888,AMBER frcmod, +http://edamontology.org/format_3889,AMBER off, +http://edamontology.org/format_3906,NMReDATA, +http://edamontology.org/format_3909,BpForms, +http://edamontology.org/format_3910,trr, +http://edamontology.org/format_3911,msh,msh +http://edamontology.org/format_3913,Loom,loom +http://edamontology.org/format_3915,Zarr,zarray|zgroup +http://edamontology.org/format_3916,MTX,mtx +http://edamontology.org/format_3951,BcForms, +http://edamontology.org/format_3956,N-Quads,nq +http://edamontology.org/format_3969,Vega,json +http://edamontology.org/format_3970,Vega-lite,json +http://edamontology.org/format_3971,NeuroML, +http://edamontology.org/format_3972,BNGL,bngl +http://edamontology.org/format_3973,Docker image format,dockerfile +http://edamontology.org/format_3975,GFA 1,gfa +http://edamontology.org/format_3976,GFA 2,gfa +http://edamontology.org/format_3977,ObjTables,xlsx +http://edamontology.org/format_3978,CONTIG,contig +http://edamontology.org/format_3979,WEGO,wego +http://edamontology.org/format_3980,RPKM,rpkm +http://edamontology.org/format_3981,TAR format,tar +http://edamontology.org/format_3982,CHAIN,chain +http://edamontology.org/format_3983,NET,net +http://edamontology.org/format_3984,QMAP,qmap +http://edamontology.org/format_3985,gxformat2,ga +http://edamontology.org/format_3986,WMV,wmv +http://edamontology.org/format_3987,ZIP format,zip +http://edamontology.org/format_3988,LSM,lsm +http://edamontology.org/format_3989,GZIP format,gz|gzip +http://edamontology.org/format_3990,AVI,avi +http://edamontology.org/format_3991,TrackDB,trackDb +http://edamontology.org/format_3992,CIGAR format,cigar +http://edamontology.org/format_3993,Stereolithography format,stl +http://edamontology.org/format_3994,U3D,u3d +http://edamontology.org/format_3995,Texture file format,tex +http://edamontology.org/format_3996,Python script,py +http://edamontology.org/format_3997,MPEG-4,mp4 +http://edamontology.org/format_3998,Perl script,pl +http://edamontology.org/format_3999,R script,R +http://edamontology.org/format_4000,R markdown,Rmd +http://edamontology.org/format_4001,NIFTI format,nii +http://edamontology.org/format_4002,pickle,pickle +http://edamontology.org/format_4003,NumPy format,npy +http://edamontology.org/format_4004,SimTools repertoire file format,repz +http://edamontology.org/format_4005,Configuration file format,cfg +http://edamontology.org/format_4006,Zstandard format,zst +http://edamontology.org/format_4007,MATLAB script,m +http://edamontology.org/operation_0004,Operation, +http://edamontology.org/operation_0224,Query and retrieval, +http://edamontology.org/operation_0225,Data retrieval (database cross-reference), +http://edamontology.org/operation_0226,Annotation, +http://edamontology.org/operation_0227,Indexing, +http://edamontology.org/operation_0228,Data index analysis, +http://edamontology.org/operation_0229,Annotation retrieval (sequence), +http://edamontology.org/operation_0230,Sequence generation, +http://edamontology.org/operation_0231,Sequence editing, +http://edamontology.org/operation_0232,Sequence merging, +http://edamontology.org/operation_0233,Sequence conversion, +http://edamontology.org/operation_0234,Sequence complexity calculation, +http://edamontology.org/operation_0235,Sequence ambiguity calculation, +http://edamontology.org/operation_0236,Sequence composition calculation, +http://edamontology.org/operation_0237,Repeat sequence analysis, +http://edamontology.org/operation_0238,Sequence motif discovery, +http://edamontology.org/operation_0239,Sequence motif recognition, +http://edamontology.org/operation_0240,Sequence motif comparison, +http://edamontology.org/operation_0241,Transcription regulatory sequence analysis, +http://edamontology.org/operation_0242,Conserved transcription regulatory sequence identification, +http://edamontology.org/operation_0243,Protein property calculation (from structure), +http://edamontology.org/operation_0244,Simulation analysis, +http://edamontology.org/operation_0245,Structural motif discovery, +http://edamontology.org/operation_0246,Protein domain recognition, +http://edamontology.org/operation_0247,Protein architecture analysis, +http://edamontology.org/operation_0248,Residue interaction calculation, +http://edamontology.org/operation_0249,Protein geometry calculation, +http://edamontology.org/operation_0250,Protein property calculation, +http://edamontology.org/operation_0252,Peptide immunogenicity prediction, +http://edamontology.org/operation_0253,Sequence feature detection, +http://edamontology.org/operation_0254,Data retrieval (feature table), +http://edamontology.org/operation_0255,Feature table query, +http://edamontology.org/operation_0256,Sequence feature comparison, +http://edamontology.org/operation_0257,Data retrieval (sequence alignment), +http://edamontology.org/operation_0258,Sequence alignment analysis, +http://edamontology.org/operation_0259,Sequence alignment comparison, +http://edamontology.org/operation_0260,Sequence alignment conversion, +http://edamontology.org/operation_0261,Nucleic acid property processing, +http://edamontology.org/operation_0262,Nucleic acid property calculation, +http://edamontology.org/operation_0264,Alternative splicing prediction, +http://edamontology.org/operation_0265,Frameshift detection, +http://edamontology.org/operation_0266,Vector sequence detection, +http://edamontology.org/operation_0267,Protein secondary structure prediction, +http://edamontology.org/operation_0268,Protein super-secondary structure prediction, +http://edamontology.org/operation_0269,Transmembrane protein prediction, +http://edamontology.org/operation_0270,Transmembrane protein analysis, +http://edamontology.org/operation_0271,Structure prediction, +http://edamontology.org/operation_0272,Residue contact prediction, +http://edamontology.org/operation_0273,Protein interaction raw data analysis, +http://edamontology.org/operation_0274,Protein-protein interaction prediction (from protein sequence), +http://edamontology.org/operation_0275,Protein-protein interaction prediction (from protein structure), +http://edamontology.org/operation_0276,Protein interaction network analysis, +http://edamontology.org/operation_0277,Pathway or network comparison, +http://edamontology.org/operation_0278,RNA secondary structure prediction, +http://edamontology.org/operation_0279,Nucleic acid folding analysis, +http://edamontology.org/operation_0280,Data retrieval (restriction enzyme annotation), +http://edamontology.org/operation_0281,Genetic marker identification, +http://edamontology.org/operation_0282,Genetic mapping, +http://edamontology.org/operation_0283,Linkage analysis, +http://edamontology.org/operation_0284,Codon usage table generation, +http://edamontology.org/operation_0285,Codon usage table comparison, +http://edamontology.org/operation_0286,Codon usage analysis, +http://edamontology.org/operation_0287,Base position variability plotting, +http://edamontology.org/operation_0288,Sequence word comparison, +http://edamontology.org/operation_0289,Sequence distance matrix generation, +http://edamontology.org/operation_0290,Sequence redundancy removal, +http://edamontology.org/operation_0291,Sequence clustering, +http://edamontology.org/operation_0292,Sequence alignment, +http://edamontology.org/operation_0293,Hybrid sequence alignment construction, +http://edamontology.org/operation_0294,Structure-based sequence alignment, +http://edamontology.org/operation_0295,Structure alignment, +http://edamontology.org/operation_0296,Sequence profile generation, +http://edamontology.org/operation_0297,3D profile generation, +http://edamontology.org/operation_0298,Profile-profile alignment, +http://edamontology.org/operation_0299,3D profile-to-3D profile alignment, +http://edamontology.org/operation_0300,Sequence profile alignment, +http://edamontology.org/operation_0301,Sequence-to-3D-profile alignment, +http://edamontology.org/operation_0302,Protein threading, +http://edamontology.org/operation_0303,Fold recognition, +http://edamontology.org/operation_0304,Metadata retrieval, +http://edamontology.org/operation_0305,Literature search, +http://edamontology.org/operation_0306,Text mining, +http://edamontology.org/operation_0307,Virtual PCR, +http://edamontology.org/operation_0308,PCR primer design, +http://edamontology.org/operation_0309,Microarray probe design, +http://edamontology.org/operation_0310,Sequence assembly, +http://edamontology.org/operation_0311,Microarray data standardisation and normalisation, +http://edamontology.org/operation_0312,Sequencing-based expression profile data processing, +http://edamontology.org/operation_0313,Expression profile clustering, +http://edamontology.org/operation_0314,Gene expression profiling, +http://edamontology.org/operation_0315,Expression profile comparison, +http://edamontology.org/operation_0316,Functional profiling, +http://edamontology.org/operation_0317,EST and cDNA sequence analysis, +http://edamontology.org/operation_0318,Structural genomics target selection, +http://edamontology.org/operation_0319,Protein secondary structure assignment, +http://edamontology.org/operation_0320,Protein structure assignment, +http://edamontology.org/operation_0321,Protein structure validation, +http://edamontology.org/operation_0322,Molecular model refinement, +http://edamontology.org/operation_0323,Phylogenetic inference, +http://edamontology.org/operation_0324,Phylogenetic analysis, +http://edamontology.org/operation_0325,Phylogenetic tree comparison, +http://edamontology.org/operation_0326,Phylogenetic tree editing, +http://edamontology.org/operation_0327,Phylogenetic footprinting, +http://edamontology.org/operation_0328,Protein folding simulation, +http://edamontology.org/operation_0329,Protein folding pathway prediction, +http://edamontology.org/operation_0330,Protein SNP mapping, +http://edamontology.org/operation_0331,Variant effect prediction, +http://edamontology.org/operation_0332,Immunogen design, +http://edamontology.org/operation_0333,Zinc finger prediction, +http://edamontology.org/operation_0334,Enzyme kinetics calculation, +http://edamontology.org/operation_0335,Formatting, +http://edamontology.org/operation_0336,Format validation, +http://edamontology.org/operation_0337,Visualisation, +http://edamontology.org/operation_0338,Sequence database search, +http://edamontology.org/operation_0339,Structure database search, +http://edamontology.org/operation_0340,Protein secondary database search, +http://edamontology.org/operation_0341,Motif database search, +http://edamontology.org/operation_0342,Sequence profile database search, +http://edamontology.org/operation_0343,Transmembrane protein database search, +http://edamontology.org/operation_0344,Sequence retrieval (by code), +http://edamontology.org/operation_0345,Sequence retrieval (by keyword), +http://edamontology.org/operation_0346,Sequence similarity search, +http://edamontology.org/operation_0347,Sequence database search (by motif or pattern), +http://edamontology.org/operation_0348,Sequence database search (by amino acid composition), +http://edamontology.org/operation_0349,Sequence database search (by property), +http://edamontology.org/operation_0350,Sequence database search (by sequence using word-based methods), +http://edamontology.org/operation_0351,Sequence database search (by sequence using profile-based methods), +http://edamontology.org/operation_0352,Sequence database search (by sequence using local alignment-based methods), +http://edamontology.org/operation_0353,Sequence database search (by sequence using global alignment-based methods), +http://edamontology.org/operation_0354,Sequence database search (by sequence for primer sequences), +http://edamontology.org/operation_0355,Sequence database search (by molecular weight), +http://edamontology.org/operation_0356,Sequence database search (by isoelectric point), +http://edamontology.org/operation_0357,Structure retrieval (by code), +http://edamontology.org/operation_0358,Structure retrieval (by keyword), +http://edamontology.org/operation_0359,Structure database search (by sequence), +http://edamontology.org/operation_0360,Structural similarity search, +http://edamontology.org/operation_0361,Sequence annotation, +http://edamontology.org/operation_0362,Genome annotation, +http://edamontology.org/operation_0363,Reverse complement, +http://edamontology.org/operation_0364,Random sequence generation, +http://edamontology.org/operation_0365,Restriction digest, +http://edamontology.org/operation_0366,Protein sequence cleavage, +http://edamontology.org/operation_0367,Sequence mutation and randomisation, +http://edamontology.org/operation_0368,Sequence masking, +http://edamontology.org/operation_0369,Sequence cutting, +http://edamontology.org/operation_0370,Restriction site creation, +http://edamontology.org/operation_0371,DNA translation, +http://edamontology.org/operation_0372,DNA transcription, +http://edamontology.org/operation_0377,Sequence composition calculation (nucleic acid), +http://edamontology.org/operation_0378,Sequence composition calculation (protein), +http://edamontology.org/operation_0379,Repeat sequence detection, +http://edamontology.org/operation_0380,Repeat sequence organisation analysis, +http://edamontology.org/operation_0383,Protein hydropathy calculation (from structure), +http://edamontology.org/operation_0384,Accessible surface calculation, +http://edamontology.org/operation_0385,Protein hydropathy cluster calculation, +http://edamontology.org/operation_0386,Protein dipole moment calculation, +http://edamontology.org/operation_0387,Molecular surface calculation, +http://edamontology.org/operation_0388,Protein binding site prediction (from structure), +http://edamontology.org/operation_0389,Protein-nucleic acid interaction analysis, +http://edamontology.org/operation_0390,Protein peeling, +http://edamontology.org/operation_0391,Protein distance matrix calculation, +http://edamontology.org/operation_0392,Contact map calculation, +http://edamontology.org/operation_0393,Residue cluster calculation, +http://edamontology.org/operation_0394,Hydrogen bond calculation, +http://edamontology.org/operation_0395,Residue non-canonical interaction detection, +http://edamontology.org/operation_0396,Ramachandran plot calculation, +http://edamontology.org/operation_0397,Ramachandran plot validation, +http://edamontology.org/operation_0398,Protein molecular weight calculation, +http://edamontology.org/operation_0399,Protein extinction coefficient calculation, +http://edamontology.org/operation_0400,Protein pKa calculation, +http://edamontology.org/operation_0401,Protein hydropathy calculation (from sequence), +http://edamontology.org/operation_0402,Protein titration curve plotting, +http://edamontology.org/operation_0403,Protein isoelectric point calculation, +http://edamontology.org/operation_0404,Protein hydrogen exchange rate calculation, +http://edamontology.org/operation_0405,Protein hydrophobic region calculation, +http://edamontology.org/operation_0406,Protein aliphatic index calculation, +http://edamontology.org/operation_0407,Protein hydrophobic moment plotting, +http://edamontology.org/operation_0408,Protein globularity prediction, +http://edamontology.org/operation_0409,Protein solubility prediction, +http://edamontology.org/operation_0410,Protein crystallizability prediction, +http://edamontology.org/operation_0411,Protein signal peptide detection (eukaryotes), +http://edamontology.org/operation_0412,Protein signal peptide detection (bacteria), +http://edamontology.org/operation_0413,MHC peptide immunogenicity prediction, +http://edamontology.org/operation_0414,Protein feature prediction (from sequence), +http://edamontology.org/operation_0415,Nucleic acid feature detection, +http://edamontology.org/operation_0416,Epitope mapping, +http://edamontology.org/operation_0417,PTM site prediction, +http://edamontology.org/operation_0418,Protein signal peptide detection, +http://edamontology.org/operation_0419,Protein binding site prediction (from sequence), +http://edamontology.org/operation_0420,Nucleic acids-binding site prediction, +http://edamontology.org/operation_0421,Protein folding site prediction, +http://edamontology.org/operation_0422,Protein cleavage site prediction, +http://edamontology.org/operation_0423,Epitope mapping (MHC Class I), +http://edamontology.org/operation_0424,Epitope mapping (MHC Class II), +http://edamontology.org/operation_0425,Whole gene prediction, +http://edamontology.org/operation_0426,Gene component prediction, +http://edamontology.org/operation_0427,Transposon prediction, +http://edamontology.org/operation_0428,PolyA signal detection, +http://edamontology.org/operation_0429,Quadruplex formation site detection, +http://edamontology.org/operation_0430,CpG island and isochore detection, +http://edamontology.org/operation_0431,Restriction site recognition, +http://edamontology.org/operation_0432,Nucleosome position prediction, +http://edamontology.org/operation_0433,Splice site prediction, +http://edamontology.org/operation_0434,Integrated gene prediction, +http://edamontology.org/operation_0435,Operon prediction, +http://edamontology.org/operation_0436,Coding region prediction, +http://edamontology.org/operation_0437,SECIS element prediction, +http://edamontology.org/operation_0438,Transcriptional regulatory element prediction, +http://edamontology.org/operation_0439,Translation initiation site prediction, +http://edamontology.org/operation_0440,Promoter prediction, +http://edamontology.org/operation_0441,cis-regulatory element prediction, +http://edamontology.org/operation_0442,Transcriptional regulatory element prediction (RNA-cis), +http://edamontology.org/operation_0443,trans-regulatory element prediction, +http://edamontology.org/operation_0444,S/MAR prediction, +http://edamontology.org/operation_0445,Transcription factor binding site prediction, +http://edamontology.org/operation_0446,Exonic splicing enhancer prediction, +http://edamontology.org/operation_0447,Sequence alignment validation, +http://edamontology.org/operation_0448,Sequence alignment analysis (conservation), +http://edamontology.org/operation_0449,Sequence alignment analysis (site correlation), +http://edamontology.org/operation_0450,Chimera detection, +http://edamontology.org/operation_0451,Recombination detection, +http://edamontology.org/operation_0452,Indel detection, +http://edamontology.org/operation_0453,Nucleosome formation potential prediction, +http://edamontology.org/operation_0455,Nucleic acid thermodynamic property calculation, +http://edamontology.org/operation_0456,Nucleic acid melting profile plotting, +http://edamontology.org/operation_0457,Nucleic acid stitch profile plotting, +http://edamontology.org/operation_0458,Nucleic acid melting curve plotting, +http://edamontology.org/operation_0459,Nucleic acid probability profile plotting, +http://edamontology.org/operation_0460,Nucleic acid temperature profile plotting, +http://edamontology.org/operation_0461,Nucleic acid curvature calculation, +http://edamontology.org/operation_0463,miRNA target prediction, +http://edamontology.org/operation_0464,tRNA gene prediction, +http://edamontology.org/operation_0465,siRNA binding specificity prediction, +http://edamontology.org/operation_0467,Protein secondary structure prediction (integrated), +http://edamontology.org/operation_0468,Protein secondary structure prediction (helices), +http://edamontology.org/operation_0469,Protein secondary structure prediction (turns), +http://edamontology.org/operation_0470,Protein secondary structure prediction (coils), +http://edamontology.org/operation_0471,Disulfide bond prediction, +http://edamontology.org/operation_0472,GPCR prediction, +http://edamontology.org/operation_0473,GPCR analysis, +http://edamontology.org/operation_0474,Protein structure prediction, +http://edamontology.org/operation_0475,Nucleic acid structure prediction, +http://edamontology.org/operation_0476,Ab initio structure prediction, +http://edamontology.org/operation_0477,Protein modelling, +http://edamontology.org/operation_0478,Molecular docking, +http://edamontology.org/operation_0479,Backbone modelling, +http://edamontology.org/operation_0480,Side chain modelling, +http://edamontology.org/operation_0481,Loop modelling, +http://edamontology.org/operation_0482,Protein-ligand docking, +http://edamontology.org/operation_0483,RNA inverse folding, +http://edamontology.org/operation_0484,SNP detection, +http://edamontology.org/operation_0485,Radiation Hybrid Mapping, +http://edamontology.org/operation_0486,Functional mapping, +http://edamontology.org/operation_0487,Haplotype mapping, +http://edamontology.org/operation_0488,Linkage disequilibrium calculation, +http://edamontology.org/operation_0489,Genetic code prediction, +http://edamontology.org/operation_0490,Dot plot plotting, +http://edamontology.org/operation_0491,Pairwise sequence alignment, +http://edamontology.org/operation_0492,Multiple sequence alignment, +http://edamontology.org/operation_0493,Pairwise sequence alignment generation (local), +http://edamontology.org/operation_0494,Pairwise sequence alignment generation (global), +http://edamontology.org/operation_0495,Local alignment, +http://edamontology.org/operation_0496,Global alignment, +http://edamontology.org/operation_0497,Constrained sequence alignment, +http://edamontology.org/operation_0498,Consensus-based sequence alignment, +http://edamontology.org/operation_0499,Tree-based sequence alignment, +http://edamontology.org/operation_0500,Secondary structure alignment generation, +http://edamontology.org/operation_0501,Protein secondary structure alignment generation, +http://edamontology.org/operation_0502,RNA secondary structure alignment, +http://edamontology.org/operation_0503,Pairwise structure alignment, +http://edamontology.org/operation_0504,Multiple structure alignment, +http://edamontology.org/operation_0505,Structure alignment (protein), +http://edamontology.org/operation_0506,Structure alignment (RNA), +http://edamontology.org/operation_0507,Pairwise structure alignment generation (local), +http://edamontology.org/operation_0508,Pairwise structure alignment generation (global), +http://edamontology.org/operation_0509,Local structure alignment, +http://edamontology.org/operation_0510,Global structure alignment, +http://edamontology.org/operation_0511,Profile-profile alignment (pairwise), +http://edamontology.org/operation_0512,Sequence alignment generation (multiple profile), +http://edamontology.org/operation_0513,3D profile-to-3D profile alignment (pairwise), +http://edamontology.org/operation_0514,Structural profile alignment generation (multiple), +http://edamontology.org/operation_0515,Data retrieval (tool metadata), +http://edamontology.org/operation_0516,Data retrieval (database metadata), +http://edamontology.org/operation_0517,PCR primer design (for large scale sequencing), +http://edamontology.org/operation_0518,PCR primer design (for genotyping polymorphisms), +http://edamontology.org/operation_0519,PCR primer design (for gene transcription profiling), +http://edamontology.org/operation_0520,PCR primer design (for conserved primers), +http://edamontology.org/operation_0521,PCR primer design (based on gene structure), +http://edamontology.org/operation_0522,PCR primer design (for methylation PCRs), +http://edamontology.org/operation_0523,Mapping assembly, +http://edamontology.org/operation_0524,De-novo assembly, +http://edamontology.org/operation_0525,Genome assembly, +http://edamontology.org/operation_0526,EST assembly, +http://edamontology.org/operation_0527,Sequence tag mapping, +http://edamontology.org/operation_0528,SAGE data processing, +http://edamontology.org/operation_0529,MPSS data processing, +http://edamontology.org/operation_0530,SBS data processing, +http://edamontology.org/operation_0531,Heat map generation, +http://edamontology.org/operation_0532,Gene expression profile analysis, +http://edamontology.org/operation_0533,Expression profile pathway mapping, +http://edamontology.org/operation_0534,Protein secondary structure assignment (from coordinate data), +http://edamontology.org/operation_0535,Protein secondary structure assignment (from CD data), +http://edamontology.org/operation_0536,Protein structure assignment (from X-ray crystallographic data), +http://edamontology.org/operation_0537,Protein structure assignment (from NMR data), +http://edamontology.org/operation_0538,Phylogenetic inference (data centric), +http://edamontology.org/operation_0539,Phylogenetic inference (method centric), +http://edamontology.org/operation_0540,Phylogenetic inference (from molecular sequences), +http://edamontology.org/operation_0541,Phylogenetic inference (from continuous quantitative characters), +http://edamontology.org/operation_0542,Phylogenetic inference (from gene frequencies), +http://edamontology.org/operation_0543,Phylogenetic inference (from polymorphism data), +http://edamontology.org/operation_0544,Species tree construction, +http://edamontology.org/operation_0545,Phylogenetic inference (parsimony methods), +http://edamontology.org/operation_0546,Phylogenetic inference (minimum distance methods), +http://edamontology.org/operation_0547,Phylogenetic inference (maximum likelihood and Bayesian methods), +http://edamontology.org/operation_0548,Phylogenetic inference (quartet methods), +http://edamontology.org/operation_0549,Phylogenetic inference (AI methods), +http://edamontology.org/operation_0550,DNA substitution modelling, +http://edamontology.org/operation_0551,Phylogenetic tree topology analysis, +http://edamontology.org/operation_0552,Phylogenetic tree bootstrapping, +http://edamontology.org/operation_0553,Gene tree construction, +http://edamontology.org/operation_0554,Allele frequency distribution analysis, +http://edamontology.org/operation_0555,Consensus tree construction, +http://edamontology.org/operation_0556,Phylogenetic sub/super tree construction, +http://edamontology.org/operation_0557,Phylogenetic tree distances calculation, +http://edamontology.org/operation_0558,Phylogenetic tree annotation, +http://edamontology.org/operation_0559,Immunogenicity prediction, +http://edamontology.org/operation_0560,DNA vaccine design, +http://edamontology.org/operation_0561,Sequence formatting, +http://edamontology.org/operation_0562,Sequence alignment formatting, +http://edamontology.org/operation_0563,Codon usage table formatting, +http://edamontology.org/operation_0564,Sequence visualisation, +http://edamontology.org/operation_0565,Sequence alignment visualisation, +http://edamontology.org/operation_0566,Sequence cluster visualisation, +http://edamontology.org/operation_0567,Phylogenetic tree visualisation, +http://edamontology.org/operation_0568,RNA secondary structure visualisation, +http://edamontology.org/operation_0569,Protein secondary structure visualisation, +http://edamontology.org/operation_0570,Structure visualisation, +http://edamontology.org/operation_0571,Expression data visualisation, +http://edamontology.org/operation_0572,Protein interaction network visualisation, +http://edamontology.org/operation_0573,Map drawing, +http://edamontology.org/operation_0574,Sequence motif rendering, +http://edamontology.org/operation_0575,Restriction map drawing, +http://edamontology.org/operation_0577,DNA linear map rendering, +http://edamontology.org/operation_0578,Plasmid map drawing, +http://edamontology.org/operation_0579,Operon drawing, +http://edamontology.org/operation_1768,Nucleic acid folding family identification, +http://edamontology.org/operation_1769,Nucleic acid folding energy calculation, +http://edamontology.org/operation_1774,Annotation retrieval, +http://edamontology.org/operation_1777,Protein function prediction, +http://edamontology.org/operation_1778,Protein function comparison, +http://edamontology.org/operation_1780,Sequence submission, +http://edamontology.org/operation_1781,Gene regulatory network analysis, +http://edamontology.org/operation_1812,Parsing, +http://edamontology.org/operation_1813,Sequence retrieval, +http://edamontology.org/operation_1814,Structure retrieval, +http://edamontology.org/operation_1816,Surface rendering, +http://edamontology.org/operation_1817,Protein atom surface calculation (accessible), +http://edamontology.org/operation_1818,Protein atom surface calculation (accessible molecular), +http://edamontology.org/operation_1819,Protein residue surface calculation (accessible), +http://edamontology.org/operation_1820,Protein residue surface calculation (vacuum accessible), +http://edamontology.org/operation_1821,Protein residue surface calculation (accessible molecular), +http://edamontology.org/operation_1822,Protein residue surface calculation (vacuum molecular), +http://edamontology.org/operation_1823,Protein surface calculation (accessible molecular), +http://edamontology.org/operation_1824,Protein surface calculation (accessible), +http://edamontology.org/operation_1825,Backbone torsion angle calculation, +http://edamontology.org/operation_1826,Full torsion angle calculation, +http://edamontology.org/operation_1827,Cysteine torsion angle calculation, +http://edamontology.org/operation_1828,Tau angle calculation, +http://edamontology.org/operation_1829,Cysteine bridge detection, +http://edamontology.org/operation_1830,Free cysteine detection, +http://edamontology.org/operation_1831,Metal-bound cysteine detection, +http://edamontology.org/operation_1832,Residue contact calculation (residue-nucleic acid), +http://edamontology.org/operation_1834,Protein-metal contact calculation, +http://edamontology.org/operation_1835,Residue contact calculation (residue-negative ion), +http://edamontology.org/operation_1836,Residue bump detection, +http://edamontology.org/operation_1837,Residue symmetry contact calculation, +http://edamontology.org/operation_1838,Residue contact calculation (residue-ligand), +http://edamontology.org/operation_1839,Salt bridge calculation, +http://edamontology.org/operation_1841,Rotamer likelihood prediction, +http://edamontology.org/operation_1842,Proline mutation value calculation, +http://edamontology.org/operation_1843,Residue packing validation, +http://edamontology.org/operation_1844,Protein geometry validation, +http://edamontology.org/operation_1845,PDB file sequence retrieval, +http://edamontology.org/operation_1846,HET group detection, +http://edamontology.org/operation_1847,DSSP secondary structure assignment, +http://edamontology.org/operation_1848,Structure formatting, +http://edamontology.org/operation_1850,Protein cysteine and disulfide bond assignment, +http://edamontology.org/operation_1913,Residue validation, +http://edamontology.org/operation_1914,Structure retrieval (water), +http://edamontology.org/operation_2008,siRNA duplex prediction, +http://edamontology.org/operation_2089,Sequence alignment refinement, +http://edamontology.org/operation_2120,Listfile processing, +http://edamontology.org/operation_2121,Sequence file editing, +http://edamontology.org/operation_2122,Sequence alignment file processing, +http://edamontology.org/operation_2123,Small molecule data processing, +http://edamontology.org/operation_2222,Data retrieval (ontology annotation), +http://edamontology.org/operation_2224,Data retrieval (ontology concept), +http://edamontology.org/operation_2233,Representative sequence identification, +http://edamontology.org/operation_2234,Structure file processing, +http://edamontology.org/operation_2237,Data retrieval (sequence profile), +http://edamontology.org/operation_2238,Statistical calculation, +http://edamontology.org/operation_2239,3D-1D scoring matrix generation, +http://edamontology.org/operation_2241,Transmembrane protein visualisation, +http://edamontology.org/operation_2246,Demonstration, +http://edamontology.org/operation_2264,Data retrieval (pathway or network), +http://edamontology.org/operation_2265,Data retrieval (identifier), +http://edamontology.org/operation_2284,Nucleic acid density plotting, +http://edamontology.org/operation_2403,Sequence analysis, +http://edamontology.org/operation_2404,Sequence motif analysis, +http://edamontology.org/operation_2405,Protein interaction data processing, +http://edamontology.org/operation_2406,Protein structure analysis, +http://edamontology.org/operation_2407,Annotation processing, +http://edamontology.org/operation_2408,Sequence feature analysis, +http://edamontology.org/operation_2409,Data handling, +http://edamontology.org/operation_2410,Gene expression analysis, +http://edamontology.org/operation_2411,Structural profile processing, +http://edamontology.org/operation_2412,Data index processing, +http://edamontology.org/operation_2413,Sequence profile processing, +http://edamontology.org/operation_2414,Protein function analysis, +http://edamontology.org/operation_2415,Protein folding analysis, +http://edamontology.org/operation_2416,Protein secondary structure analysis, +http://edamontology.org/operation_2417,Physicochemical property data processing, +http://edamontology.org/operation_2419,Primer and probe design, +http://edamontology.org/operation_2420,Operation (typed), +http://edamontology.org/operation_2421,Database search, +http://edamontology.org/operation_2422,Data retrieval, +http://edamontology.org/operation_2423,Prediction and recognition, +http://edamontology.org/operation_2424,Comparison, +http://edamontology.org/operation_2425,Optimisation and refinement, +http://edamontology.org/operation_2426,Modelling and simulation, +http://edamontology.org/operation_2427,Data handling, +http://edamontology.org/operation_2428,Validation, +http://edamontology.org/operation_2429,Mapping, +http://edamontology.org/operation_2430,Design, +http://edamontology.org/operation_2432,Microarray data processing, +http://edamontology.org/operation_2433,Codon usage table processing, +http://edamontology.org/operation_2434,Data retrieval (codon usage table), +http://edamontology.org/operation_2435,Gene expression profile processing, +http://edamontology.org/operation_2436,Gene-set enrichment analysis, +http://edamontology.org/operation_2437,Gene regulatory network prediction, +http://edamontology.org/operation_2438,Pathway or network processing, +http://edamontology.org/operation_2439,RNA secondary structure analysis, +http://edamontology.org/operation_2440,Structure processing (RNA), +http://edamontology.org/operation_2441,RNA structure prediction, +http://edamontology.org/operation_2442,DNA structure prediction, +http://edamontology.org/operation_2443,Phylogenetic tree processing, +http://edamontology.org/operation_2444,Protein secondary structure processing, +http://edamontology.org/operation_2445,Protein interaction network processing, +http://edamontology.org/operation_2446,Sequence processing, +http://edamontology.org/operation_2447,Sequence processing (protein), +http://edamontology.org/operation_2448,Sequence processing (nucleic acid), +http://edamontology.org/operation_2451,Sequence comparison, +http://edamontology.org/operation_2452,Sequence cluster processing, +http://edamontology.org/operation_2453,Feature table processing, +http://edamontology.org/operation_2454,Gene prediction, +http://edamontology.org/operation_2456,GPCR classification, +http://edamontology.org/operation_2457,GPCR coupling selectivity prediction, +http://edamontology.org/operation_2459,Structure processing (protein), +http://edamontology.org/operation_2460,Protein atom surface calculation, +http://edamontology.org/operation_2461,Protein residue surface calculation, +http://edamontology.org/operation_2462,Protein surface calculation, +http://edamontology.org/operation_2463,Sequence alignment processing, +http://edamontology.org/operation_2464,Protein-protein binding site prediction, +http://edamontology.org/operation_2465,Structure processing, +http://edamontology.org/operation_2466,Map annotation, +http://edamontology.org/operation_2467,Data retrieval (protein annotation), +http://edamontology.org/operation_2468,Data retrieval (phylogenetic tree), +http://edamontology.org/operation_2469,Data retrieval (protein interaction annotation), +http://edamontology.org/operation_2470,Data retrieval (protein family annotation), +http://edamontology.org/operation_2471,Data retrieval (RNA family annotation), +http://edamontology.org/operation_2472,Data retrieval (gene annotation), +http://edamontology.org/operation_2473,Data retrieval (genotype and phenotype annotation), +http://edamontology.org/operation_2474,Protein architecture comparison, +http://edamontology.org/operation_2475,Protein architecture recognition, +http://edamontology.org/operation_2476,Molecular dynamics, +http://edamontology.org/operation_2478,Nucleic acid sequence analysis, +http://edamontology.org/operation_2479,Protein sequence analysis, +http://edamontology.org/operation_2480,Structure analysis, +http://edamontology.org/operation_2481,Nucleic acid structure analysis, +http://edamontology.org/operation_2482,Secondary structure processing, +http://edamontology.org/operation_2483,Structure comparison, +http://edamontology.org/operation_2485,Helical wheel drawing, +http://edamontology.org/operation_2486,Topology diagram drawing, +http://edamontology.org/operation_2487,Protein structure comparison, +http://edamontology.org/operation_2488,Protein secondary structure comparison, +http://edamontology.org/operation_2489,Subcellular localisation prediction, +http://edamontology.org/operation_2490,Residue contact calculation (residue-residue), +http://edamontology.org/operation_2491,Hydrogen bond calculation (inter-residue), +http://edamontology.org/operation_2492,Protein interaction prediction, +http://edamontology.org/operation_2493,Codon usage data processing, +http://edamontology.org/operation_2495,Expression analysis, +http://edamontology.org/operation_2496,Gene regulatory network processing, +http://edamontology.org/operation_2497,Pathway or network analysis, +http://edamontology.org/operation_2498,Sequencing-based expression profile data analysis, +http://edamontology.org/operation_2499,Splicing analysis, +http://edamontology.org/operation_2500,Microarray raw data analysis, +http://edamontology.org/operation_2501,Nucleic acid analysis, +http://edamontology.org/operation_2502,Protein analysis, +http://edamontology.org/operation_2503,Sequence data processing, +http://edamontology.org/operation_2504,Structural data processing, +http://edamontology.org/operation_2505,Text processing, +http://edamontology.org/operation_2506,Protein sequence alignment analysis, +http://edamontology.org/operation_2507,Nucleic acid sequence alignment analysis, +http://edamontology.org/operation_2508,Nucleic acid sequence comparison, +http://edamontology.org/operation_2509,Protein sequence comparison, +http://edamontology.org/operation_2510,DNA back-translation, +http://edamontology.org/operation_2511,Sequence editing (nucleic acid), +http://edamontology.org/operation_2512,Sequence editing (protein), +http://edamontology.org/operation_2513,Sequence generation (nucleic acid), +http://edamontology.org/operation_2514,Sequence generation (protein), +http://edamontology.org/operation_2515,Nucleic acid sequence visualisation, +http://edamontology.org/operation_2516,Protein sequence visualisation, +http://edamontology.org/operation_2518,Nucleic acid structure comparison, +http://edamontology.org/operation_2519,Structure processing (nucleic acid), +http://edamontology.org/operation_2520,DNA mapping, +http://edamontology.org/operation_2521,Map data processing, +http://edamontology.org/operation_2574,Protein hydropathy calculation, +http://edamontology.org/operation_2575,Binding site prediction, +http://edamontology.org/operation_2844,Structure clustering, +http://edamontology.org/operation_2871,Sequence tagged site (STS) mapping, +http://edamontology.org/operation_2928,Alignment, +http://edamontology.org/operation_2929,Protein fragment weight comparison, +http://edamontology.org/operation_2930,Protein property comparison, +http://edamontology.org/operation_2931,Secondary structure comparison, +http://edamontology.org/operation_2932,Hopp and Woods plotting, +http://edamontology.org/operation_2934,Cluster textual view generation, +http://edamontology.org/operation_2935,Clustering profile plotting, +http://edamontology.org/operation_2936,Dendrograph plotting, +http://edamontology.org/operation_2937,Proximity map plotting, +http://edamontology.org/operation_2938,Dendrogram visualisation, +http://edamontology.org/operation_2939,Principal component visualisation, +http://edamontology.org/operation_2940,Scatter plot plotting, +http://edamontology.org/operation_2941,Whole microarray graph plotting, +http://edamontology.org/operation_2942,Treemap visualisation, +http://edamontology.org/operation_2943,Box-Whisker plot plotting, +http://edamontology.org/operation_2944,Physical mapping, +http://edamontology.org/operation_2945,Analysis, +http://edamontology.org/operation_2946,Alignment analysis, +http://edamontology.org/operation_2947,Article analysis, +http://edamontology.org/operation_2948,Molecular interaction analysis, +http://edamontology.org/operation_2949,Protein-protein interaction analysis, +http://edamontology.org/operation_2950,Residue distance calculation, +http://edamontology.org/operation_2951,Alignment processing, +http://edamontology.org/operation_2952,Structure alignment processing, +http://edamontology.org/operation_2962,Codon usage bias calculation, +http://edamontology.org/operation_2963,Codon usage bias plotting, +http://edamontology.org/operation_2964,Codon usage fraction calculation, +http://edamontology.org/operation_2990,Classification, +http://edamontology.org/operation_2993,Molecular interaction data processing, +http://edamontology.org/operation_2995,Sequence classification, +http://edamontology.org/operation_2996,Structure classification, +http://edamontology.org/operation_2997,Protein comparison, +http://edamontology.org/operation_2998,Nucleic acid comparison, +http://edamontology.org/operation_3023,Prediction and recognition (protein), +http://edamontology.org/operation_3024,Prediction and recognition (nucleic acid), +http://edamontology.org/operation_3080,Structure editing, +http://edamontology.org/operation_3081,Sequence alignment editing, +http://edamontology.org/operation_3083,Pathway or network visualisation, +http://edamontology.org/operation_3084,Protein function prediction (from sequence), +http://edamontology.org/operation_3087,Protein sequence feature detection, +http://edamontology.org/operation_3088,Protein property calculation (from sequence), +http://edamontology.org/operation_3090,Protein feature prediction (from structure), +http://edamontology.org/operation_3092,Protein feature detection, +http://edamontology.org/operation_3093,Database search (by sequence), +http://edamontology.org/operation_3094,Protein interaction network prediction, +http://edamontology.org/operation_3095,Nucleic acid design, +http://edamontology.org/operation_3096,Editing, +http://edamontology.org/operation_3180,Sequence assembly validation, +http://edamontology.org/operation_3182,Genome alignment, +http://edamontology.org/operation_3183,Localised reassembly, +http://edamontology.org/operation_3184,Sequence assembly visualisation, +http://edamontology.org/operation_3185,Base-calling, +http://edamontology.org/operation_3186,Bisulfite mapping, +http://edamontology.org/operation_3187,Sequence contamination filtering, +http://edamontology.org/operation_3189,Trim ends, +http://edamontology.org/operation_3190,Trim vector, +http://edamontology.org/operation_3191,Trim to reference, +http://edamontology.org/operation_3192,Sequence trimming, +http://edamontology.org/operation_3194,Genome feature comparison, +http://edamontology.org/operation_3195,Sequencing error detection, +http://edamontology.org/operation_3196,Genotyping, +http://edamontology.org/operation_3197,Genetic variation analysis, +http://edamontology.org/operation_3198,Read mapping, +http://edamontology.org/operation_3199,Split read mapping, +http://edamontology.org/operation_3200,DNA barcoding, +http://edamontology.org/operation_3201,SNP calling, +http://edamontology.org/operation_3202,Polymorphism detection, +http://edamontology.org/operation_3203,Chromatogram visualisation, +http://edamontology.org/operation_3204,Methylation analysis, +http://edamontology.org/operation_3205,Methylation calling, +http://edamontology.org/operation_3206,Whole genome methylation analysis, +http://edamontology.org/operation_3207,Gene methylation analysis, +http://edamontology.org/operation_3208,Genome visualisation, +http://edamontology.org/operation_3209,Genome comparison, +http://edamontology.org/operation_3211,Genome indexing, +http://edamontology.org/operation_3212,Genome indexing (Burrows-Wheeler), +http://edamontology.org/operation_3213,Genome indexing (suffix arrays), +http://edamontology.org/operation_3214,Spectral analysis, +http://edamontology.org/operation_3215,Peak detection, +http://edamontology.org/operation_3216,Scaffolding, +http://edamontology.org/operation_3217,Scaffold gap completion, +http://edamontology.org/operation_3218,Sequencing quality control, +http://edamontology.org/operation_3219,Read pre-processing, +http://edamontology.org/operation_3221,Species frequency estimation, +http://edamontology.org/operation_3222,Peak calling, +http://edamontology.org/operation_3223,Differential gene expression profiling, +http://edamontology.org/operation_3224,Gene set testing, +http://edamontology.org/operation_3225,Variant classification, +http://edamontology.org/operation_3226,Variant prioritisation, +http://edamontology.org/operation_3227,Variant calling, +http://edamontology.org/operation_3228,Structural variation detection, +http://edamontology.org/operation_3229,Exome assembly, +http://edamontology.org/operation_3230,Read depth analysis, +http://edamontology.org/operation_3232,Gene expression QTL analysis, +http://edamontology.org/operation_3233,Copy number estimation, +http://edamontology.org/operation_3237,Primer removal, +http://edamontology.org/operation_3258,Transcriptome assembly, +http://edamontology.org/operation_3259,Transcriptome assembly (de novo), +http://edamontology.org/operation_3260,Transcriptome assembly (mapping), +http://edamontology.org/operation_3267,Sequence coordinate conversion, +http://edamontology.org/operation_3278,Document similarity calculation, +http://edamontology.org/operation_3279,Document clustering, +http://edamontology.org/operation_3280,Named-entity and concept recognition, +http://edamontology.org/operation_3282,ID mapping, +http://edamontology.org/operation_3283,Anonymisation, +http://edamontology.org/operation_3289,ID retrieval, +http://edamontology.org/operation_3348,Sequence checksum generation, +http://edamontology.org/operation_3349,Bibliography generation, +http://edamontology.org/operation_3350,Protein quaternary structure prediction, +http://edamontology.org/operation_3351,Molecular surface analysis, +http://edamontology.org/operation_3352,Ontology comparison, +http://edamontology.org/operation_3353,Ontology comparison, +http://edamontology.org/operation_3357,Format detection, +http://edamontology.org/operation_3359,Splitting, +http://edamontology.org/operation_3429,Generation, +http://edamontology.org/operation_3430,Nucleic acid sequence feature detection, +http://edamontology.org/operation_3431,Deposition, +http://edamontology.org/operation_3432,Clustering, +http://edamontology.org/operation_3433,Assembly, +http://edamontology.org/operation_3434,Conversion, +http://edamontology.org/operation_3435,Standardisation and normalisation, +http://edamontology.org/operation_3436,Aggregation, +http://edamontology.org/operation_3437,Article comparison, +http://edamontology.org/operation_3438,Calculation, +http://edamontology.org/operation_3439,Pathway or network prediction, +http://edamontology.org/operation_3440,Genome assembly, +http://edamontology.org/operation_3441,Plotting, +http://edamontology.org/operation_3443,Image analysis, +http://edamontology.org/operation_3445,Diffraction data analysis, +http://edamontology.org/operation_3446,Cell migration analysis, +http://edamontology.org/operation_3447,Diffraction data reduction, +http://edamontology.org/operation_3450,Neurite measurement, +http://edamontology.org/operation_3453,Diffraction data integration, +http://edamontology.org/operation_3454,Phasing, +http://edamontology.org/operation_3455,Molecular replacement, +http://edamontology.org/operation_3456,Rigid body refinement, +http://edamontology.org/operation_3457,Single particle analysis, +http://edamontology.org/operation_3458,Single particle alignment and classification, +http://edamontology.org/operation_3459,Functional clustering, +http://edamontology.org/operation_3460,Taxonomic classification, +http://edamontology.org/operation_3461,Virulence prediction, +http://edamontology.org/operation_3463,Expression correlation analysis, +http://edamontology.org/operation_3465,Correlation, +http://edamontology.org/operation_3469,RNA structure covariance model generation, +http://edamontology.org/operation_3470,RNA secondary structure prediction (shape-based), +http://edamontology.org/operation_3471,Nucleic acid folding prediction (alignment-based), +http://edamontology.org/operation_3472,k-mer counting, +http://edamontology.org/operation_3478,Phylogenetic reconstruction, +http://edamontology.org/operation_3480,Probabilistic data generation, +http://edamontology.org/operation_3481,Probabilistic sequence generation, +http://edamontology.org/operation_3482,Antimicrobial resistance prediction, +http://edamontology.org/operation_3501,Enrichment analysis, +http://edamontology.org/operation_3502,Chemical similarity enrichment, +http://edamontology.org/operation_3503,Incident curve plotting, +http://edamontology.org/operation_3504,Variant pattern analysis, +http://edamontology.org/operation_3545,Mathematical modelling, +http://edamontology.org/operation_3552,Microscope image visualisation, +http://edamontology.org/operation_3553,Image annotation, +http://edamontology.org/operation_3557,Imputation, +http://edamontology.org/operation_3559,Ontology visualisation, +http://edamontology.org/operation_3560,Maximum occurence analysis, +http://edamontology.org/operation_3561,Database comparison, +http://edamontology.org/operation_3562,Network simulation, +http://edamontology.org/operation_3563,RNA-seq read count analysis, +http://edamontology.org/operation_3564,Chemical redundancy removal, +http://edamontology.org/operation_3565,RNA-seq time series data analysis, +http://edamontology.org/operation_3566,Simulated gene expression data generation, +http://edamontology.org/operation_3625,Relation extraction, +http://edamontology.org/operation_3627,Mass spectra calibration, +http://edamontology.org/operation_3628,Chromatographic alignment, +http://edamontology.org/operation_3629,Deisotoping, +http://edamontology.org/operation_3630,Protein quantification, +http://edamontology.org/operation_3631,Peptide identification, +http://edamontology.org/operation_3632,Isotopic distributions calculation, +http://edamontology.org/operation_3633,Retention time prediction, +http://edamontology.org/operation_3634,Label-free quantification, +http://edamontology.org/operation_3635,Labeled quantification, +http://edamontology.org/operation_3636,MRM/SRM, +http://edamontology.org/operation_3637,Spectral counting, +http://edamontology.org/operation_3638,SILAC, +http://edamontology.org/operation_3639,iTRAQ, +http://edamontology.org/operation_3640,18O labeling, +http://edamontology.org/operation_3641,TMT-tag, +http://edamontology.org/operation_3642,Dimethyl, +http://edamontology.org/operation_3643,Tag-based peptide identification, +http://edamontology.org/operation_3644,de Novo sequencing, +http://edamontology.org/operation_3645,PTM identification, +http://edamontology.org/operation_3646,Peptide database search, +http://edamontology.org/operation_3647,Blind peptide database search, +http://edamontology.org/operation_3648,Validation of peptide-spectrum matches, +http://edamontology.org/operation_3649,Target-Decoy, +http://edamontology.org/operation_3658,Statistical inference, +http://edamontology.org/operation_3659,Regression analysis, +http://edamontology.org/operation_3660,Metabolic network modelling, +http://edamontology.org/operation_3661,SNP annotation, +http://edamontology.org/operation_3662,Ab-initio gene prediction, +http://edamontology.org/operation_3663,Homology-based gene prediction, +http://edamontology.org/operation_3664,Statistical modelling, +http://edamontology.org/operation_3666,Molecular surface comparison, +http://edamontology.org/operation_3672,Gene functional annotation, +http://edamontology.org/operation_3675,Variant filtering, +http://edamontology.org/operation_3677,Differential binding analysis, +http://edamontology.org/operation_3680,RNA-Seq analysis, +http://edamontology.org/operation_3694,Mass spectrum visualisation, +http://edamontology.org/operation_3695,Filtering, +http://edamontology.org/operation_3703,Reference identification, +http://edamontology.org/operation_3704,Ion counting, +http://edamontology.org/operation_3705,Isotope-coded protein label, +http://edamontology.org/operation_3715,Metabolic labeling, +http://edamontology.org/operation_3730,Cross-assembly, +http://edamontology.org/operation_3731,Sample comparison, +http://edamontology.org/operation_3741,Differential protein expression profiling, +http://edamontology.org/operation_3742,Differential gene expression analysis, +http://edamontology.org/operation_3744,Multiple sample visualisation, +http://edamontology.org/operation_3745,Ancestral reconstruction, +http://edamontology.org/operation_3755,PTM localisation, +http://edamontology.org/operation_3760,Service management, +http://edamontology.org/operation_3761,Service discovery, +http://edamontology.org/operation_3762,Service composition, +http://edamontology.org/operation_3763,Service invocation, +http://edamontology.org/operation_3766,Weighted correlation network analysis, +http://edamontology.org/operation_3767,Protein identification, +http://edamontology.org/operation_3778,Text annotation, +http://edamontology.org/operation_3791,Collapsing methods, +http://edamontology.org/operation_3792,miRNA expression analysis, +http://edamontology.org/operation_3793,Read summarisation, +http://edamontology.org/operation_3795,In vitro selection, +http://edamontology.org/operation_3797,Rarefaction, +http://edamontology.org/operation_3798,Read binning, +http://edamontology.org/operation_3799,Quantification, +http://edamontology.org/operation_3800,RNA-Seq quantification, +http://edamontology.org/operation_3801,Spectral library search, +http://edamontology.org/operation_3802,Sorting, +http://edamontology.org/operation_3803,Natural product identification, +http://edamontology.org/operation_3809,DMR identification, +http://edamontology.org/operation_3840,Multilocus sequence typing, +http://edamontology.org/operation_3860,Spectrum calculation, +http://edamontology.org/operation_3890,Trajectory visualization, +http://edamontology.org/operation_3891,Essential dynamics, +http://edamontology.org/operation_3893,Forcefield parameterisation, +http://edamontology.org/operation_3894,DNA profiling, +http://edamontology.org/operation_3896,Active site prediction, +http://edamontology.org/operation_3897,Ligand-binding site prediction, +http://edamontology.org/operation_3898,Metal-binding site prediction, +http://edamontology.org/operation_3899,Protein-protein docking, +http://edamontology.org/operation_3900,DNA-binding protein prediction, +http://edamontology.org/operation_3901,RNA-binding protein prediction, +http://edamontology.org/operation_3902,RNA binding site prediction, +http://edamontology.org/operation_3903,DNA binding site prediction, +http://edamontology.org/operation_3904,Protein disorder prediction, +http://edamontology.org/operation_3907,Information extraction, +http://edamontology.org/operation_3908,Information retrieval, +http://edamontology.org/operation_3918,Genome analysis, +http://edamontology.org/operation_3919,Methylation calling, +http://edamontology.org/operation_3920,DNA testing, +http://edamontology.org/operation_3921,Sequence read processing, +http://edamontology.org/operation_3923,Genome resequencing, +http://edamontology.org/operation_3925,Network visualisation, +http://edamontology.org/operation_3926,Pathway visualisation, +http://edamontology.org/operation_3927,Network analysis, +http://edamontology.org/operation_3928,Pathway analysis, +http://edamontology.org/operation_3929,Metabolic pathway prediction, +http://edamontology.org/operation_3931,Chemometrics, +http://edamontology.org/operation_3933,Demultiplexing, +http://edamontology.org/operation_3935,Dimensionality reduction, +http://edamontology.org/operation_3936,Feature selection, +http://edamontology.org/operation_3937,Feature extraction, +http://edamontology.org/operation_3938,Virtual screening, +http://edamontology.org/operation_3939,Metabolic engineering, +http://edamontology.org/operation_3942,Tree dating, +http://edamontology.org/operation_3946,Ecological modelling, +http://edamontology.org/operation_3947,Phylogenetic tree reconciliation, +http://edamontology.org/operation_3950,Selection detection, +http://edamontology.org/operation_3960,Principal component analysis, +http://edamontology.org/operation_3961,Copy number variation detection, +http://edamontology.org/operation_3962,Deletion detection, +http://edamontology.org/operation_3963,Duplication detection, +http://edamontology.org/operation_3964,Complex CNV detection, +http://edamontology.org/operation_3965,Amplification detection, +http://edamontology.org/operation_3968,Adhesin prediction, +http://edamontology.org/operation_4008,Protein design, +http://edamontology.org/operation_4009,Small molecule design, +http://edamontology.org/topic_0003,Topic, +http://edamontology.org/topic_0077,Nucleic acids, +http://edamontology.org/topic_0078,Proteins, +http://edamontology.org/topic_0079,Metabolites, +http://edamontology.org/topic_0080,Sequence analysis, +http://edamontology.org/topic_0081,Structure analysis, +http://edamontology.org/topic_0082,Structure prediction, +http://edamontology.org/topic_0083,Alignment, +http://edamontology.org/topic_0084,Phylogeny, +http://edamontology.org/topic_0085,Functional genomics, +http://edamontology.org/topic_0089,Ontology and terminology, +http://edamontology.org/topic_0090,Information retrieval, +http://edamontology.org/topic_0091,Bioinformatics, +http://edamontology.org/topic_0092,Data visualisation, +http://edamontology.org/topic_0094,Nucleic acid thermodynamics, +http://edamontology.org/topic_0097,Nucleic acid structure analysis, +http://edamontology.org/topic_0099,RNA, +http://edamontology.org/topic_0100,Nucleic acid restriction, +http://edamontology.org/topic_0102,Mapping, +http://edamontology.org/topic_0107,Genetic codes and codon usage, +http://edamontology.org/topic_0108,Protein expression, +http://edamontology.org/topic_0109,Gene finding, +http://edamontology.org/topic_0110,Transcription, +http://edamontology.org/topic_0111,Promoters, +http://edamontology.org/topic_0112,Nucleic acid folding, +http://edamontology.org/topic_0114,Gene structure, +http://edamontology.org/topic_0121,Proteomics, +http://edamontology.org/topic_0122,Structural genomics, +http://edamontology.org/topic_0123,Protein properties, +http://edamontology.org/topic_0128,Protein interactions, +http://edamontology.org/topic_0130,"Protein folding, stability and design", +http://edamontology.org/topic_0133,Two-dimensional gel electrophoresis, +http://edamontology.org/topic_0134,Mass spectrometry, +http://edamontology.org/topic_0135,Protein microarrays, +http://edamontology.org/topic_0137,Protein hydropathy, +http://edamontology.org/topic_0140,Protein targeting and localisation, +http://edamontology.org/topic_0141,Protein cleavage sites and proteolysis, +http://edamontology.org/topic_0143,Protein structure comparison, +http://edamontology.org/topic_0144,Protein residue interactions, +http://edamontology.org/topic_0147,Protein-protein interactions, +http://edamontology.org/topic_0148,Protein-ligand interactions, +http://edamontology.org/topic_0149,Protein-nucleic acid interactions, +http://edamontology.org/topic_0150,Protein design, +http://edamontology.org/topic_0151,G protein-coupled receptors (GPCR), +http://edamontology.org/topic_0152,Carbohydrates, +http://edamontology.org/topic_0153,Lipids, +http://edamontology.org/topic_0154,Small molecules, +http://edamontology.org/topic_0156,Sequence editing, +http://edamontology.org/topic_0157,"Sequence composition, complexity and repeats", +http://edamontology.org/topic_0158,Sequence motifs, +http://edamontology.org/topic_0159,Sequence comparison, +http://edamontology.org/topic_0160,"Sequence sites, features and motifs", +http://edamontology.org/topic_0163,Sequence database search, +http://edamontology.org/topic_0164,Sequence clustering, +http://edamontology.org/topic_0166,Protein structural motifs and surfaces, +http://edamontology.org/topic_0167,Structural (3D) profiles, +http://edamontology.org/topic_0172,Protein structure prediction, +http://edamontology.org/topic_0173,Nucleic acid structure prediction, +http://edamontology.org/topic_0174,Ab initio structure prediction, +http://edamontology.org/topic_0175,Homology modelling, +http://edamontology.org/topic_0176,Molecular dynamics, +http://edamontology.org/topic_0177,Molecular docking, +http://edamontology.org/topic_0178,Protein secondary structure prediction, +http://edamontology.org/topic_0179,Protein tertiary structure prediction, +http://edamontology.org/topic_0180,Protein fold recognition, +http://edamontology.org/topic_0182,Sequence alignment, +http://edamontology.org/topic_0183,Structure alignment, +http://edamontology.org/topic_0184,Threading, +http://edamontology.org/topic_0188,Sequence profiles and HMMs, +http://edamontology.org/topic_0191,Phylogeny reconstruction, +http://edamontology.org/topic_0194,Phylogenomics, +http://edamontology.org/topic_0195,Virtual PCR, +http://edamontology.org/topic_0196,Sequence assembly, +http://edamontology.org/topic_0199,Genetic variation, +http://edamontology.org/topic_0200,Microarrays, +http://edamontology.org/topic_0202,Pharmacology, +http://edamontology.org/topic_0203,Gene expression, +http://edamontology.org/topic_0204,Gene regulation, +http://edamontology.org/topic_0208,Pharmacogenomics, +http://edamontology.org/topic_0209,Medicinal chemistry, +http://edamontology.org/topic_0210,Fish, +http://edamontology.org/topic_0211,Flies, +http://edamontology.org/topic_0213,Mice or rats, +http://edamontology.org/topic_0215,Worms, +http://edamontology.org/topic_0217,Literature analysis, +http://edamontology.org/topic_0218,Natural language processing, +http://edamontology.org/topic_0219,"Data submission, annotation and curation", +http://edamontology.org/topic_0220,"Document, record and content management", +http://edamontology.org/topic_0221,Sequence annotation, +http://edamontology.org/topic_0222,Genome annotation, +http://edamontology.org/topic_0593,NMR, +http://edamontology.org/topic_0594,Sequence classification, +http://edamontology.org/topic_0595,Protein classification, +http://edamontology.org/topic_0598,Sequence motif or profile, +http://edamontology.org/topic_0601,Protein modifications, +http://edamontology.org/topic_0602,"Molecular interactions, pathways and networks", +http://edamontology.org/topic_0605,Informatics, +http://edamontology.org/topic_0606,Literature data resources, +http://edamontology.org/topic_0607,Laboratory information management, +http://edamontology.org/topic_0608,Cell and tissue culture, +http://edamontology.org/topic_0610,Ecology, +http://edamontology.org/topic_0611,Electron microscopy, +http://edamontology.org/topic_0612,Cell cycle, +http://edamontology.org/topic_0613,Peptides and amino acids, +http://edamontology.org/topic_0616,Organelles, +http://edamontology.org/topic_0617,Ribosomes, +http://edamontology.org/topic_0618,Scents, +http://edamontology.org/topic_0620,Drugs and target structures, +http://edamontology.org/topic_0621,Model organisms, +http://edamontology.org/topic_0622,Genomics, +http://edamontology.org/topic_0623,Gene and protein families, +http://edamontology.org/topic_0624,Chromosomes, +http://edamontology.org/topic_0625,Genotype and phenotype, +http://edamontology.org/topic_0629,Gene expression and microarray, +http://edamontology.org/topic_0632,Probes and primers, +http://edamontology.org/topic_0634,Pathology, +http://edamontology.org/topic_0635,Specific protein resources, +http://edamontology.org/topic_0637,Taxonomy, +http://edamontology.org/topic_0639,Protein sequence analysis, +http://edamontology.org/topic_0640,Nucleic acid sequence analysis, +http://edamontology.org/topic_0641,Repeat sequences, +http://edamontology.org/topic_0642,Low complexity sequences, +http://edamontology.org/topic_0644,Proteome, +http://edamontology.org/topic_0654,DNA, +http://edamontology.org/topic_0655,Coding RNA, +http://edamontology.org/topic_0659,"Functional, regulatory and non-coding RNA", +http://edamontology.org/topic_0660,rRNA, +http://edamontology.org/topic_0663,tRNA, +http://edamontology.org/topic_0694,Protein secondary structure, +http://edamontology.org/topic_0697,RNA structure, +http://edamontology.org/topic_0698,Protein tertiary structure, +http://edamontology.org/topic_0722,Nucleic acid classification, +http://edamontology.org/topic_0724,Protein families, +http://edamontology.org/topic_0736,Protein folds and structural domains, +http://edamontology.org/topic_0740,Nucleic acid sequence alignment, +http://edamontology.org/topic_0741,Protein sequence alignment, +http://edamontology.org/topic_0747,Nucleic acid sites and features, +http://edamontology.org/topic_0748,Protein sites and features, +http://edamontology.org/topic_0749,Transcription factors and regulatory sites, +http://edamontology.org/topic_0751,Phosphorylation sites, +http://edamontology.org/topic_0753,Metabolic pathways, +http://edamontology.org/topic_0754,Signaling pathways, +http://edamontology.org/topic_0767,Protein and peptide identification, +http://edamontology.org/topic_0769,Workflows, +http://edamontology.org/topic_0770,Data types and objects, +http://edamontology.org/topic_0771,Theoretical biology, +http://edamontology.org/topic_0779,Mitochondria, +http://edamontology.org/topic_0780,Plant biology, +http://edamontology.org/topic_0781,Virology, +http://edamontology.org/topic_0782,Fungi, +http://edamontology.org/topic_0783,Pathogens, +http://edamontology.org/topic_0786,Arabidopsis, +http://edamontology.org/topic_0787,Rice, +http://edamontology.org/topic_0796,Genetic mapping and linkage, +http://edamontology.org/topic_0797,Comparative genomics, +http://edamontology.org/topic_0798,Mobile genetic elements, +http://edamontology.org/topic_0803,Human disease, +http://edamontology.org/topic_0804,Immunology, +http://edamontology.org/topic_0820,Membrane and lipoproteins, +http://edamontology.org/topic_0821,Enzymes, +http://edamontology.org/topic_0922,Primers, +http://edamontology.org/topic_1302,PolyA signal or sites, +http://edamontology.org/topic_1304,CpG island and isochores, +http://edamontology.org/topic_1305,Restriction sites, +http://edamontology.org/topic_1307,Splice sites, +http://edamontology.org/topic_1308,Matrix/scaffold attachment sites, +http://edamontology.org/topic_1311,Operon, +http://edamontology.org/topic_1312,Promoters, +http://edamontology.org/topic_1317,Structural biology, +http://edamontology.org/topic_1456,Protein membrane regions, +http://edamontology.org/topic_1770,Structure comparison, +http://edamontology.org/topic_1775,Function analysis, +http://edamontology.org/topic_1811,Prokaryotes and Archaea, +http://edamontology.org/topic_2225,Protein databases, +http://edamontology.org/topic_2226,Structure determination, +http://edamontology.org/topic_2229,Cell biology, +http://edamontology.org/topic_2230,Classification, +http://edamontology.org/topic_2232,Lipoproteins, +http://edamontology.org/topic_2257,Phylogeny visualisation, +http://edamontology.org/topic_2258,Cheminformatics, +http://edamontology.org/topic_2259,Systems biology, +http://edamontology.org/topic_2269,Statistics and probability, +http://edamontology.org/topic_2271,Structure database search, +http://edamontology.org/topic_2275,Molecular modelling, +http://edamontology.org/topic_2276,Protein function prediction, +http://edamontology.org/topic_2277,SNP, +http://edamontology.org/topic_2278,Transmembrane protein prediction, +http://edamontology.org/topic_2280,Nucleic acid structure comparison, +http://edamontology.org/topic_2397,Exons, +http://edamontology.org/topic_2399,Gene transcription, +http://edamontology.org/topic_2533,DNA mutation, +http://edamontology.org/topic_2640,Oncology, +http://edamontology.org/topic_2661,Toxins and targets, +http://edamontology.org/topic_2754,Introns, +http://edamontology.org/topic_2807,Tool topic, +http://edamontology.org/topic_2809,Study topic, +http://edamontology.org/topic_2811,Nomenclature, +http://edamontology.org/topic_2813,Disease genes and proteins, +http://edamontology.org/topic_2814,Protein structure analysis, +http://edamontology.org/topic_2815,Human biology, +http://edamontology.org/topic_2816,Gene resources, +http://edamontology.org/topic_2817,Yeast, +http://edamontology.org/topic_2818,Eukaryotes, +http://edamontology.org/topic_2819,Invertebrates, +http://edamontology.org/topic_2820,Vertebrates, +http://edamontology.org/topic_2821,Unicellular eukaryotes, +http://edamontology.org/topic_2826,Protein structure alignment, +http://edamontology.org/topic_2828,X-ray diffraction, +http://edamontology.org/topic_2829,"Ontologies, nomenclature and classification", +http://edamontology.org/topic_2830,Immunoproteins and antigens, +http://edamontology.org/topic_2839,Molecules, +http://edamontology.org/topic_2840,Toxicology, +http://edamontology.org/topic_2842,High-throughput sequencing, +http://edamontology.org/topic_2846,Gene regulatory networks, +http://edamontology.org/topic_2847,Disease (specific), +http://edamontology.org/topic_2867,VNTR, +http://edamontology.org/topic_2868,Microsatellites, +http://edamontology.org/topic_2869,RFLP, +http://edamontology.org/topic_2885,DNA polymorphism, +http://edamontology.org/topic_2953,Nucleic acid design, +http://edamontology.org/topic_3032,Primer or probe design, +http://edamontology.org/topic_3038,Structure databases, +http://edamontology.org/topic_3039,Nucleic acid structure, +http://edamontology.org/topic_3041,Sequence databases, +http://edamontology.org/topic_3042,Nucleic acid sequences, +http://edamontology.org/topic_3043,Protein sequences, +http://edamontology.org/topic_3044,Protein interaction networks, +http://edamontology.org/topic_3047,Molecular biology, +http://edamontology.org/topic_3048,Mammals, +http://edamontology.org/topic_3050,Biodiversity, +http://edamontology.org/topic_3052,Sequence clusters and classification, +http://edamontology.org/topic_3053,Genetics, +http://edamontology.org/topic_3055,Quantitative genetics, +http://edamontology.org/topic_3056,Population genetics, +http://edamontology.org/topic_3060,Regulatory RNA, +http://edamontology.org/topic_3061,Documentation and help, +http://edamontology.org/topic_3062,Genetic organisation, +http://edamontology.org/topic_3063,Medical informatics, +http://edamontology.org/topic_3064,Developmental biology, +http://edamontology.org/topic_3065,Embryology, +http://edamontology.org/topic_3067,Anatomy, +http://edamontology.org/topic_3068,Literature and language, +http://edamontology.org/topic_3070,Biology, +http://edamontology.org/topic_3071,Biological databases, +http://edamontology.org/topic_3072,Sequence feature detection, +http://edamontology.org/topic_3073,Nucleic acid feature detection, +http://edamontology.org/topic_3074,Protein feature detection, +http://edamontology.org/topic_3075,Biological system modelling, +http://edamontology.org/topic_3077,Data acquisition, +http://edamontology.org/topic_3078,Genes and proteins resources, +http://edamontology.org/topic_3118,Protein topological domains, +http://edamontology.org/topic_3120,Protein variants, +http://edamontology.org/topic_3123,Expression signals, +http://edamontology.org/topic_3125,DNA binding sites, +http://edamontology.org/topic_3126,Nucleic acid repeats, +http://edamontology.org/topic_3127,DNA replication and recombination, +http://edamontology.org/topic_3135,Signal or transit peptide, +http://edamontology.org/topic_3139,Sequence tagged sites, +http://edamontology.org/topic_3168,Sequencing, +http://edamontology.org/topic_3169,ChIP-seq, +http://edamontology.org/topic_3170,RNA-Seq, +http://edamontology.org/topic_3171,DNA methylation, +http://edamontology.org/topic_3172,Metabolomics, +http://edamontology.org/topic_3173,Epigenomics, +http://edamontology.org/topic_3174,Metagenomics, +http://edamontology.org/topic_3175,Structural variation, +http://edamontology.org/topic_3176,DNA packaging, +http://edamontology.org/topic_3177,DNA-Seq, +http://edamontology.org/topic_3178,RNA-Seq alignment, +http://edamontology.org/topic_3179,ChIP-on-chip, +http://edamontology.org/topic_3263,Data security, +http://edamontology.org/topic_3277,Sample collections, +http://edamontology.org/topic_3292,Biochemistry, +http://edamontology.org/topic_3293,Phylogenetics, +http://edamontology.org/topic_3295,Epigenetics, +http://edamontology.org/topic_3297,Biotechnology, +http://edamontology.org/topic_3298,Phenomics, +http://edamontology.org/topic_3299,Evolutionary biology, +http://edamontology.org/topic_3300,Physiology, +http://edamontology.org/topic_3301,Microbiology, +http://edamontology.org/topic_3302,Parasitology, +http://edamontology.org/topic_3303,Medicine, +http://edamontology.org/topic_3304,Neurobiology, +http://edamontology.org/topic_3305,Public health and epidemiology, +http://edamontology.org/topic_3306,Biophysics, +http://edamontology.org/topic_3307,Computational biology, +http://edamontology.org/topic_3308,Transcriptomics, +http://edamontology.org/topic_3314,Chemistry, +http://edamontology.org/topic_3315,Mathematics, +http://edamontology.org/topic_3316,Computer science, +http://edamontology.org/topic_3318,Physics, +http://edamontology.org/topic_3320,RNA splicing, +http://edamontology.org/topic_3321,Molecular genetics, +http://edamontology.org/topic_3322,Respiratory medicine, +http://edamontology.org/topic_3323,Metabolic disease, +http://edamontology.org/topic_3324,Infectious disease, +http://edamontology.org/topic_3325,Rare diseases, +http://edamontology.org/topic_3332,Computational chemistry, +http://edamontology.org/topic_3334,Neurology, +http://edamontology.org/topic_3335,Cardiology, +http://edamontology.org/topic_3336,Drug discovery, +http://edamontology.org/topic_3337,Biobank, +http://edamontology.org/topic_3338,Mouse clinic, +http://edamontology.org/topic_3339,Microbial collection, +http://edamontology.org/topic_3340,Cell culture collection, +http://edamontology.org/topic_3341,Clone library, +http://edamontology.org/topic_3342,Translational medicine, +http://edamontology.org/topic_3343,Compound libraries and screening, +http://edamontology.org/topic_3344,Biomedical science, +http://edamontology.org/topic_3345,Data identity and mapping, +http://edamontology.org/topic_3346,Sequence search, +http://edamontology.org/topic_3360,Biomarkers, +http://edamontology.org/topic_3361,Laboratory techniques, +http://edamontology.org/topic_3365,"Data architecture, analysis and design", +http://edamontology.org/topic_3366,Data integration and warehousing, +http://edamontology.org/topic_3368,Biomaterials, +http://edamontology.org/topic_3369,Chemical biology, +http://edamontology.org/topic_3370,Analytical chemistry, +http://edamontology.org/topic_3371,Synthetic chemistry, +http://edamontology.org/topic_3372,Software engineering, +http://edamontology.org/topic_3373,Drug development, +http://edamontology.org/topic_3374,Biotherapeutics, +http://edamontology.org/topic_3375,Drug metabolism, +http://edamontology.org/topic_3376,Medicines research and development, +http://edamontology.org/topic_3377,Safety sciences, +http://edamontology.org/topic_3378,Pharmacovigilance, +http://edamontology.org/topic_3379,Preclinical and clinical studies, +http://edamontology.org/topic_3382,Imaging, +http://edamontology.org/topic_3383,Bioimaging, +http://edamontology.org/topic_3384,Medical imaging, +http://edamontology.org/topic_3385,Light microscopy, +http://edamontology.org/topic_3386,Laboratory animal science, +http://edamontology.org/topic_3387,Marine biology, +http://edamontology.org/topic_3388,Molecular medicine, +http://edamontology.org/topic_3390,Nutritional science, +http://edamontology.org/topic_3391,Omics, +http://edamontology.org/topic_3393,Quality affairs, +http://edamontology.org/topic_3394,Regulatory affairs, +http://edamontology.org/topic_3395,Regenerative medicine, +http://edamontology.org/topic_3396,Systems medicine, +http://edamontology.org/topic_3397,Veterinary medicine, +http://edamontology.org/topic_3398,Bioengineering, +http://edamontology.org/topic_3399,Geriatric medicine, +http://edamontology.org/topic_3400,"Allergy, clinical immunology and immunotherapeutics", +http://edamontology.org/topic_3401,Pain medicine, +http://edamontology.org/topic_3402,Anaesthesiology, +http://edamontology.org/topic_3403,Critical care medicine, +http://edamontology.org/topic_3404,Dermatology, +http://edamontology.org/topic_3405,Dentistry, +http://edamontology.org/topic_3406,"Ear, nose and throat medicine", +http://edamontology.org/topic_3407,Endocrinology and metabolism, +http://edamontology.org/topic_3408,Haematology, +http://edamontology.org/topic_3409,Gastroenterology, +http://edamontology.org/topic_3410,Gender medicine, +http://edamontology.org/topic_3411,Gynaecology and obstetrics, +http://edamontology.org/topic_3412,Hepatic and biliary medicine, +http://edamontology.org/topic_3413,Infectious tropical disease, +http://edamontology.org/topic_3414,Trauma medicine, +http://edamontology.org/topic_3415,Medical toxicology, +http://edamontology.org/topic_3416,Musculoskeletal medicine, +http://edamontology.org/topic_3417,Opthalmology, +http://edamontology.org/topic_3418,Paediatrics, +http://edamontology.org/topic_3419,Psychiatry, +http://edamontology.org/topic_3420,Reproductive health, +http://edamontology.org/topic_3421,Surgery, +http://edamontology.org/topic_3422,Urology and nephrology, +http://edamontology.org/topic_3423,Complementary medicine, +http://edamontology.org/topic_3444,MRI, +http://edamontology.org/topic_3448,Neutron diffraction, +http://edamontology.org/topic_3452,Tomography, +http://edamontology.org/topic_3473,Data mining, +http://edamontology.org/topic_3474,Machine learning, +http://edamontology.org/topic_3489,Database management, +http://edamontology.org/topic_3500,Zoology, +http://edamontology.org/topic_3510,"Protein sites, features and motifs", +http://edamontology.org/topic_3511,"Nucleic acid sites, features and motifs", +http://edamontology.org/topic_3512,Gene transcripts, +http://edamontology.org/topic_3514,Protein-ligand interactions, +http://edamontology.org/topic_3515,Protein-drug interactions, +http://edamontology.org/topic_3516,Genotyping experiment, +http://edamontology.org/topic_3517,GWAS study, +http://edamontology.org/topic_3518,Microarray experiment, +http://edamontology.org/topic_3519,PCR experiment, +http://edamontology.org/topic_3520,Proteomics experiment, +http://edamontology.org/topic_3521,2D PAGE experiment, +http://edamontology.org/topic_3522,Northern blot experiment, +http://edamontology.org/topic_3523,RNAi experiment, +http://edamontology.org/topic_3524,Simulation experiment, +http://edamontology.org/topic_3525,Protein-nucleic acid interactions, +http://edamontology.org/topic_3526,Protein-protein interactions, +http://edamontology.org/topic_3527,Cellular process pathways, +http://edamontology.org/topic_3528,Disease pathways, +http://edamontology.org/topic_3529,Environmental information processing pathways, +http://edamontology.org/topic_3530,Genetic information processing pathways, +http://edamontology.org/topic_3531,Protein super-secondary structure, +http://edamontology.org/topic_3533,Protein active sites, +http://edamontology.org/topic_3534,Protein binding sites, +http://edamontology.org/topic_3535,Protein-nucleic acid binding sites, +http://edamontology.org/topic_3536,Protein cleavage sites, +http://edamontology.org/topic_3537,Protein chemical modifications, +http://edamontology.org/topic_3538,Protein disordered structure, +http://edamontology.org/topic_3539,Protein domains, +http://edamontology.org/topic_3540,Protein key folding sites, +http://edamontology.org/topic_3541,Protein post-translational modifications, +http://edamontology.org/topic_3542,Protein secondary structure, +http://edamontology.org/topic_3543,Protein sequence repeats, +http://edamontology.org/topic_3544,Protein signal peptides, +http://edamontology.org/topic_3569,Applied mathematics, +http://edamontology.org/topic_3570,Pure mathematics, +http://edamontology.org/topic_3571,Data governance, +http://edamontology.org/topic_3572,Data quality management, +http://edamontology.org/topic_3573,Freshwater biology, +http://edamontology.org/topic_3574,Human genetics, +http://edamontology.org/topic_3575,Tropical medicine, +http://edamontology.org/topic_3576,Medical biotechnology, +http://edamontology.org/topic_3577,Personalised medicine, +http://edamontology.org/topic_3656,Immunoprecipitation experiment, +http://edamontology.org/topic_3673,Whole genome sequencing, +http://edamontology.org/topic_3674,Methylated DNA immunoprecipitation, +http://edamontology.org/topic_3676,Exome sequencing, +http://edamontology.org/topic_3678,Experimental design and studies, +http://edamontology.org/topic_3679,Animal study, +http://edamontology.org/topic_3697,Microbial ecology, +http://edamontology.org/topic_3794,RNA immunoprecipitation, +http://edamontology.org/topic_3796,Population genomics, +http://edamontology.org/topic_3810,Agricultural science, +http://edamontology.org/topic_3837,Metagenomic sequencing, +http://edamontology.org/topic_3855,Environmental science, +http://edamontology.org/topic_3892,Biomolecular simulation, +http://edamontology.org/topic_3895,Synthetic biology, +http://edamontology.org/topic_3912,Genetic engineering, +http://edamontology.org/topic_3922,Proteogenomics, +http://edamontology.org/topic_3930,Immunogenetics, +http://edamontology.org/topic_3934,Cytometry, +http://edamontology.org/topic_3940,Chromosome conformation capture, +http://edamontology.org/topic_3941,Metatranscriptomics, +http://edamontology.org/topic_3943,Paleogenomics, +http://edamontology.org/topic_3944,Cladistics, +http://edamontology.org/topic_3945,Molecular evolution, +http://edamontology.org/topic_3948,Immunoinformatics, +http://edamontology.org/topic_3954,Echography, +http://edamontology.org/topic_3955,Fluxomics, +http://edamontology.org/topic_3957,Protein interaction experiment, +http://edamontology.org/topic_3958,Copy number variation, +http://edamontology.org/topic_3959,Cytogenetics, +http://edamontology.org/topic_3966,Vaccinology, +http://edamontology.org/topic_3967,Immunomics, +http://edamontology.org/topic_3974,Epistasis, +http://www.geneontology.org/formats/oboInOwl#ObsoleteClass,Obsolete concept (EDAM), +http://www.w3.org/2002/07/owl#DeprecatedClass,DeprecatedClass diff --git a/nf_core/modules/lint/__init__.py b/nf_core/modules/lint/__init__.py index f2472db0d3..7f01f7f4a2 100644 --- a/nf_core/modules/lint/__init__.py +++ b/nf_core/modules/lint/__init__.py @@ -611,13 +611,21 @@ def _add_edam_ontologies(section, edam_formats, desc): section["ontologies"] = [] log.debug(f"expected ontologies for {desc}: {expected_ontologies}") log.debug(f"current ontologies for {desc}: {current_ontologies}") - for ontology, ext in expected_ontologies: - if ontology not in current_ontologies: + for ontology_url, ext in expected_ontologies: + comment_text = edam_formats[ext][1] + if ontology_url not in current_ontologies: try: - section["ontologies"].append(ruamel.yaml.comments.CommentedMap({"edam": ontology})) - section["ontologies"][-1].yaml_add_eol_comment(f"{edam_formats[ext][1]}", "edam") + cm = ruamel.yaml.comments.CommentedMap() + cm["edam"] = ontology_url + cm.yaml_add_eol_comment(comment_text, key="edam") + section["ontologies"].append(cm) except KeyError: log.warning(f"Could not add ontologies in {desc}") + else: + for item in section["ontologies"]: + if isinstance(item, ruamel.yaml.comments.CommentedMap) and item.get("edam") == ontology_url: + item.yaml_add_eol_comment(comment_text, key="edam") + break # EDAM ontologies edam_formats = nf_core.modules.modules_utils.load_edam() @@ -681,7 +689,17 @@ def _add_edam_ontologies(section, edam_formats, desc): def _ensure_string_keys(obj): """Recursively ensure all dict keys are strings (e.g., convert 1.2 -> "1.2")""" - if isinstance(obj, dict): + if isinstance(obj, ruamel.yaml.comments.CommentedMap): + for key in list(obj.keys()): + value = obj.pop(key) + new_key = str(key) if not isinstance(key, str) else key + obj[new_key] = _ensure_string_keys(value) + return obj + elif isinstance(obj, ruamel.yaml.comments.CommentedSeq): + for i, item in enumerate(obj): + obj[i] = _ensure_string_keys(item) + return obj + elif isinstance(obj, dict): return {str(k) if not isinstance(k, str) else k: _ensure_string_keys(v) for k, v in obj.items()} elif isinstance(obj, list): return [_ensure_string_keys(item) for item in obj] diff --git a/nf_core/modules/modules_utils.py b/nf_core/modules/modules_utils.py index 7b38369e8c..461816bb39 100644 --- a/nf_core/modules/modules_utils.py +++ b/nf_core/modules/modules_utils.py @@ -2,8 +2,6 @@ from pathlib import Path from urllib.parse import urlparse -import requests - from ..components.nfcore_component import NFCoreComponent log = logging.getLogger(__name__) @@ -99,15 +97,17 @@ def get_installed_modules(directory: Path, repo_type="modules") -> tuple[list[st def load_edam(): """Load the EDAM ontology from the nf-core repository""" edam_formats = {} + local_path = Path(__file__).parent.parent / "assets" / "EDAM_1.25.csv" try: - response = requests.get("https://edamontology.org/EDAM.tsv") - except requests.exceptions.RequestException as e: + with local_path.open("rb") as f: + data_bytes = f.read() + except (FileNotFoundError, OSError) as e: log.warning(f"Failed to load EDAM ontology: {e}") - return edam_formats - for line in response.content.splitlines(): - fields = line.decode("utf-8").split("\t") - if fields[0].split("/")[-1].startswith("format") and fields[14]: # We choose an already provided extension - extensions = fields[14].split("|") + return {} + for line in data_bytes.splitlines(): + fields = line.decode("utf-8").split(",") + if fields[0].split("/")[-1].startswith("format") and fields[2]: # We choose an already provided extension + extensions = fields[2].split("|") for extension in extensions: if extension not in edam_formats: edam_formats[extension] = (fields[0], fields[1]) # URL, name From 8316b6e6a10672058ed29b681e8b525992ac4883 Mon Sep 17 00:00:00 2001 From: louis Date: Tue, 28 Apr 2026 21:11:50 +0200 Subject: [PATCH 002/135] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ac4dbc685..90a675fa34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ ### Linting +- use static edam.csv and fix yaml comment loss ([#4242](https://github.com/nf-core/tools/pull/4242)) + ### Modules ### Subworkflows From c00bc7ebe0c2db0fb3fdb3f1fe7ec64ac305fe02 Mon Sep 17 00:00:00 2001 From: louis Date: Tue, 28 Apr 2026 21:29:06 +0200 Subject: [PATCH 003/135] Provide script to obtain EDAM --- nf_core/assets/EDAM.tsv | 62 + nf_core/assets/EDAM_1.25.csv | 3474 ----------------------------- nf_core/assets/get_latest_edam.sh | 4 + nf_core/modules/modules_utils.py | 4 +- 4 files changed, 68 insertions(+), 3476 deletions(-) create mode 100644 nf_core/assets/EDAM.tsv delete mode 100644 nf_core/assets/EDAM_1.25.csv create mode 100644 nf_core/assets/get_latest_edam.sh diff --git a/nf_core/assets/EDAM.tsv b/nf_core/assets/EDAM.tsv new file mode 100644 index 0000000000..f77ef5c107 --- /dev/null +++ b/nf_core/assets/EDAM.tsv @@ -0,0 +1,62 @@ +Class ID Preferred Label File extension +http://edamontology.org/format_1930 FASTQ fq|fastq +http://edamontology.org/format_2332 XML xml +http://edamontology.org/format_3256 N-Triples nt +http://edamontology.org/format_3257 Notation3 n3 +http://edamontology.org/format_3261 RDF/XML rdf +http://edamontology.org/format_3464 JSON json +http://edamontology.org/format_3475 TSV tsv|tab +http://edamontology.org/format_3556 MHTML mhtml|mht|eml +http://edamontology.org/format_3665 K-mer countgraph oxlicg +http://edamontology.org/format_3682 imzML metadata file imzML +http://edamontology.org/format_3710 WIFF format wiff +http://edamontology.org/format_3746 BIOM format biom +http://edamontology.org/format_3749 JSON-LD jsonld +http://edamontology.org/format_3750 YAML yaml|yml +http://edamontology.org/format_3752 CSV csv +http://edamontology.org/format_3788 SQL sql +http://edamontology.org/format_3789 XQuery xq|xqy|xquery +http://edamontology.org/format_3839 ibd ibd +http://edamontology.org/format_3857 CWL cwl +http://edamontology.org/format_3911 msh msh +http://edamontology.org/format_3913 Loom loom +http://edamontology.org/format_3915 Zarr zarray|zgroup +http://edamontology.org/format_3916 MTX mtx +http://edamontology.org/format_3956 N-Quads nq +http://edamontology.org/format_3969 Vega json +http://edamontology.org/format_3970 Vega-lite json +http://edamontology.org/format_3972 BNGL bngl +http://edamontology.org/format_3973 Docker image format dockerfile +http://edamontology.org/format_3975 GFA 1 gfa +http://edamontology.org/format_3976 GFA 2 gfa +http://edamontology.org/format_3977 ObjTables xlsx +http://edamontology.org/format_3978 CONTIG contig +http://edamontology.org/format_3979 WEGO wego +http://edamontology.org/format_3980 RPKM rpkm +http://edamontology.org/format_3981 TAR format tar +http://edamontology.org/format_3982 CHAIN chain +http://edamontology.org/format_3983 NET net +http://edamontology.org/format_3984 QMAP qmap +http://edamontology.org/format_3985 gxformat2 ga +http://edamontology.org/format_3986 WMV wmv +http://edamontology.org/format_3987 ZIP format zip +http://edamontology.org/format_3988 LSM lsm +http://edamontology.org/format_3989 GZIP format gz|gzip +http://edamontology.org/format_3990 AVI avi +http://edamontology.org/format_3991 TrackDB trackDb +http://edamontology.org/format_3992 CIGAR format cigar +http://edamontology.org/format_3993 Stereolithography format stl +http://edamontology.org/format_3994 U3D u3d +http://edamontology.org/format_3995 Texture file format tex +http://edamontology.org/format_3996 Python script py +http://edamontology.org/format_3997 MPEG-4 mp4 +http://edamontology.org/format_3998 Perl script pl +http://edamontology.org/format_3999 R script R +http://edamontology.org/format_4000 R markdown Rmd +http://edamontology.org/format_4001 NIFTI format nii +http://edamontology.org/format_4002 pickle pickle +http://edamontology.org/format_4003 NumPy format npy +http://edamontology.org/format_4004 SimTools repertoire file format repz +http://edamontology.org/format_4005 Configuration file format cfg +http://edamontology.org/format_4006 Zstandard format zst +http://edamontology.org/format_4007 MATLAB script m diff --git a/nf_core/assets/EDAM_1.25.csv b/nf_core/assets/EDAM_1.25.csv deleted file mode 100644 index 497367c8f9..0000000000 --- a/nf_core/assets/EDAM_1.25.csv +++ /dev/null @@ -1,3474 +0,0 @@ -Class ID,Preferred Label,File extension -http://edamontology.org/data_0005,Resource type, -http://edamontology.org/data_0006,Data, -http://edamontology.org/data_0007,Tool, -http://edamontology.org/data_0581,Database, -http://edamontology.org/data_0582,Ontology, -http://edamontology.org/data_0583,Directory metadata, -http://edamontology.org/data_0831,MeSH vocabulary, -http://edamontology.org/data_0832,HGNC vocabulary, -http://edamontology.org/data_0835,UMLS vocabulary, -http://edamontology.org/data_0842,Identifier, -http://edamontology.org/data_0843,Database entry, -http://edamontology.org/data_0844,Molecular mass, -http://edamontology.org/data_0845,Molecular charge, -http://edamontology.org/data_0846,Chemical formula, -http://edamontology.org/data_0847,QSAR descriptor, -http://edamontology.org/data_0848,Raw sequence, -http://edamontology.org/data_0849,Sequence record, -http://edamontology.org/data_0850,Sequence set, -http://edamontology.org/data_0851,Sequence mask character, -http://edamontology.org/data_0852,Sequence mask type, -http://edamontology.org/data_0853,DNA sense specification, -http://edamontology.org/data_0854,Sequence length specification, -http://edamontology.org/data_0855,Sequence metadata, -http://edamontology.org/data_0856,Sequence feature source, -http://edamontology.org/data_0857,Sequence search results, -http://edamontology.org/data_0858,Sequence signature matches, -http://edamontology.org/data_0859,Sequence signature model, -http://edamontology.org/data_0860,Sequence signature data, -http://edamontology.org/data_0861,Sequence alignment (words), -http://edamontology.org/data_0862,Dotplot, -http://edamontology.org/data_0863,Sequence alignment, -http://edamontology.org/data_0864,Sequence alignment parameter, -http://edamontology.org/data_0865,Sequence similarity score, -http://edamontology.org/data_0866,Sequence alignment metadata, -http://edamontology.org/data_0867,Sequence alignment report, -http://edamontology.org/data_0868,Profile-profile alignment, -http://edamontology.org/data_0869,Sequence-profile alignment, -http://edamontology.org/data_0870,Sequence distance matrix, -http://edamontology.org/data_0871,Phylogenetic character data, -http://edamontology.org/data_0872,Phylogenetic tree, -http://edamontology.org/data_0874,Comparison matrix, -http://edamontology.org/data_0875,Protein topology, -http://edamontology.org/data_0876,Protein features report (secondary structure), -http://edamontology.org/data_0877,Protein features report (super-secondary), -http://edamontology.org/data_0878,Protein secondary structure alignment, -http://edamontology.org/data_0879,Secondary structure alignment metadata (protein), -http://edamontology.org/data_0880,RNA secondary structure, -http://edamontology.org/data_0881,RNA secondary structure alignment, -http://edamontology.org/data_0882,Secondary structure alignment metadata (RNA), -http://edamontology.org/data_0883,Structure, -http://edamontology.org/data_0884,Tertiary structure record, -http://edamontology.org/data_0885,Structure database search results, -http://edamontology.org/data_0886,Structure alignment, -http://edamontology.org/data_0887,Structure alignment report, -http://edamontology.org/data_0888,Structure similarity score, -http://edamontology.org/data_0889,Structural profile, -http://edamontology.org/data_0890,Structural (3D) profile alignment, -http://edamontology.org/data_0891,Sequence-3D profile alignment, -http://edamontology.org/data_0892,Protein sequence-structure scoring matrix, -http://edamontology.org/data_0893,Sequence-structure alignment, -http://edamontology.org/data_0894,Amino acid annotation, -http://edamontology.org/data_0895,Peptide annotation, -http://edamontology.org/data_0896,Protein report, -http://edamontology.org/data_0897,Protein property, -http://edamontology.org/data_0899,Protein structural motifs and surfaces, -http://edamontology.org/data_0900,Protein domain classification, -http://edamontology.org/data_0901,Protein features report (domains), -http://edamontology.org/data_0902,Protein architecture report, -http://edamontology.org/data_0903,Protein folding report, -http://edamontology.org/data_0904,Protein features (mutation), -http://edamontology.org/data_0905,Protein interaction raw data, -http://edamontology.org/data_0906,Protein interaction data, -http://edamontology.org/data_0907,Protein family report, -http://edamontology.org/data_0909,Vmax, -http://edamontology.org/data_0910,Km, -http://edamontology.org/data_0911,Nucleotide base annotation, -http://edamontology.org/data_0912,Nucleic acid property, -http://edamontology.org/data_0914,Codon usage data, -http://edamontology.org/data_0916,Gene report, -http://edamontology.org/data_0917,Gene classification, -http://edamontology.org/data_0918,DNA variation, -http://edamontology.org/data_0919,Chromosome report, -http://edamontology.org/data_0920,Genotype/phenotype report, -http://edamontology.org/data_0923,PCR experiment report, -http://edamontology.org/data_0924,Sequence trace, -http://edamontology.org/data_0925,Sequence assembly, -http://edamontology.org/data_0926,RH scores, -http://edamontology.org/data_0927,Genetic linkage report, -http://edamontology.org/data_0928,Gene expression profile, -http://edamontology.org/data_0931,Microarray experiment report, -http://edamontology.org/data_0932,Oligonucleotide probe data, -http://edamontology.org/data_0933,SAGE experimental data, -http://edamontology.org/data_0934,MPSS experimental data, -http://edamontology.org/data_0935,SBS experimental data, -http://edamontology.org/data_0936,Sequence tag profile (with gene assignment), -http://edamontology.org/data_0937,Electron density map, -http://edamontology.org/data_0938,Raw NMR data, -http://edamontology.org/data_0939,CD spectra, -http://edamontology.org/data_0940,Volume map, -http://edamontology.org/data_0941,Electron microscopy model, -http://edamontology.org/data_0942,2D PAGE image, -http://edamontology.org/data_0943,Mass spectrum, -http://edamontology.org/data_0944,Peptide mass fingerprint, -http://edamontology.org/data_0945,Peptide identification, -http://edamontology.org/data_0946,Pathway or network annotation, -http://edamontology.org/data_0947,Biological pathway map, -http://edamontology.org/data_0948,Data resource definition, -http://edamontology.org/data_0949,Workflow metadata, -http://edamontology.org/data_0950,Mathematical model, -http://edamontology.org/data_0951,Statistical estimate score, -http://edamontology.org/data_0952,EMBOSS database resource definition, -http://edamontology.org/data_0953,Version information, -http://edamontology.org/data_0954,Database cross-mapping, -http://edamontology.org/data_0955,Data index, -http://edamontology.org/data_0956,Data index report, -http://edamontology.org/data_0957,Database metadata, -http://edamontology.org/data_0958,Tool metadata, -http://edamontology.org/data_0959,Job metadata, -http://edamontology.org/data_0960,User metadata, -http://edamontology.org/data_0962,Small molecule report, -http://edamontology.org/data_0963,Cell line report, -http://edamontology.org/data_0964,Scent annotation, -http://edamontology.org/data_0966,Ontology term, -http://edamontology.org/data_0967,Ontology concept data, -http://edamontology.org/data_0968,Keyword, -http://edamontology.org/data_0970,Citation, -http://edamontology.org/data_0971,Article, -http://edamontology.org/data_0972,Text mining report, -http://edamontology.org/data_0974,Entity identifier, -http://edamontology.org/data_0975,Data resource identifier, -http://edamontology.org/data_0976,Identifier (by type of data), -http://edamontology.org/data_0977,Tool identifier, -http://edamontology.org/data_0978,Discrete entity identifier, -http://edamontology.org/data_0979,Entity feature identifier, -http://edamontology.org/data_0980,Entity collection identifier, -http://edamontology.org/data_0981,Phenomenon identifier, -http://edamontology.org/data_0982,Molecule identifier, -http://edamontology.org/data_0983,Atom ID, -http://edamontology.org/data_0984,Molecule name, -http://edamontology.org/data_0985,Molecule type, -http://edamontology.org/data_0986,Chemical identifier, -http://edamontology.org/data_0987,Chromosome name, -http://edamontology.org/data_0988,Peptide identifier, -http://edamontology.org/data_0989,Protein identifier, -http://edamontology.org/data_0990,Compound name, -http://edamontology.org/data_0991,Chemical registry number, -http://edamontology.org/data_0992,Ligand identifier, -http://edamontology.org/data_0993,Drug identifier, -http://edamontology.org/data_0994,Amino acid identifier, -http://edamontology.org/data_0995,Nucleotide identifier, -http://edamontology.org/data_0996,Monosaccharide identifier, -http://edamontology.org/data_0997,Chemical name (ChEBI), -http://edamontology.org/data_0998,Chemical name (IUPAC), -http://edamontology.org/data_0999,Chemical name (INN), -http://edamontology.org/data_1000,Chemical name (brand), -http://edamontology.org/data_1001,Chemical name (synonymous), -http://edamontology.org/data_1002,CAS number, -http://edamontology.org/data_1003,Chemical registry number (Beilstein), -http://edamontology.org/data_1004,Chemical registry number (Gmelin), -http://edamontology.org/data_1005,HET group name, -http://edamontology.org/data_1006,Amino acid name, -http://edamontology.org/data_1007,Nucleotide code, -http://edamontology.org/data_1008,Polypeptide chain ID, -http://edamontology.org/data_1009,Protein name, -http://edamontology.org/data_1010,Enzyme identifier, -http://edamontology.org/data_1011,EC number, -http://edamontology.org/data_1012,Enzyme name, -http://edamontology.org/data_1013,Restriction enzyme name, -http://edamontology.org/data_1014,Sequence position specification, -http://edamontology.org/data_1015,Sequence feature ID, -http://edamontology.org/data_1016,Sequence position, -http://edamontology.org/data_1017,Sequence range, -http://edamontology.org/data_1018,Nucleic acid feature identifier, -http://edamontology.org/data_1019,Protein feature identifier, -http://edamontology.org/data_1020,Sequence feature key, -http://edamontology.org/data_1021,Sequence feature qualifier, -http://edamontology.org/data_1022,Sequence feature label, -http://edamontology.org/data_1023,EMBOSS Uniform Feature Object, -http://edamontology.org/data_1024,Codon name, -http://edamontology.org/data_1025,Gene identifier, -http://edamontology.org/data_1026,Gene symbol, -http://edamontology.org/data_1027,Gene ID (NCBI), -http://edamontology.org/data_1028,Gene identifier (NCBI RefSeq), -http://edamontology.org/data_1029,Gene identifier (NCBI UniGene), -http://edamontology.org/data_1030,Gene identifier (Entrez), -http://edamontology.org/data_1031,Gene ID (CGD), -http://edamontology.org/data_1032,Gene ID (DictyBase), -http://edamontology.org/data_1033,Ensembl gene ID, -http://edamontology.org/data_1034,Gene ID (SGD), -http://edamontology.org/data_1035,Gene ID (GeneDB), -http://edamontology.org/data_1036,TIGR identifier, -http://edamontology.org/data_1037,TAIR accession (gene), -http://edamontology.org/data_1038,Protein domain ID, -http://edamontology.org/data_1039,SCOP domain identifier, -http://edamontology.org/data_1040,CATH domain ID, -http://edamontology.org/data_1041,SCOP concise classification string (sccs), -http://edamontology.org/data_1042,SCOP sunid, -http://edamontology.org/data_1043,CATH node ID, -http://edamontology.org/data_1044,Kingdom name, -http://edamontology.org/data_1045,Species name, -http://edamontology.org/data_1046,Strain name, -http://edamontology.org/data_1047,URI, -http://edamontology.org/data_1048,Database ID, -http://edamontology.org/data_1049,Directory name, -http://edamontology.org/data_1050,File name, -http://edamontology.org/data_1051,Ontology name, -http://edamontology.org/data_1052,URL, -http://edamontology.org/data_1053,URN, -http://edamontology.org/data_1055,LSID, -http://edamontology.org/data_1056,Database name, -http://edamontology.org/data_1057,Sequence database name, -http://edamontology.org/data_1058,Enumerated file name, -http://edamontology.org/data_1059,File name extension, -http://edamontology.org/data_1060,File base name, -http://edamontology.org/data_1061,QSAR descriptor name, -http://edamontology.org/data_1062,Database entry identifier, -http://edamontology.org/data_1063,Sequence identifier, -http://edamontology.org/data_1064,Sequence set ID, -http://edamontology.org/data_1065,Sequence signature identifier, -http://edamontology.org/data_1066,Sequence alignment ID, -http://edamontology.org/data_1067,Phylogenetic distance matrix identifier, -http://edamontology.org/data_1068,Phylogenetic tree ID, -http://edamontology.org/data_1069,Comparison matrix identifier, -http://edamontology.org/data_1070,Structure ID, -http://edamontology.org/data_1071,Structural (3D) profile ID, -http://edamontology.org/data_1072,Structure alignment ID, -http://edamontology.org/data_1073,Amino acid index ID, -http://edamontology.org/data_1074,Protein interaction ID, -http://edamontology.org/data_1075,Protein family identifier, -http://edamontology.org/data_1076,Codon usage table name, -http://edamontology.org/data_1077,Transcription factor identifier, -http://edamontology.org/data_1078,Experiment annotation ID, -http://edamontology.org/data_1079,Electron microscopy model ID, -http://edamontology.org/data_1080,Gene expression report ID, -http://edamontology.org/data_1081,Genotype and phenotype annotation ID, -http://edamontology.org/data_1082,Pathway or network identifier, -http://edamontology.org/data_1083,Workflow ID, -http://edamontology.org/data_1084,Data resource definition ID, -http://edamontology.org/data_1085,Biological model ID, -http://edamontology.org/data_1086,Compound identifier, -http://edamontology.org/data_1087,Ontology concept ID, -http://edamontology.org/data_1088,Article ID, -http://edamontology.org/data_1089,FlyBase ID, -http://edamontology.org/data_1091,WormBase name, -http://edamontology.org/data_1092,WormBase class, -http://edamontology.org/data_1093,Sequence accession, -http://edamontology.org/data_1094,Sequence type, -http://edamontology.org/data_1095,EMBOSS Uniform Sequence Address, -http://edamontology.org/data_1096,Sequence accession (protein), -http://edamontology.org/data_1097,Sequence accession (nucleic acid), -http://edamontology.org/data_1098,RefSeq accession, -http://edamontology.org/data_1099,UniProt accession (extended), -http://edamontology.org/data_1100,PIR identifier, -http://edamontology.org/data_1101,TREMBL accession, -http://edamontology.org/data_1102,Gramene primary identifier, -http://edamontology.org/data_1103,EMBL/GenBank/DDBJ ID, -http://edamontology.org/data_1104,Sequence cluster ID (UniGene), -http://edamontology.org/data_1105,dbEST accession, -http://edamontology.org/data_1106,dbSNP ID, -http://edamontology.org/data_1110,EMBOSS sequence type, -http://edamontology.org/data_1111,EMBOSS listfile, -http://edamontology.org/data_1112,Sequence cluster ID, -http://edamontology.org/data_1113,Sequence cluster ID (COG), -http://edamontology.org/data_1114,Sequence motif identifier, -http://edamontology.org/data_1115,Sequence profile ID, -http://edamontology.org/data_1116,ELM ID, -http://edamontology.org/data_1117,Prosite accession number, -http://edamontology.org/data_1118,HMMER hidden Markov model ID, -http://edamontology.org/data_1119,JASPAR profile ID, -http://edamontology.org/data_1120,Sequence alignment type, -http://edamontology.org/data_1121,BLAST sequence alignment type, -http://edamontology.org/data_1122,Phylogenetic tree type, -http://edamontology.org/data_1123,TreeBASE study accession number, -http://edamontology.org/data_1124,TreeFam accession number, -http://edamontology.org/data_1125,Comparison matrix type, -http://edamontology.org/data_1126,Comparison matrix name, -http://edamontology.org/data_1127,PDB ID, -http://edamontology.org/data_1128,AAindex ID, -http://edamontology.org/data_1129,BIND accession number, -http://edamontology.org/data_1130,IntAct accession number, -http://edamontology.org/data_1131,Protein family name, -http://edamontology.org/data_1132,InterPro entry name, -http://edamontology.org/data_1133,InterPro accession, -http://edamontology.org/data_1134,InterPro secondary accession, -http://edamontology.org/data_1135,Gene3D ID, -http://edamontology.org/data_1136,PIRSF ID, -http://edamontology.org/data_1137,PRINTS code, -http://edamontology.org/data_1138,Pfam accession number, -http://edamontology.org/data_1139,SMART accession number, -http://edamontology.org/data_1140,Superfamily hidden Markov model number, -http://edamontology.org/data_1141,TIGRFam ID, -http://edamontology.org/data_1142,ProDom accession number, -http://edamontology.org/data_1143,TRANSFAC accession number, -http://edamontology.org/data_1144,ArrayExpress accession number, -http://edamontology.org/data_1145,PRIDE experiment accession number, -http://edamontology.org/data_1146,EMDB ID, -http://edamontology.org/data_1147,GEO accession number, -http://edamontology.org/data_1148,GermOnline ID, -http://edamontology.org/data_1149,EMAGE ID, -http://edamontology.org/data_1150,Disease ID, -http://edamontology.org/data_1151,HGVbase ID, -http://edamontology.org/data_1152,HIVDB identifier, -http://edamontology.org/data_1153,OMIM ID, -http://edamontology.org/data_1154,KEGG object identifier, -http://edamontology.org/data_1155,Pathway ID (reactome), -http://edamontology.org/data_1156,Pathway ID (aMAZE), -http://edamontology.org/data_1157,Pathway ID (BioCyc), -http://edamontology.org/data_1158,Pathway ID (INOH), -http://edamontology.org/data_1159,Pathway ID (PATIKA), -http://edamontology.org/data_1160,Pathway ID (CPDB), -http://edamontology.org/data_1161,Pathway ID (Panther), -http://edamontology.org/data_1162,MIRIAM identifier, -http://edamontology.org/data_1163,MIRIAM data type name, -http://edamontology.org/data_1164,MIRIAM URI, -http://edamontology.org/data_1165,MIRIAM data type primary name, -http://edamontology.org/data_1166,MIRIAM data type synonymous name, -http://edamontology.org/data_1167,Taverna workflow ID, -http://edamontology.org/data_1170,Biological model name, -http://edamontology.org/data_1171,BioModel ID, -http://edamontology.org/data_1172,PubChem CID, -http://edamontology.org/data_1173,ChemSpider ID, -http://edamontology.org/data_1174,ChEBI ID, -http://edamontology.org/data_1175,BioPax concept ID, -http://edamontology.org/data_1176,GO concept ID, -http://edamontology.org/data_1177,MeSH concept ID, -http://edamontology.org/data_1178,HGNC concept ID, -http://edamontology.org/data_1179,NCBI taxonomy ID, -http://edamontology.org/data_1180,Plant Ontology concept ID, -http://edamontology.org/data_1181,UMLS concept ID, -http://edamontology.org/data_1182,FMA concept ID, -http://edamontology.org/data_1183,EMAP concept ID, -http://edamontology.org/data_1184,ChEBI concept ID, -http://edamontology.org/data_1185,MGED concept ID, -http://edamontology.org/data_1186,myGrid concept ID, -http://edamontology.org/data_1187,PubMed ID, -http://edamontology.org/data_1188,DOI, -http://edamontology.org/data_1189,Medline UI, -http://edamontology.org/data_1190,Tool name, -http://edamontology.org/data_1191,Tool name (signature), -http://edamontology.org/data_1192,Tool name (BLAST), -http://edamontology.org/data_1193,Tool name (FASTA), -http://edamontology.org/data_1194,Tool name (EMBOSS), -http://edamontology.org/data_1195,Tool name (EMBASSY package), -http://edamontology.org/data_1201,QSAR descriptor (constitutional), -http://edamontology.org/data_1202,QSAR descriptor (electronic), -http://edamontology.org/data_1203,QSAR descriptor (geometrical), -http://edamontology.org/data_1204,QSAR descriptor (topological), -http://edamontology.org/data_1205,QSAR descriptor (molecular), -http://edamontology.org/data_1233,Sequence set (protein), -http://edamontology.org/data_1234,Sequence set (nucleic acid), -http://edamontology.org/data_1235,Sequence cluster, -http://edamontology.org/data_1236,Psiblast checkpoint file, -http://edamontology.org/data_1237,HMMER synthetic sequences set, -http://edamontology.org/data_1238,Proteolytic digest, -http://edamontology.org/data_1239,Restriction digest, -http://edamontology.org/data_1240,PCR primers, -http://edamontology.org/data_1241,vectorstrip cloning vector definition file, -http://edamontology.org/data_1242,Primer3 internal oligo mishybridizing library, -http://edamontology.org/data_1243,Primer3 mispriming library file, -http://edamontology.org/data_1244,primersearch primer pairs sequence record, -http://edamontology.org/data_1245,Sequence cluster (protein), -http://edamontology.org/data_1246,Sequence cluster (nucleic acid), -http://edamontology.org/data_1249,Sequence length, -http://edamontology.org/data_1250,Word size, -http://edamontology.org/data_1251,Window size, -http://edamontology.org/data_1252,Sequence length range, -http://edamontology.org/data_1253,Sequence information report, -http://edamontology.org/data_1254,Sequence property, -http://edamontology.org/data_1255,Sequence features, -http://edamontology.org/data_1256,Sequence features (comparative), -http://edamontology.org/data_1257,Sequence property (protein), -http://edamontology.org/data_1258,Sequence property (nucleic acid), -http://edamontology.org/data_1259,Sequence complexity report, -http://edamontology.org/data_1260,Sequence ambiguity report, -http://edamontology.org/data_1261,Sequence composition report, -http://edamontology.org/data_1262,Peptide molecular weight hits, -http://edamontology.org/data_1263,Base position variability plot, -http://edamontology.org/data_1264,Sequence composition table, -http://edamontology.org/data_1265,Base frequencies table, -http://edamontology.org/data_1266,Base word frequencies table, -http://edamontology.org/data_1267,Amino acid frequencies table, -http://edamontology.org/data_1268,Amino acid word frequencies table, -http://edamontology.org/data_1269,DAS sequence feature annotation, -http://edamontology.org/data_1270,Feature table, -http://edamontology.org/data_1274,Map, -http://edamontology.org/data_1276,Nucleic acid features, -http://edamontology.org/data_1277,Protein features, -http://edamontology.org/data_1278,Genetic map, -http://edamontology.org/data_1279,Sequence map, -http://edamontology.org/data_1280,Physical map, -http://edamontology.org/data_1281,Sequence signature map, -http://edamontology.org/data_1283,Cytogenetic map, -http://edamontology.org/data_1284,DNA transduction map, -http://edamontology.org/data_1285,Gene map, -http://edamontology.org/data_1286,Plasmid map, -http://edamontology.org/data_1288,Genome map, -http://edamontology.org/data_1289,Restriction map, -http://edamontology.org/data_1290,InterPro compact match image, -http://edamontology.org/data_1291,InterPro detailed match image, -http://edamontology.org/data_1292,InterPro architecture image, -http://edamontology.org/data_1293,SMART protein schematic, -http://edamontology.org/data_1294,GlobPlot domain image, -http://edamontology.org/data_1298,Sequence motif matches, -http://edamontology.org/data_1299,Sequence features (repeats), -http://edamontology.org/data_1300,Gene and transcript structure (report), -http://edamontology.org/data_1301,Mobile genetic elements, -http://edamontology.org/data_1303,Nucleic acid features (quadruplexes), -http://edamontology.org/data_1306,Nucleosome exclusion sequences, -http://edamontology.org/data_1309,Gene features (exonic splicing enhancer), -http://edamontology.org/data_1310,Nucleic acid features (microRNA), -http://edamontology.org/data_1313,Coding region, -http://edamontology.org/data_1314,Gene features (SECIS element), -http://edamontology.org/data_1315,Transcription factor binding sites, -http://edamontology.org/data_1321,Protein features (sites), -http://edamontology.org/data_1322,Protein features report (signal peptides), -http://edamontology.org/data_1323,Protein features report (cleavage sites), -http://edamontology.org/data_1324,Protein features (post-translation modifications), -http://edamontology.org/data_1325,Protein features report (active sites), -http://edamontology.org/data_1326,Protein features report (binding sites), -http://edamontology.org/data_1327,Protein features (epitopes), -http://edamontology.org/data_1328,Protein features report (nucleic acid binding sites), -http://edamontology.org/data_1329,MHC Class I epitopes report, -http://edamontology.org/data_1330,MHC Class II epitopes report, -http://edamontology.org/data_1331,Protein features (PEST sites), -http://edamontology.org/data_1338,Sequence database hits scores list, -http://edamontology.org/data_1339,Sequence database hits alignments list, -http://edamontology.org/data_1340,Sequence database hits evaluation data, -http://edamontology.org/data_1344,MEME motif alphabet, -http://edamontology.org/data_1345,MEME background frequencies file, -http://edamontology.org/data_1346,MEME motifs directive file, -http://edamontology.org/data_1347,Dirichlet distribution, -http://edamontology.org/data_1348,HMM emission and transition counts, -http://edamontology.org/data_1352,Regular expression, -http://edamontology.org/data_1353,Sequence motif, -http://edamontology.org/data_1354,Sequence profile, -http://edamontology.org/data_1355,Protein signature, -http://edamontology.org/data_1358,Prosite nucleotide pattern, -http://edamontology.org/data_1359,Prosite protein pattern, -http://edamontology.org/data_1361,Position frequency matrix, -http://edamontology.org/data_1362,Position weight matrix, -http://edamontology.org/data_1363,Information content matrix, -http://edamontology.org/data_1364,Hidden Markov model, -http://edamontology.org/data_1365,Fingerprint, -http://edamontology.org/data_1368,Domainatrix signature, -http://edamontology.org/data_1371,HMMER NULL hidden Markov model, -http://edamontology.org/data_1372,Protein family signature, -http://edamontology.org/data_1373,Protein domain signature, -http://edamontology.org/data_1374,Protein region signature, -http://edamontology.org/data_1375,Protein repeat signature, -http://edamontology.org/data_1376,Protein site signature, -http://edamontology.org/data_1377,Protein conserved site signature, -http://edamontology.org/data_1378,Protein active site signature, -http://edamontology.org/data_1379,Protein binding site signature, -http://edamontology.org/data_1380,Protein post-translational modification signature, -http://edamontology.org/data_1381,Pair sequence alignment, -http://edamontology.org/data_1382,Sequence alignment (multiple), -http://edamontology.org/data_1383,Nucleic acid sequence alignment, -http://edamontology.org/data_1384,Protein sequence alignment, -http://edamontology.org/data_1385,Hybrid sequence alignment, -http://edamontology.org/data_1386,Sequence alignment (nucleic acid pair), -http://edamontology.org/data_1387,Sequence alignment (protein pair), -http://edamontology.org/data_1388,Hybrid sequence alignment (pair), -http://edamontology.org/data_1389,Multiple nucleotide sequence alignment, -http://edamontology.org/data_1390,Multiple protein sequence alignment, -http://edamontology.org/data_1394,Alignment score or penalty, -http://edamontology.org/data_1395,Score end gaps control, -http://edamontology.org/data_1396,Aligned sequence order, -http://edamontology.org/data_1397,Gap opening penalty, -http://edamontology.org/data_1398,Gap extension penalty, -http://edamontology.org/data_1399,Gap separation penalty, -http://edamontology.org/data_1400,Terminal gap penalty, -http://edamontology.org/data_1401,Match reward score, -http://edamontology.org/data_1402,Mismatch penalty score, -http://edamontology.org/data_1403,Drop off score, -http://edamontology.org/data_1404,Gap opening penalty (integer), -http://edamontology.org/data_1405,Gap opening penalty (float), -http://edamontology.org/data_1406,Gap extension penalty (integer), -http://edamontology.org/data_1407,Gap extension penalty (float), -http://edamontology.org/data_1408,Gap separation penalty (integer), -http://edamontology.org/data_1409,Gap separation penalty (float), -http://edamontology.org/data_1410,Terminal gap opening penalty, -http://edamontology.org/data_1411,Terminal gap extension penalty, -http://edamontology.org/data_1412,Sequence identity, -http://edamontology.org/data_1413,Sequence similarity, -http://edamontology.org/data_1414,Sequence alignment metadata (quality report), -http://edamontology.org/data_1415,Sequence alignment report (site conservation), -http://edamontology.org/data_1416,Sequence alignment report (site correlation), -http://edamontology.org/data_1417,Sequence-profile alignment (Domainatrix signature), -http://edamontology.org/data_1418,Sequence-profile alignment (HMM), -http://edamontology.org/data_1420,Sequence-profile alignment (fingerprint), -http://edamontology.org/data_1426,Phylogenetic continuous quantitative data, -http://edamontology.org/data_1427,Phylogenetic discrete data, -http://edamontology.org/data_1428,Phylogenetic character cliques, -http://edamontology.org/data_1429,Phylogenetic invariants, -http://edamontology.org/data_1438,Phylogenetic report, -http://edamontology.org/data_1439,DNA substitution model, -http://edamontology.org/data_1440,Phylogenetic tree report (tree shape), -http://edamontology.org/data_1441,Phylogenetic tree report (tree evaluation), -http://edamontology.org/data_1442,Phylogenetic tree distances, -http://edamontology.org/data_1443,Phylogenetic tree report (tree stratigraphic), -http://edamontology.org/data_1444,Phylogenetic character contrasts, -http://edamontology.org/data_1446,Comparison matrix (integers), -http://edamontology.org/data_1447,Comparison matrix (floats), -http://edamontology.org/data_1448,Comparison matrix (nucleotide), -http://edamontology.org/data_1449,Comparison matrix (amino acid), -http://edamontology.org/data_1450,Nucleotide comparison matrix (integers), -http://edamontology.org/data_1451,Nucleotide comparison matrix (floats), -http://edamontology.org/data_1452,Amino acid comparison matrix (integers), -http://edamontology.org/data_1453,Amino acid comparison matrix (floats), -http://edamontology.org/data_1459,Nucleic acid structure, -http://edamontology.org/data_1460,Protein structure, -http://edamontology.org/data_1461,Protein-ligand complex, -http://edamontology.org/data_1462,Carbohydrate structure, -http://edamontology.org/data_1463,Small molecule structure, -http://edamontology.org/data_1464,DNA structure, -http://edamontology.org/data_1465,RNA structure, -http://edamontology.org/data_1466,tRNA structure, -http://edamontology.org/data_1467,Protein chain, -http://edamontology.org/data_1468,Protein domain, -http://edamontology.org/data_1469,Protein structure (all atoms), -http://edamontology.org/data_1470,C-alpha trace, -http://edamontology.org/data_1471,Protein chain (all atoms), -http://edamontology.org/data_1472,Protein chain (C-alpha atoms), -http://edamontology.org/data_1473,Protein domain (all atoms), -http://edamontology.org/data_1474,Protein domain (C-alpha atoms), -http://edamontology.org/data_1479,Structure alignment (pair), -http://edamontology.org/data_1480,Structure alignment (multiple), -http://edamontology.org/data_1481,Protein structure alignment, -http://edamontology.org/data_1482,Nucleic acid structure alignment, -http://edamontology.org/data_1483,Structure alignment (protein pair), -http://edamontology.org/data_1484,Multiple protein tertiary structure alignment, -http://edamontology.org/data_1485,Structure alignment (protein all atoms), -http://edamontology.org/data_1486,Structure alignment (protein C-alpha atoms), -http://edamontology.org/data_1487,Pairwise protein tertiary structure alignment (all atoms), -http://edamontology.org/data_1488,Pairwise protein tertiary structure alignment (C-alpha atoms), -http://edamontology.org/data_1489,Multiple protein tertiary structure alignment (all atoms), -http://edamontology.org/data_1490,Multiple protein tertiary structure alignment (C-alpha atoms), -http://edamontology.org/data_1491,Structure alignment (nucleic acid pair), -http://edamontology.org/data_1492,Multiple nucleic acid tertiary structure alignment, -http://edamontology.org/data_1493,RNA structure alignment, -http://edamontology.org/data_1494,Structural transformation matrix, -http://edamontology.org/data_1495,DaliLite hit table, -http://edamontology.org/data_1496,Molecular similarity score, -http://edamontology.org/data_1497,Root-mean-square deviation, -http://edamontology.org/data_1498,Tanimoto similarity score, -http://edamontology.org/data_1499,3D-1D scoring matrix, -http://edamontology.org/data_1501,Amino acid index, -http://edamontology.org/data_1502,Amino acid index (chemical classes), -http://edamontology.org/data_1503,Amino acid pair-wise contact potentials, -http://edamontology.org/data_1505,Amino acid index (molecular weight), -http://edamontology.org/data_1506,Amino acid index (hydropathy), -http://edamontology.org/data_1507,Amino acid index (White-Wimley data), -http://edamontology.org/data_1508,Amino acid index (van der Waals radii), -http://edamontology.org/data_1509,Enzyme report, -http://edamontology.org/data_1517,Restriction enzyme report, -http://edamontology.org/data_1519,Peptide molecular weights, -http://edamontology.org/data_1520,Peptide hydrophobic moment, -http://edamontology.org/data_1521,Protein aliphatic index, -http://edamontology.org/data_1522,Protein sequence hydropathy plot, -http://edamontology.org/data_1523,Protein charge plot, -http://edamontology.org/data_1524,Protein solubility, -http://edamontology.org/data_1525,Protein crystallizability, -http://edamontology.org/data_1526,Protein globularity, -http://edamontology.org/data_1527,Protein titration curve, -http://edamontology.org/data_1528,Protein isoelectric point, -http://edamontology.org/data_1529,Protein pKa value, -http://edamontology.org/data_1530,Protein hydrogen exchange rate, -http://edamontology.org/data_1531,Protein extinction coefficient, -http://edamontology.org/data_1532,Protein optical density, -http://edamontology.org/data_1533,Protein subcellular localisation, -http://edamontology.org/data_1534,Peptide immunogenicity data, -http://edamontology.org/data_1536,MHC peptide immunogenicity report, -http://edamontology.org/data_1537,Protein structure report, -http://edamontology.org/data_1539,Protein structural quality report, -http://edamontology.org/data_1540,Protein non-covalent interactions report, -http://edamontology.org/data_1541,Protein flexibility or motion report, -http://edamontology.org/data_1542,Protein solvent accessibility, -http://edamontology.org/data_1543,Protein surface report, -http://edamontology.org/data_1544,Ramachandran plot, -http://edamontology.org/data_1545,Protein dipole moment, -http://edamontology.org/data_1546,Protein distance matrix, -http://edamontology.org/data_1547,Protein contact map, -http://edamontology.org/data_1548,Protein residue 3D cluster, -http://edamontology.org/data_1549,Protein hydrogen bonds, -http://edamontology.org/data_1550,Protein non-canonical interactions, -http://edamontology.org/data_1553,CATH node, -http://edamontology.org/data_1554,SCOP node, -http://edamontology.org/data_1555,EMBASSY domain classification, -http://edamontology.org/data_1556,CATH class, -http://edamontology.org/data_1557,CATH architecture, -http://edamontology.org/data_1558,CATH topology, -http://edamontology.org/data_1559,CATH homologous superfamily, -http://edamontology.org/data_1560,CATH structurally similar group, -http://edamontology.org/data_1561,CATH functional category, -http://edamontology.org/data_1564,Protein fold recognition report, -http://edamontology.org/data_1565,Protein-protein interaction report, -http://edamontology.org/data_1566,Protein-ligand interaction report, -http://edamontology.org/data_1567,Protein-nucleic acid interactions report, -http://edamontology.org/data_1583,Nucleic acid melting profile, -http://edamontology.org/data_1584,Nucleic acid enthalpy, -http://edamontology.org/data_1585,Nucleic acid entropy, -http://edamontology.org/data_1586,Nucleic acid melting temperature, -http://edamontology.org/data_1587,Nucleic acid stitch profile, -http://edamontology.org/data_1588,DNA base pair stacking energies data, -http://edamontology.org/data_1589,DNA base pair twist angle data, -http://edamontology.org/data_1590,DNA base trimer roll angles data, -http://edamontology.org/data_1591,Vienna RNA parameters, -http://edamontology.org/data_1592,Vienna RNA structure constraints, -http://edamontology.org/data_1593,Vienna RNA concentration data, -http://edamontology.org/data_1594,Vienna RNA calculated energy, -http://edamontology.org/data_1595,Base pairing probability matrix dotplot, -http://edamontology.org/data_1596,Nucleic acid folding report, -http://edamontology.org/data_1597,Codon usage table, -http://edamontology.org/data_1598,Genetic code, -http://edamontology.org/data_1599,Codon adaptation index, -http://edamontology.org/data_1600,Codon usage bias plot, -http://edamontology.org/data_1601,Nc statistic, -http://edamontology.org/data_1602,Codon usage fraction difference, -http://edamontology.org/data_1621,Pharmacogenomic test report, -http://edamontology.org/data_1622,Disease report, -http://edamontology.org/data_1634,Linkage disequilibrium (report), -http://edamontology.org/data_1636,Heat map, -http://edamontology.org/data_1642,Affymetrix probe sets library file, -http://edamontology.org/data_1643,Affymetrix probe sets information library file, -http://edamontology.org/data_1646,Molecular weights standard fingerprint, -http://edamontology.org/data_1656,Metabolic pathway report, -http://edamontology.org/data_1657,Genetic information processing pathway report, -http://edamontology.org/data_1658,Environmental information processing pathway report, -http://edamontology.org/data_1659,Signal transduction pathway report, -http://edamontology.org/data_1660,Cellular process pathways report, -http://edamontology.org/data_1661,Disease pathway or network report, -http://edamontology.org/data_1662,Drug structure relationship map, -http://edamontology.org/data_1663,Protein interaction networks, -http://edamontology.org/data_1664,MIRIAM datatype, -http://edamontology.org/data_1667,E-value, -http://edamontology.org/data_1668,Z-value, -http://edamontology.org/data_1669,P-value, -http://edamontology.org/data_1670,Database version information, -http://edamontology.org/data_1671,Tool version information, -http://edamontology.org/data_1672,CATH version information, -http://edamontology.org/data_1673,Swiss-Prot to PDB mapping, -http://edamontology.org/data_1674,Sequence database cross-references, -http://edamontology.org/data_1675,Job status, -http://edamontology.org/data_1676,Job ID, -http://edamontology.org/data_1677,Job type, -http://edamontology.org/data_1678,Tool log, -http://edamontology.org/data_1679,DaliLite log file, -http://edamontology.org/data_1680,STRIDE log file, -http://edamontology.org/data_1681,NACCESS log file, -http://edamontology.org/data_1682,EMBOSS wordfinder log file, -http://edamontology.org/data_1683,EMBOSS domainatrix log file, -http://edamontology.org/data_1684,EMBOSS sites log file, -http://edamontology.org/data_1685,EMBOSS supermatcher error file, -http://edamontology.org/data_1686,EMBOSS megamerger log file, -http://edamontology.org/data_1687,EMBOSS whichdb log file, -http://edamontology.org/data_1688,EMBOSS vectorstrip log file, -http://edamontology.org/data_1689,Username, -http://edamontology.org/data_1690,Password, -http://edamontology.org/data_1691,Email address, -http://edamontology.org/data_1692,Person name, -http://edamontology.org/data_1693,Number of iterations, -http://edamontology.org/data_1694,Number of output entities, -http://edamontology.org/data_1695,Hit sort order, -http://edamontology.org/data_1696,Drug report, -http://edamontology.org/data_1707,Phylogenetic tree image, -http://edamontology.org/data_1708,RNA secondary structure image, -http://edamontology.org/data_1709,Protein secondary structure image, -http://edamontology.org/data_1710,Structure image, -http://edamontology.org/data_1711,Sequence alignment image, -http://edamontology.org/data_1712,Chemical structure image, -http://edamontology.org/data_1713,Fate map, -http://edamontology.org/data_1714,Microarray spots image, -http://edamontology.org/data_1715,BioPax term, -http://edamontology.org/data_1716,GO, -http://edamontology.org/data_1717,MeSH, -http://edamontology.org/data_1718,HGNC, -http://edamontology.org/data_1719,NCBI taxonomy vocabulary, -http://edamontology.org/data_1720,Plant ontology term, -http://edamontology.org/data_1721,UMLS, -http://edamontology.org/data_1722,FMA, -http://edamontology.org/data_1723,EMAP, -http://edamontology.org/data_1724,ChEBI, -http://edamontology.org/data_1725,MGED, -http://edamontology.org/data_1726,myGrid, -http://edamontology.org/data_1727,GO (biological process), -http://edamontology.org/data_1728,GO (molecular function), -http://edamontology.org/data_1729,GO (cellular component), -http://edamontology.org/data_1730,Ontology relation type, -http://edamontology.org/data_1731,Ontology concept definition, -http://edamontology.org/data_1732,Ontology concept comment, -http://edamontology.org/data_1733,Ontology concept reference, -http://edamontology.org/data_1738,doc2loc document information, -http://edamontology.org/data_1742,PDB residue number, -http://edamontology.org/data_1743,Atomic coordinate, -http://edamontology.org/data_1744,Atomic x coordinate, -http://edamontology.org/data_1745,Atomic y coordinate, -http://edamontology.org/data_1746,Atomic z coordinate, -http://edamontology.org/data_1748,PDB atom name, -http://edamontology.org/data_1755,Protein atom, -http://edamontology.org/data_1756,Protein residue, -http://edamontology.org/data_1757,Atom name, -http://edamontology.org/data_1758,PDB residue name, -http://edamontology.org/data_1759,PDB model number, -http://edamontology.org/data_1762,CATH domain report, -http://edamontology.org/data_1764,CATH representative domain sequences (ATOM), -http://edamontology.org/data_1765,CATH representative domain sequences (COMBS), -http://edamontology.org/data_1766,CATH domain sequences (ATOM), -http://edamontology.org/data_1767,CATH domain sequences (COMBS), -http://edamontology.org/data_1771,Sequence version, -http://edamontology.org/data_1772,Score, -http://edamontology.org/data_1776,Protein report (function), -http://edamontology.org/data_1783,Gene name (ASPGD), -http://edamontology.org/data_1784,Gene name (CGD), -http://edamontology.org/data_1785,Gene name (dictyBase), -http://edamontology.org/data_1786,Gene name (EcoGene primary), -http://edamontology.org/data_1787,Gene name (MaizeGDB), -http://edamontology.org/data_1788,Gene name (SGD), -http://edamontology.org/data_1789,Gene name (TGD), -http://edamontology.org/data_1790,Gene name (CGSC), -http://edamontology.org/data_1791,Gene name (HGNC), -http://edamontology.org/data_1792,Gene name (MGD), -http://edamontology.org/data_1793,Gene name (Bacillus subtilis), -http://edamontology.org/data_1794,Gene ID (PlasmoDB), -http://edamontology.org/data_1795,Gene ID (EcoGene), -http://edamontology.org/data_1796,Gene ID (FlyBase), -http://edamontology.org/data_1797,Gene ID (GeneDB Glossina morsitans), -http://edamontology.org/data_1798,Gene ID (GeneDB Leishmania major), -http://edamontology.org/data_1799,Gene ID (GeneDB Plasmodium falciparum), -http://edamontology.org/data_1800,Gene ID (GeneDB Schizosaccharomyces pombe), -http://edamontology.org/data_1801,Gene ID (GeneDB Trypanosoma brucei), -http://edamontology.org/data_1802,Gene ID (Gramene), -http://edamontology.org/data_1803,Gene ID (Virginia microbial), -http://edamontology.org/data_1804,Gene ID (SGN), -http://edamontology.org/data_1805,Gene ID (WormBase), -http://edamontology.org/data_1806,Gene synonym, -http://edamontology.org/data_1807,ORF name, -http://edamontology.org/data_1852,Sequence assembly component, -http://edamontology.org/data_1853,Chromosome annotation (aberration), -http://edamontology.org/data_1855,Clone ID, -http://edamontology.org/data_1856,PDB insertion code, -http://edamontology.org/data_1857,Atomic occupancy, -http://edamontology.org/data_1858,Isotropic B factor, -http://edamontology.org/data_1859,Deletion map, -http://edamontology.org/data_1860,QTL map, -http://edamontology.org/data_1863,Haplotype map, -http://edamontology.org/data_1864,Map set data, -http://edamontology.org/data_1865,Map feature, -http://edamontology.org/data_1866,Map type, -http://edamontology.org/data_1867,Protein fold name, -http://edamontology.org/data_1868,Taxon, -http://edamontology.org/data_1869,Organism identifier, -http://edamontology.org/data_1870,Genus name, -http://edamontology.org/data_1872,Taxonomic classification, -http://edamontology.org/data_1873,iHOP organism ID, -http://edamontology.org/data_1874,Genbank common name, -http://edamontology.org/data_1875,NCBI taxon, -http://edamontology.org/data_1877,Synonym, -http://edamontology.org/data_1878,Misspelling, -http://edamontology.org/data_1879,Acronym, -http://edamontology.org/data_1880,Misnomer, -http://edamontology.org/data_1881,Author ID, -http://edamontology.org/data_1882,DragonDB author identifier, -http://edamontology.org/data_1883,Annotated URI, -http://edamontology.org/data_1884,UniProt keywords, -http://edamontology.org/data_1885,Gene ID (GeneFarm), -http://edamontology.org/data_1886,Blattner number, -http://edamontology.org/data_1887,Gene ID (MIPS Maize), -http://edamontology.org/data_1888,Gene ID (MIPS Medicago), -http://edamontology.org/data_1889,Gene name (DragonDB), -http://edamontology.org/data_1890,Gene name (Arabidopsis), -http://edamontology.org/data_1891,iHOP symbol, -http://edamontology.org/data_1892,Gene name (GeneFarm), -http://edamontology.org/data_1893,Locus ID, -http://edamontology.org/data_1895,Locus ID (AGI), -http://edamontology.org/data_1896,Locus ID (ASPGD), -http://edamontology.org/data_1897,Locus ID (MGG), -http://edamontology.org/data_1898,Locus ID (CGD), -http://edamontology.org/data_1899,Locus ID (CMR), -http://edamontology.org/data_1900,NCBI locus tag, -http://edamontology.org/data_1901,Locus ID (SGD), -http://edamontology.org/data_1902,Locus ID (MMP), -http://edamontology.org/data_1903,Locus ID (DictyBase), -http://edamontology.org/data_1904,Locus ID (EntrezGene), -http://edamontology.org/data_1905,Locus ID (MaizeGDB), -http://edamontology.org/data_1906,Quantitative trait locus, -http://edamontology.org/data_1907,Gene ID (KOME), -http://edamontology.org/data_1908,Locus ID (Tropgene), -http://edamontology.org/data_1916,Alignment, -http://edamontology.org/data_1917,Atomic property, -http://edamontology.org/data_2007,UniProt keyword, -http://edamontology.org/data_2009,Ordered locus name, -http://edamontology.org/data_2012,Sequence coordinates, -http://edamontology.org/data_2016,Amino acid property, -http://edamontology.org/data_2018,Annotation, -http://edamontology.org/data_2019,Map data, -http://edamontology.org/data_2022,Vienna RNA structural data, -http://edamontology.org/data_2023,Sequence mask parameter, -http://edamontology.org/data_2024,Enzyme kinetics data, -http://edamontology.org/data_2025,Michaelis Menten plot, -http://edamontology.org/data_2026,Hanes Woolf plot, -http://edamontology.org/data_2028,Experimental data, -http://edamontology.org/data_2041,Genome version information, -http://edamontology.org/data_2042,Evidence, -http://edamontology.org/data_2043,Sequence record lite, -http://edamontology.org/data_2044,Sequence, -http://edamontology.org/data_2046,Nucleic acid sequence record (lite), -http://edamontology.org/data_2047,Protein sequence record (lite), -http://edamontology.org/data_2048,Report, -http://edamontology.org/data_2050,Molecular property (general), -http://edamontology.org/data_2053,Structural data, -http://edamontology.org/data_2070,Sequence motif (nucleic acid), -http://edamontology.org/data_2071,Sequence motif (protein), -http://edamontology.org/data_2079,Search parameter, -http://edamontology.org/data_2080,Database search results, -http://edamontology.org/data_2081,Secondary structure, -http://edamontology.org/data_2082,Matrix, -http://edamontology.org/data_2083,Alignment data, -http://edamontology.org/data_2084,Nucleic acid report, -http://edamontology.org/data_2085,Structure report, -http://edamontology.org/data_2086,Nucleic acid structure data, -http://edamontology.org/data_2087,Molecular property, -http://edamontology.org/data_2088,DNA base structural data, -http://edamontology.org/data_2090,Database entry version information, -http://edamontology.org/data_2091,Accession, -http://edamontology.org/data_2092,SNP, -http://edamontology.org/data_2093,Data reference, -http://edamontology.org/data_2098,Job identifier, -http://edamontology.org/data_2099,Name, -http://edamontology.org/data_2100,Type, -http://edamontology.org/data_2101,User ID, -http://edamontology.org/data_2102,KEGG organism code, -http://edamontology.org/data_2103,Gene name (KEGG GENES), -http://edamontology.org/data_2104,BioCyc ID, -http://edamontology.org/data_2105,Compound ID (BioCyc), -http://edamontology.org/data_2106,Reaction ID (BioCyc), -http://edamontology.org/data_2107,Enzyme ID (BioCyc), -http://edamontology.org/data_2108,Reaction ID, -http://edamontology.org/data_2109,Identifier (hybrid), -http://edamontology.org/data_2110,Molecular property identifier, -http://edamontology.org/data_2111,Codon usage table ID, -http://edamontology.org/data_2112,FlyBase primary identifier, -http://edamontology.org/data_2113,WormBase identifier, -http://edamontology.org/data_2114,WormBase wormpep ID, -http://edamontology.org/data_2116,Nucleic acid features (codon), -http://edamontology.org/data_2117,Map identifier, -http://edamontology.org/data_2118,Person identifier, -http://edamontology.org/data_2119,Nucleic acid identifier, -http://edamontology.org/data_2126,Translation frame specification, -http://edamontology.org/data_2127,Genetic code identifier, -http://edamontology.org/data_2128,Genetic code name, -http://edamontology.org/data_2129,File format name, -http://edamontology.org/data_2130,Sequence profile type, -http://edamontology.org/data_2131,Operating system name, -http://edamontology.org/data_2132,Mutation type, -http://edamontology.org/data_2133,Logical operator, -http://edamontology.org/data_2134,Results sort order, -http://edamontology.org/data_2135,Toggle, -http://edamontology.org/data_2136,Sequence width, -http://edamontology.org/data_2137,Gap penalty, -http://edamontology.org/data_2139,Nucleic acid melting temperature, -http://edamontology.org/data_2140,Concentration, -http://edamontology.org/data_2141,Window step size, -http://edamontology.org/data_2142,EMBOSS graph, -http://edamontology.org/data_2143,EMBOSS report, -http://edamontology.org/data_2145,Sequence offset, -http://edamontology.org/data_2146,Threshold, -http://edamontology.org/data_2147,Protein report (transcription factor), -http://edamontology.org/data_2149,Database category name, -http://edamontology.org/data_2150,Sequence profile name, -http://edamontology.org/data_2151,Color, -http://edamontology.org/data_2152,Rendering parameter, -http://edamontology.org/data_2154,Sequence name, -http://edamontology.org/data_2156,Date, -http://edamontology.org/data_2157,Word composition, -http://edamontology.org/data_2160,Fickett testcode plot, -http://edamontology.org/data_2161,Sequence similarity plot, -http://edamontology.org/data_2162,Helical wheel, -http://edamontology.org/data_2163,Helical net, -http://edamontology.org/data_2164,Protein sequence properties plot, -http://edamontology.org/data_2165,Protein ionisation curve, -http://edamontology.org/data_2166,Sequence composition plot, -http://edamontology.org/data_2167,Nucleic acid density plot, -http://edamontology.org/data_2168,Sequence trace image, -http://edamontology.org/data_2169,Nucleic acid features (siRNA), -http://edamontology.org/data_2173,Sequence set (stream), -http://edamontology.org/data_2174,FlyBase secondary identifier, -http://edamontology.org/data_2176,Cardinality, -http://edamontology.org/data_2177,Exactly 1, -http://edamontology.org/data_2178,1 or more, -http://edamontology.org/data_2179,Exactly 2, -http://edamontology.org/data_2180,2 or more, -http://edamontology.org/data_2190,Sequence checksum, -http://edamontology.org/data_2191,Protein features report (chemical modifications), -http://edamontology.org/data_2192,Error, -http://edamontology.org/data_2193,Database entry metadata, -http://edamontology.org/data_2198,Gene cluster, -http://edamontology.org/data_2201,Sequence record full, -http://edamontology.org/data_2208,Plasmid identifier, -http://edamontology.org/data_2209,Mutation ID, -http://edamontology.org/data_2212,Mutation annotation (basic), -http://edamontology.org/data_2213,Mutation annotation (prevalence), -http://edamontology.org/data_2214,Mutation annotation (prognostic), -http://edamontology.org/data_2215,Mutation annotation (functional), -http://edamontology.org/data_2216,Codon number, -http://edamontology.org/data_2217,Tumor annotation, -http://edamontology.org/data_2218,Server metadata, -http://edamontology.org/data_2219,Database field name, -http://edamontology.org/data_2220,Sequence cluster ID (SYSTERS), -http://edamontology.org/data_2223,Ontology metadata, -http://edamontology.org/data_2235,Raw SCOP domain classification, -http://edamontology.org/data_2236,Raw CATH domain classification, -http://edamontology.org/data_2240,Heterogen annotation, -http://edamontology.org/data_2242,Phylogenetic property values, -http://edamontology.org/data_2245,Sequence set (bootstrapped), -http://edamontology.org/data_2247,Phylogenetic consensus tree, -http://edamontology.org/data_2248,Schema, -http://edamontology.org/data_2249,DTD, -http://edamontology.org/data_2250,XML Schema, -http://edamontology.org/data_2251,Relax-NG schema, -http://edamontology.org/data_2252,XSLT stylesheet, -http://edamontology.org/data_2253,Data resource definition name, -http://edamontology.org/data_2254,OBO file format name, -http://edamontology.org/data_2285,Gene ID (MIPS), -http://edamontology.org/data_2288,Sequence identifier (protein), -http://edamontology.org/data_2289,Sequence identifier (nucleic acid), -http://edamontology.org/data_2290,EMBL accession, -http://edamontology.org/data_2291,UniProt ID, -http://edamontology.org/data_2292,GenBank accession, -http://edamontology.org/data_2293,Gramene secondary identifier, -http://edamontology.org/data_2294,Sequence variation ID, -http://edamontology.org/data_2295,Gene ID, -http://edamontology.org/data_2296,Gene name (AceView), -http://edamontology.org/data_2297,Gene ID (ECK), -http://edamontology.org/data_2298,Gene ID (HGNC), -http://edamontology.org/data_2299,Gene name, -http://edamontology.org/data_2300,Gene name (NCBI), -http://edamontology.org/data_2301,SMILES string, -http://edamontology.org/data_2302,STRING ID, -http://edamontology.org/data_2307,Virus annotation, -http://edamontology.org/data_2308,Virus annotation (taxonomy), -http://edamontology.org/data_2309,Reaction ID (SABIO-RK), -http://edamontology.org/data_2313,Carbohydrate report, -http://edamontology.org/data_2314,GI number, -http://edamontology.org/data_2315,NCBI version, -http://edamontology.org/data_2316,Cell line name, -http://edamontology.org/data_2317,Cell line name (exact), -http://edamontology.org/data_2318,Cell line name (truncated), -http://edamontology.org/data_2319,Cell line name (no punctuation), -http://edamontology.org/data_2320,Cell line name (assonant), -http://edamontology.org/data_2321,Enzyme ID, -http://edamontology.org/data_2325,REBASE enzyme number, -http://edamontology.org/data_2326,DrugBank ID, -http://edamontology.org/data_2327,GI number (protein), -http://edamontology.org/data_2335,Bit score, -http://edamontology.org/data_2336,Translation phase specification, -http://edamontology.org/data_2337,Resource metadata, -http://edamontology.org/data_2338,Ontology identifier, -http://edamontology.org/data_2339,Ontology concept name, -http://edamontology.org/data_2340,Genome build identifier, -http://edamontology.org/data_2342,Pathway or network name, -http://edamontology.org/data_2343,Pathway ID (KEGG), -http://edamontology.org/data_2344,Pathway ID (NCI-Nature), -http://edamontology.org/data_2345,Pathway ID (ConsensusPathDB), -http://edamontology.org/data_2346,Sequence cluster ID (UniRef), -http://edamontology.org/data_2347,Sequence cluster ID (UniRef100), -http://edamontology.org/data_2348,Sequence cluster ID (UniRef90), -http://edamontology.org/data_2349,Sequence cluster ID (UniRef50), -http://edamontology.org/data_2353,Ontology data, -http://edamontology.org/data_2354,RNA family report, -http://edamontology.org/data_2355,RNA family identifier, -http://edamontology.org/data_2356,RFAM accession, -http://edamontology.org/data_2357,Protein signature type, -http://edamontology.org/data_2358,Domain-nucleic acid interaction report, -http://edamontology.org/data_2359,Domain-domain interactions, -http://edamontology.org/data_2360,Domain-domain interaction (indirect), -http://edamontology.org/data_2362,Sequence accession (hybrid), -http://edamontology.org/data_2363,2D PAGE data, -http://edamontology.org/data_2364,2D PAGE report, -http://edamontology.org/data_2365,Pathway or network accession, -http://edamontology.org/data_2366,Secondary structure alignment, -http://edamontology.org/data_2367,ASTD ID, -http://edamontology.org/data_2368,ASTD ID (exon), -http://edamontology.org/data_2369,ASTD ID (intron), -http://edamontology.org/data_2370,ASTD ID (polya), -http://edamontology.org/data_2371,ASTD ID (tss), -http://edamontology.org/data_2372,2D PAGE spot report, -http://edamontology.org/data_2373,Spot ID, -http://edamontology.org/data_2374,Spot serial number, -http://edamontology.org/data_2375,Spot ID (HSC-2DPAGE), -http://edamontology.org/data_2378,Protein-motif interaction, -http://edamontology.org/data_2379,Strain identifier, -http://edamontology.org/data_2380,CABRI accession, -http://edamontology.org/data_2381,Experiment report (genotyping), -http://edamontology.org/data_2382,Genotype experiment ID, -http://edamontology.org/data_2383,EGA accession, -http://edamontology.org/data_2384,IPI protein ID, -http://edamontology.org/data_2385,RefSeq accession (protein), -http://edamontology.org/data_2386,EPD ID, -http://edamontology.org/data_2387,TAIR accession, -http://edamontology.org/data_2388,TAIR accession (At gene), -http://edamontology.org/data_2389,UniSTS accession, -http://edamontology.org/data_2390,UNITE accession, -http://edamontology.org/data_2391,UTR accession, -http://edamontology.org/data_2392,UniParc accession, -http://edamontology.org/data_2393,mFLJ/mKIAA number, -http://edamontology.org/data_2395,Fungi annotation, -http://edamontology.org/data_2396,Fungi annotation (anamorph), -http://edamontology.org/data_2398,Ensembl protein ID, -http://edamontology.org/data_2400,Toxin annotation, -http://edamontology.org/data_2401,Protein report (membrane protein), -http://edamontology.org/data_2402,Protein-drug interaction report, -http://edamontology.org/data_2522,Map data, -http://edamontology.org/data_2523,Phylogenetic data, -http://edamontology.org/data_2524,Protein data, -http://edamontology.org/data_2525,Nucleic acid data, -http://edamontology.org/data_2526,Text data, -http://edamontology.org/data_2527,Parameter, -http://edamontology.org/data_2528,Molecular data, -http://edamontology.org/data_2529,Molecule report, -http://edamontology.org/data_2530,Organism report, -http://edamontology.org/data_2531,Protocol, -http://edamontology.org/data_2534,Sequence attribute, -http://edamontology.org/data_2535,Sequence tag profile, -http://edamontology.org/data_2536,Mass spectrometry data, -http://edamontology.org/data_2537,Protein structure raw data, -http://edamontology.org/data_2538,Mutation identifier, -http://edamontology.org/data_2539,Alignment data, -http://edamontology.org/data_2540,Data index data, -http://edamontology.org/data_2563,Amino acid name (single letter), -http://edamontology.org/data_2564,Amino acid name (three letter), -http://edamontology.org/data_2565,Amino acid name (full name), -http://edamontology.org/data_2576,Toxin identifier, -http://edamontology.org/data_2578,ArachnoServer ID, -http://edamontology.org/data_2579,Expressed gene list, -http://edamontology.org/data_2580,BindingDB Monomer ID, -http://edamontology.org/data_2581,GO concept name, -http://edamontology.org/data_2582,GO concept ID (biological process), -http://edamontology.org/data_2583,GO concept ID (molecular function), -http://edamontology.org/data_2584,GO concept name (cellular component), -http://edamontology.org/data_2586,Northern blot image, -http://edamontology.org/data_2587,Blot ID, -http://edamontology.org/data_2588,BlotBase blot ID, -http://edamontology.org/data_2589,Hierarchy, -http://edamontology.org/data_2590,Hierarchy identifier, -http://edamontology.org/data_2591,Brite hierarchy ID, -http://edamontology.org/data_2592,Cancer type, -http://edamontology.org/data_2593,BRENDA organism ID, -http://edamontology.org/data_2594,UniGene taxon, -http://edamontology.org/data_2595,UTRdb taxon, -http://edamontology.org/data_2596,Catalogue ID, -http://edamontology.org/data_2597,CABRI catalogue name, -http://edamontology.org/data_2598,Secondary structure alignment metadata, -http://edamontology.org/data_2599,Molecule interaction report, -http://edamontology.org/data_2600,Pathway or network, -http://edamontology.org/data_2601,Small molecule data, -http://edamontology.org/data_2602,Genotype and phenotype data, -http://edamontology.org/data_2603,Expression data, -http://edamontology.org/data_2605,Compound ID (KEGG), -http://edamontology.org/data_2606,RFAM name, -http://edamontology.org/data_2608,Reaction ID (KEGG), -http://edamontology.org/data_2609,Drug ID (KEGG), -http://edamontology.org/data_2610,Ensembl ID, -http://edamontology.org/data_2611,ICD identifier, -http://edamontology.org/data_2612,Sequence cluster ID (CluSTr), -http://edamontology.org/data_2613,KEGG Glycan ID, -http://edamontology.org/data_2614,TCDB ID, -http://edamontology.org/data_2615,MINT ID, -http://edamontology.org/data_2616,DIP ID, -http://edamontology.org/data_2617,Signaling Gateway protein ID, -http://edamontology.org/data_2618,Protein modification ID, -http://edamontology.org/data_2619,RESID ID, -http://edamontology.org/data_2620,RGD ID, -http://edamontology.org/data_2621,TAIR accession (protein), -http://edamontology.org/data_2622,Compound ID (HMDB), -http://edamontology.org/data_2625,LIPID MAPS ID, -http://edamontology.org/data_2626,PeptideAtlas ID, -http://edamontology.org/data_2627,Molecular interaction ID, -http://edamontology.org/data_2628,BioGRID interaction ID, -http://edamontology.org/data_2629,Enzyme ID (MEROPS), -http://edamontology.org/data_2630,Mobile genetic element ID, -http://edamontology.org/data_2631,ACLAME ID, -http://edamontology.org/data_2632,SGD ID, -http://edamontology.org/data_2633,Book ID, -http://edamontology.org/data_2634,ISBN, -http://edamontology.org/data_2635,Compound ID (3DMET), -http://edamontology.org/data_2636,MatrixDB interaction ID, -http://edamontology.org/data_2637,cPath ID, -http://edamontology.org/data_2638,PubChem bioassay ID, -http://edamontology.org/data_2639,PubChem ID, -http://edamontology.org/data_2641,Reaction ID (MACie), -http://edamontology.org/data_2642,Gene ID (miRBase), -http://edamontology.org/data_2643,Gene ID (ZFIN), -http://edamontology.org/data_2644,Reaction ID (Rhea), -http://edamontology.org/data_2645,Pathway ID (Unipathway), -http://edamontology.org/data_2646,Compound ID (ChEMBL), -http://edamontology.org/data_2647,LGICdb identifier, -http://edamontology.org/data_2648,Reaction kinetics ID (SABIO-RK), -http://edamontology.org/data_2649,PharmGKB ID, -http://edamontology.org/data_2650,Pathway ID (PharmGKB), -http://edamontology.org/data_2651,Disease ID (PharmGKB), -http://edamontology.org/data_2652,Drug ID (PharmGKB), -http://edamontology.org/data_2653,Drug ID (TTD), -http://edamontology.org/data_2654,Target ID (TTD), -http://edamontology.org/data_2655,Cell type identifier, -http://edamontology.org/data_2656,NeuronDB ID, -http://edamontology.org/data_2657,NeuroMorpho ID, -http://edamontology.org/data_2658,Compound ID (ChemIDplus), -http://edamontology.org/data_2659,Pathway ID (SMPDB), -http://edamontology.org/data_2660,BioNumbers ID, -http://edamontology.org/data_2662,T3DB ID, -http://edamontology.org/data_2663,Carbohydrate identifier, -http://edamontology.org/data_2664,GlycomeDB ID, -http://edamontology.org/data_2665,LipidBank ID, -http://edamontology.org/data_2666,CDD ID, -http://edamontology.org/data_2667,MMDB ID, -http://edamontology.org/data_2668,iRefIndex ID, -http://edamontology.org/data_2669,ModelDB ID, -http://edamontology.org/data_2670,Pathway ID (DQCS), -http://edamontology.org/data_2671,Ensembl ID (Homo sapiens), -http://edamontology.org/data_2672,Ensembl ID ('Bos taurus'), -http://edamontology.org/data_2673,Ensembl ID ('Canis familiaris'), -http://edamontology.org/data_2674,Ensembl ID ('Cavia porcellus'), -http://edamontology.org/data_2675,Ensembl ID ('Ciona intestinalis'), -http://edamontology.org/data_2676,Ensembl ID ('Ciona savignyi'), -http://edamontology.org/data_2677,Ensembl ID ('Danio rerio'), -http://edamontology.org/data_2678,Ensembl ID ('Dasypus novemcinctus'), -http://edamontology.org/data_2679,Ensembl ID ('Echinops telfairi'), -http://edamontology.org/data_2680,Ensembl ID ('Erinaceus europaeus'), -http://edamontology.org/data_2681,Ensembl ID ('Felis catus'), -http://edamontology.org/data_2682,Ensembl ID ('Gallus gallus'), -http://edamontology.org/data_2683,Ensembl ID ('Gasterosteus aculeatus'), -http://edamontology.org/data_2684,Ensembl ID ('Homo sapiens'), -http://edamontology.org/data_2685,Ensembl ID ('Loxodonta africana'), -http://edamontology.org/data_2686,Ensembl ID ('Macaca mulatta'), -http://edamontology.org/data_2687,Ensembl ID ('Monodelphis domestica'), -http://edamontology.org/data_2688,Ensembl ID ('Mus musculus'), -http://edamontology.org/data_2689,Ensembl ID ('Myotis lucifugus'), -http://edamontology.org/data_2690,"Ensembl ID (""Ornithorhynchus anatinus\"")", -http://edamontology.org/data_2691,Ensembl ID ('Oryctolagus cuniculus'), -http://edamontology.org/data_2692,Ensembl ID ('Oryzias latipes'), -http://edamontology.org/data_2693,Ensembl ID ('Otolemur garnettii'), -http://edamontology.org/data_2694,Ensembl ID ('Pan troglodytes'), -http://edamontology.org/data_2695,Ensembl ID ('Rattus norvegicus'), -http://edamontology.org/data_2696,Ensembl ID ('Spermophilus tridecemlineatus'), -http://edamontology.org/data_2697,Ensembl ID ('Takifugu rubripes'), -http://edamontology.org/data_2698,Ensembl ID ('Tupaia belangeri'), -http://edamontology.org/data_2699,Ensembl ID ('Xenopus tropicalis'), -http://edamontology.org/data_2700,CATH identifier, -http://edamontology.org/data_2701,CATH node ID (family), -http://edamontology.org/data_2702,Enzyme ID (CAZy), -http://edamontology.org/data_2704,Clone ID (IMAGE), -http://edamontology.org/data_2705,GO concept ID (cellular component), -http://edamontology.org/data_2706,Chromosome name (BioCyc), -http://edamontology.org/data_2709,CleanEx entry name, -http://edamontology.org/data_2710,CleanEx dataset code, -http://edamontology.org/data_2711,Genome report, -http://edamontology.org/data_2713,Protein ID (CORUM), -http://edamontology.org/data_2714,CDD PSSM-ID, -http://edamontology.org/data_2715,Protein ID (CuticleDB), -http://edamontology.org/data_2716,DBD ID, -http://edamontology.org/data_2717,Oligonucleotide probe annotation, -http://edamontology.org/data_2718,Oligonucleotide ID, -http://edamontology.org/data_2719,dbProbe ID, -http://edamontology.org/data_2720,Dinucleotide property, -http://edamontology.org/data_2721,DiProDB ID, -http://edamontology.org/data_2722,Protein features report (disordered structure), -http://edamontology.org/data_2723,Protein ID (DisProt), -http://edamontology.org/data_2724,Embryo report, -http://edamontology.org/data_2725,Ensembl transcript ID, -http://edamontology.org/data_2726,Inhibitor annotation, -http://edamontology.org/data_2727,Promoter ID, -http://edamontology.org/data_2728,EST accession, -http://edamontology.org/data_2729,COGEME EST ID, -http://edamontology.org/data_2730,COGEME unisequence ID, -http://edamontology.org/data_2731,Protein family ID (GeneFarm), -http://edamontology.org/data_2732,Family name, -http://edamontology.org/data_2733,Genus name (virus), -http://edamontology.org/data_2734,Family name (virus), -http://edamontology.org/data_2735,Database name (SwissRegulon), -http://edamontology.org/data_2736,Sequence feature ID (SwissRegulon), -http://edamontology.org/data_2737,FIG ID, -http://edamontology.org/data_2738,Gene ID (Xenbase), -http://edamontology.org/data_2739,Gene ID (Genolist), -http://edamontology.org/data_2740,Gene name (Genolist), -http://edamontology.org/data_2741,ABS ID, -http://edamontology.org/data_2742,AraC-XylS ID, -http://edamontology.org/data_2743,Gene name (HUGO), -http://edamontology.org/data_2744,Locus ID (PseudoCAP), -http://edamontology.org/data_2745,Locus ID (UTR), -http://edamontology.org/data_2746,MonosaccharideDB ID, -http://edamontology.org/data_2747,Database name (CMD), -http://edamontology.org/data_2748,Database name (Osteogenesis), -http://edamontology.org/data_2749,Genome identifier, -http://edamontology.org/data_2751,GenomeReviews ID, -http://edamontology.org/data_2752,GlycoMap ID, -http://edamontology.org/data_2753,Carbohydrate conformational map, -http://edamontology.org/data_2755,Transcription factor name, -http://edamontology.org/data_2756,TCID, -http://edamontology.org/data_2757,Pfam domain name, -http://edamontology.org/data_2758,Pfam clan ID, -http://edamontology.org/data_2759,Gene ID (VectorBase), -http://edamontology.org/data_2761,UTRSite ID, -http://edamontology.org/data_2762,Sequence signature report, -http://edamontology.org/data_2763,Locus annotation, -http://edamontology.org/data_2764,Protein name (UniProt), -http://edamontology.org/data_2765,Term ID list, -http://edamontology.org/data_2766,HAMAP ID, -http://edamontology.org/data_2767,Identifier with metadata, -http://edamontology.org/data_2768,Gene symbol annotation, -http://edamontology.org/data_2769,Transcript ID, -http://edamontology.org/data_2770,HIT ID, -http://edamontology.org/data_2771,HIX ID, -http://edamontology.org/data_2772,HPA antibody id, -http://edamontology.org/data_2773,IMGT/HLA ID, -http://edamontology.org/data_2774,Gene ID (JCVI), -http://edamontology.org/data_2775,Kinase name, -http://edamontology.org/data_2776,ConsensusPathDB entity ID, -http://edamontology.org/data_2777,ConsensusPathDB entity name, -http://edamontology.org/data_2778,CCAP strain number, -http://edamontology.org/data_2779,Stock number, -http://edamontology.org/data_2780,Stock number (TAIR), -http://edamontology.org/data_2781,REDIdb ID, -http://edamontology.org/data_2782,SMART domain name, -http://edamontology.org/data_2783,Protein family ID (PANTHER), -http://edamontology.org/data_2784,RNAVirusDB ID, -http://edamontology.org/data_2785,Virus ID, -http://edamontology.org/data_2786,NCBI Genome Project ID, -http://edamontology.org/data_2787,NCBI genome accession, -http://edamontology.org/data_2788,Sequence profile data, -http://edamontology.org/data_2789,Protein ID (TopDB), -http://edamontology.org/data_2790,Gel ID, -http://edamontology.org/data_2791,Reference map name (SWISS-2DPAGE), -http://edamontology.org/data_2792,Protein ID (PeroxiBase), -http://edamontology.org/data_2793,SISYPHUS ID, -http://edamontology.org/data_2794,ORF ID, -http://edamontology.org/data_2795,ORF identifier, -http://edamontology.org/data_2796,Linucs ID, -http://edamontology.org/data_2797,Protein ID (LGICdb), -http://edamontology.org/data_2798,MaizeDB ID, -http://edamontology.org/data_2799,Gene ID (MfunGD), -http://edamontology.org/data_2800,Orpha number, -http://edamontology.org/data_2802,Protein ID (EcID), -http://edamontology.org/data_2803,Clone ID (RefSeq), -http://edamontology.org/data_2804,Protein ID (ConoServer), -http://edamontology.org/data_2805,GeneSNP ID, -http://edamontology.org/data_2812,Lipid identifier, -http://edamontology.org/data_2831,Databank, -http://edamontology.org/data_2832,Web portal, -http://edamontology.org/data_2835,Gene ID (VBASE2), -http://edamontology.org/data_2836,DPVweb ID, -http://edamontology.org/data_2837,Pathway ID (BioSystems), -http://edamontology.org/data_2838,Experimental data (proteomics), -http://edamontology.org/data_2849,Abstract, -http://edamontology.org/data_2850,Lipid structure, -http://edamontology.org/data_2851,Drug structure, -http://edamontology.org/data_2852,Toxin structure, -http://edamontology.org/data_2854,Position-specific scoring matrix, -http://edamontology.org/data_2855,Distance matrix, -http://edamontology.org/data_2856,Structural distance matrix, -http://edamontology.org/data_2857,Article metadata, -http://edamontology.org/data_2858,Ontology concept, -http://edamontology.org/data_2865,Codon usage bias, -http://edamontology.org/data_2866,Northern blot report, -http://edamontology.org/data_2870,Radiation hybrid map, -http://edamontology.org/data_2872,ID list, -http://edamontology.org/data_2873,Phylogenetic gene frequencies data, -http://edamontology.org/data_2874,Sequence set (polymorphic), -http://edamontology.org/data_2875,DRCAT resource, -http://edamontology.org/data_2877,Protein complex, -http://edamontology.org/data_2878,Protein structural motif, -http://edamontology.org/data_2879,Lipid report, -http://edamontology.org/data_2880,Secondary structure image, -http://edamontology.org/data_2881,Secondary structure report, -http://edamontology.org/data_2882,DNA features, -http://edamontology.org/data_2883,RNA features report, -http://edamontology.org/data_2884,Plot, -http://edamontology.org/data_2886,Protein sequence record, -http://edamontology.org/data_2887,Nucleic acid sequence record, -http://edamontology.org/data_2888,Protein sequence record (full), -http://edamontology.org/data_2889,Nucleic acid sequence record (full), -http://edamontology.org/data_2891,Biological model accession, -http://edamontology.org/data_2892,Cell type name, -http://edamontology.org/data_2893,Cell type accession, -http://edamontology.org/data_2894,Compound accession, -http://edamontology.org/data_2895,Drug accession, -http://edamontology.org/data_2896,Toxin name, -http://edamontology.org/data_2897,Toxin accession, -http://edamontology.org/data_2898,Monosaccharide accession, -http://edamontology.org/data_2899,Drug name, -http://edamontology.org/data_2900,Carbohydrate accession, -http://edamontology.org/data_2901,Molecule accession, -http://edamontology.org/data_2902,Data resource definition accession, -http://edamontology.org/data_2903,Genome accession, -http://edamontology.org/data_2904,Map accession, -http://edamontology.org/data_2905,Lipid accession, -http://edamontology.org/data_2906,Peptide ID, -http://edamontology.org/data_2907,Protein accession, -http://edamontology.org/data_2908,Organism accession, -http://edamontology.org/data_2909,Organism name, -http://edamontology.org/data_2910,Protein family accession, -http://edamontology.org/data_2911,Transcription factor accession, -http://edamontology.org/data_2912,Strain accession, -http://edamontology.org/data_2913,Virus identifier, -http://edamontology.org/data_2914,Sequence features metadata, -http://edamontology.org/data_2915,Gramene identifier, -http://edamontology.org/data_2916,DDBJ accession, -http://edamontology.org/data_2917,ConsensusPathDB identifier, -http://edamontology.org/data_2925,Sequence data, -http://edamontology.org/data_2927,Codon usage, -http://edamontology.org/data_2954,Article report, -http://edamontology.org/data_2955,Sequence report, -http://edamontology.org/data_2956,Protein secondary structure, -http://edamontology.org/data_2957,Hopp and Woods plot, -http://edamontology.org/data_2958,Nucleic acid melting curve, -http://edamontology.org/data_2959,Nucleic acid probability profile, -http://edamontology.org/data_2960,Nucleic acid temperature profile, -http://edamontology.org/data_2961,Gene regulatory network report, -http://edamontology.org/data_2965,2D PAGE gel report, -http://edamontology.org/data_2966,Oligonucleotide probe sets annotation, -http://edamontology.org/data_2967,Microarray image, -http://edamontology.org/data_2968,Image, -http://edamontology.org/data_2969,Sequence image, -http://edamontology.org/data_2970,Protein hydropathy data, -http://edamontology.org/data_2971,Workflow data, -http://edamontology.org/data_2972,Workflow, -http://edamontology.org/data_2973,Secondary structure data, -http://edamontology.org/data_2974,Protein sequence (raw), -http://edamontology.org/data_2975,Nucleic acid sequence (raw), -http://edamontology.org/data_2976,Protein sequence, -http://edamontology.org/data_2977,Nucleic acid sequence, -http://edamontology.org/data_2978,Reaction data, -http://edamontology.org/data_2979,Peptide property, -http://edamontology.org/data_2980,Protein classification, -http://edamontology.org/data_2981,Sequence motif data, -http://edamontology.org/data_2982,Sequence profile data, -http://edamontology.org/data_2983,Pathway or network data, -http://edamontology.org/data_2984,Pathway or network report, -http://edamontology.org/data_2985,Nucleic acid thermodynamic data, -http://edamontology.org/data_2986,Nucleic acid classification, -http://edamontology.org/data_2987,Classification report, -http://edamontology.org/data_2989,Protein features report (key folding sites), -http://edamontology.org/data_2991,Protein geometry data, -http://edamontology.org/data_2992,Protein structure image, -http://edamontology.org/data_2994,Phylogenetic character weights, -http://edamontology.org/data_3002,Annotation track, -http://edamontology.org/data_3021,UniProt accession, -http://edamontology.org/data_3022,NCBI genetic code ID, -http://edamontology.org/data_3025,Ontology concept identifier, -http://edamontology.org/data_3026,GO concept name (biological process), -http://edamontology.org/data_3027,GO concept name (molecular function), -http://edamontology.org/data_3028,Taxonomy, -http://edamontology.org/data_3029,Protein ID (EMBL/GenBank/DDBJ), -http://edamontology.org/data_3031,Core data, -http://edamontology.org/data_3034,Sequence feature identifier, -http://edamontology.org/data_3035,Structure identifier, -http://edamontology.org/data_3036,Matrix identifier, -http://edamontology.org/data_3085,Protein sequence composition, -http://edamontology.org/data_3086,Nucleic acid sequence composition (report), -http://edamontology.org/data_3101,Protein domain classification node, -http://edamontology.org/data_3102,CAS number, -http://edamontology.org/data_3103,ATC code, -http://edamontology.org/data_3104,UNII, -http://edamontology.org/data_3105,Geotemporal metadata, -http://edamontology.org/data_3106,System metadata, -http://edamontology.org/data_3107,Sequence feature name, -http://edamontology.org/data_3108,Experimental measurement, -http://edamontology.org/data_3110,Raw microarray data, -http://edamontology.org/data_3111,Processed microarray data, -http://edamontology.org/data_3112,Gene expression matrix, -http://edamontology.org/data_3113,Sample annotation, -http://edamontology.org/data_3115,Microarray metadata, -http://edamontology.org/data_3116,Microarray protocol annotation, -http://edamontology.org/data_3117,Microarray hybridisation data, -http://edamontology.org/data_3119,Sequence features (compositionally-biased regions), -http://edamontology.org/data_3122,Nucleic acid features (difference and change), -http://edamontology.org/data_3128,Nucleic acid structure report, -http://edamontology.org/data_3129,Protein features report (repeats), -http://edamontology.org/data_3130,Sequence motif matches (protein), -http://edamontology.org/data_3131,Sequence motif matches (nucleic acid), -http://edamontology.org/data_3132,Nucleic acid features (d-loop), -http://edamontology.org/data_3133,Nucleic acid features (stem loop), -http://edamontology.org/data_3134,Gene transcript report, -http://edamontology.org/data_3137,Non-coding RNA, -http://edamontology.org/data_3138,Transcriptional features (report), -http://edamontology.org/data_3140,Nucleic acid features (immunoglobulin gene structure), -http://edamontology.org/data_3141,SCOP class, -http://edamontology.org/data_3142,SCOP fold, -http://edamontology.org/data_3143,SCOP superfamily, -http://edamontology.org/data_3144,SCOP family, -http://edamontology.org/data_3145,SCOP protein, -http://edamontology.org/data_3146,SCOP species, -http://edamontology.org/data_3147,Mass spectrometry experiment, -http://edamontology.org/data_3148,Gene family report, -http://edamontology.org/data_3153,Protein image, -http://edamontology.org/data_3154,Protein alignment, -http://edamontology.org/data_3165,NGS experiment, -http://edamontology.org/data_3181,Sequence assembly report, -http://edamontology.org/data_3210,Genome index, -http://edamontology.org/data_3231,GWAS report, -http://edamontology.org/data_3236,Cytoband position, -http://edamontology.org/data_3238,Cell type ontology ID, -http://edamontology.org/data_3241,Kinetic model, -http://edamontology.org/data_3264,COSMIC ID, -http://edamontology.org/data_3265,HGMD ID, -http://edamontology.org/data_3266,Sequence assembly ID, -http://edamontology.org/data_3268,Sequence feature type, -http://edamontology.org/data_3269,Gene homology (report), -http://edamontology.org/data_3270,Ensembl gene tree ID, -http://edamontology.org/data_3271,Gene tree, -http://edamontology.org/data_3272,Species tree, -http://edamontology.org/data_3273,Sample ID, -http://edamontology.org/data_3274,MGI accession, -http://edamontology.org/data_3275,Phenotype name, -http://edamontology.org/data_3354,Transition matrix, -http://edamontology.org/data_3355,Emission matrix, -http://edamontology.org/data_3356,Hidden Markov model, -http://edamontology.org/data_3358,Format identifier, -http://edamontology.org/data_3424,Raw image, -http://edamontology.org/data_3425,Carbohydrate property, -http://edamontology.org/data_3426,Proteomics experiment report, -http://edamontology.org/data_3427,RNAi report, -http://edamontology.org/data_3428,Simulation experiment report, -http://edamontology.org/data_3442,MRI image, -http://edamontology.org/data_3449,Cell migration track image, -http://edamontology.org/data_3451,Rate of association, -http://edamontology.org/data_3479,Gene order, -http://edamontology.org/data_3483,Spectrum, -http://edamontology.org/data_3488,NMR spectrum, -http://edamontology.org/data_3490,Chemical structure sketch, -http://edamontology.org/data_3492,Nucleic acid signature, -http://edamontology.org/data_3494,DNA sequence, -http://edamontology.org/data_3495,RNA sequence, -http://edamontology.org/data_3496,RNA sequence (raw), -http://edamontology.org/data_3497,DNA sequence (raw), -http://edamontology.org/data_3498,Sequence variations, -http://edamontology.org/data_3505,Bibliography, -http://edamontology.org/data_3509,Ontology mapping, -http://edamontology.org/data_3546,Image metadata, -http://edamontology.org/data_3558,Clinical trial report, -http://edamontology.org/data_3567,Reference sample report, -http://edamontology.org/data_3568,Gene Expression Atlas Experiment ID, -http://edamontology.org/data_3667,Disease identifier, -http://edamontology.org/data_3668,Disease name, -http://edamontology.org/data_3669,Training material, -http://edamontology.org/data_3670,Online course, -http://edamontology.org/data_3671,Text, -http://edamontology.org/data_3707,Biodiversity data, -http://edamontology.org/data_3716,Biosafety report, -http://edamontology.org/data_3717,Isolation report, -http://edamontology.org/data_3718,Pathogenicity report, -http://edamontology.org/data_3719,Biosafety classification, -http://edamontology.org/data_3720,Geographic location, -http://edamontology.org/data_3721,Isolation source, -http://edamontology.org/data_3722,Physiology parameter, -http://edamontology.org/data_3723,Morphology parameter, -http://edamontology.org/data_3724,Cultivation parameter, -http://edamontology.org/data_3732,Sequencing metadata name, -http://edamontology.org/data_3733,Flow cell identifier, -http://edamontology.org/data_3734,Lane identifier, -http://edamontology.org/data_3735,Run number, -http://edamontology.org/data_3736,Ecological data, -http://edamontology.org/data_3737,Alpha diversity data, -http://edamontology.org/data_3738,Beta diversity data, -http://edamontology.org/data_3739,Gamma diversity data, -http://edamontology.org/data_3743,Ordination plot, -http://edamontology.org/data_3753,Over-representation data, -http://edamontology.org/data_3754,GO-term enrichment data, -http://edamontology.org/data_3756,Localisation score, -http://edamontology.org/data_3757,Unimod ID, -http://edamontology.org/data_3759,ProteomeXchange ID, -http://edamontology.org/data_3768,Clustered expression profiles, -http://edamontology.org/data_3769,BRENDA ontology concept ID, -http://edamontology.org/data_3779,Annotated text, -http://edamontology.org/data_3786,Query script, -http://edamontology.org/data_3805,3D EM Map, -http://edamontology.org/data_3806,3D EM Mask, -http://edamontology.org/data_3807,EM Movie, -http://edamontology.org/data_3808,EM Micrograph, -http://edamontology.org/data_3842,Molecular simulation data, -http://edamontology.org/data_3856,RNA central ID, -http://edamontology.org/data_3861,Electronic health record, -http://edamontology.org/data_3869,Simulation, -http://edamontology.org/data_3870,Trajectory data, -http://edamontology.org/data_3871,Forcefield parameters, -http://edamontology.org/data_3872,Topology data, -http://edamontology.org/data_3905,Histogram, -http://edamontology.org/data_3914,Quality control report, -http://edamontology.org/data_3917,Count matrix, -http://edamontology.org/data_3924,DNA structure alignment, -http://edamontology.org/data_3932,Q-value, -http://edamontology.org/data_3949,Profile HMM, -http://edamontology.org/data_3952,Pathway ID (WikiPathways), -http://edamontology.org/data_3953,Pathway overrepresentation data, -http://edamontology.org/format_1196,SMILES, -http://edamontology.org/format_1197,InChI, -http://edamontology.org/format_1198,mf, -http://edamontology.org/format_1199,InChIKey, -http://edamontology.org/format_1200,smarts, -http://edamontology.org/format_1206,unambiguous pure, -http://edamontology.org/format_1207,nucleotide, -http://edamontology.org/format_1208,protein, -http://edamontology.org/format_1209,consensus, -http://edamontology.org/format_1210,pure nucleotide, -http://edamontology.org/format_1211,unambiguous pure nucleotide, -http://edamontology.org/format_1212,dna, -http://edamontology.org/format_1213,rna, -http://edamontology.org/format_1214,unambiguous pure dna, -http://edamontology.org/format_1215,pure dna, -http://edamontology.org/format_1216,unambiguous pure rna sequence, -http://edamontology.org/format_1217,pure rna, -http://edamontology.org/format_1218,unambiguous pure protein, -http://edamontology.org/format_1219,pure protein, -http://edamontology.org/format_1228,UniGene entry format, -http://edamontology.org/format_1247,COG sequence cluster format, -http://edamontology.org/format_1248,EMBL feature location, -http://edamontology.org/format_1295,quicktandem, -http://edamontology.org/format_1296,Sanger inverted repeats, -http://edamontology.org/format_1297,EMBOSS repeat, -http://edamontology.org/format_1316,est2genome format, -http://edamontology.org/format_1318,restrict format, -http://edamontology.org/format_1319,restover format, -http://edamontology.org/format_1320,REBASE restriction sites, -http://edamontology.org/format_1332,FASTA search results format, -http://edamontology.org/format_1333,BLAST results, -http://edamontology.org/format_1334,mspcrunch, -http://edamontology.org/format_1335,Smith-Waterman format, -http://edamontology.org/format_1336,dhf, -http://edamontology.org/format_1337,lhf, -http://edamontology.org/format_1341,InterPro hits format, -http://edamontology.org/format_1342,InterPro protein view report format, -http://edamontology.org/format_1343,InterPro match table format, -http://edamontology.org/format_1349,HMMER Dirichlet prior, -http://edamontology.org/format_1350,MEME Dirichlet prior, -http://edamontology.org/format_1351,HMMER emission and transition, -http://edamontology.org/format_1356,prosite-pattern, -http://edamontology.org/format_1357,EMBOSS sequence pattern, -http://edamontology.org/format_1360,meme-motif, -http://edamontology.org/format_1366,prosite-profile, -http://edamontology.org/format_1367,JASPAR format, -http://edamontology.org/format_1369,MEME background Markov model, -http://edamontology.org/format_1370,HMMER format, -http://edamontology.org/format_1391,HMMER-aln, -http://edamontology.org/format_1392,DIALIGN format, -http://edamontology.org/format_1393,daf, -http://edamontology.org/format_1419,Sequence-MEME profile alignment, -http://edamontology.org/format_1421,HMMER profile alignment (sequences versus HMMs), -http://edamontology.org/format_1422,HMMER profile alignment (HMM versus sequences), -http://edamontology.org/format_1423,Phylip distance matrix, -http://edamontology.org/format_1424,ClustalW dendrogram, -http://edamontology.org/format_1425,Phylip tree raw, -http://edamontology.org/format_1430,Phylip continuous quantitative characters, -http://edamontology.org/format_1431,Phylogenetic property values format, -http://edamontology.org/format_1432,Phylip character frequencies format, -http://edamontology.org/format_1433,Phylip discrete states format, -http://edamontology.org/format_1434,Phylip cliques format, -http://edamontology.org/format_1435,Phylip tree format, -http://edamontology.org/format_1436,TreeBASE format, -http://edamontology.org/format_1437,TreeFam format, -http://edamontology.org/format_1445,Phylip tree distance format, -http://edamontology.org/format_1454,dssp, -http://edamontology.org/format_1455,hssp, -http://edamontology.org/format_1457,Dot-bracket format, -http://edamontology.org/format_1458,Vienna local RNA secondary structure format, -http://edamontology.org/format_1475,PDB database entry format, -http://edamontology.org/format_1476,PDB, -http://edamontology.org/format_1477,mmCIF, -http://edamontology.org/format_1478,PDBML, -http://edamontology.org/format_1500,Domainatrix 3D-1D scoring matrix format, -http://edamontology.org/format_1504,aaindex, -http://edamontology.org/format_1511,IntEnz enzyme report format, -http://edamontology.org/format_1512,BRENDA enzyme report format, -http://edamontology.org/format_1513,KEGG REACTION enzyme report format, -http://edamontology.org/format_1514,KEGG ENZYME enzyme report format, -http://edamontology.org/format_1515,REBASE proto enzyme report format, -http://edamontology.org/format_1516,REBASE withrefm enzyme report format, -http://edamontology.org/format_1551,Pcons report format, -http://edamontology.org/format_1552,ProQ report format, -http://edamontology.org/format_1563,SMART domain assignment report format, -http://edamontology.org/format_1568,BIND entry format, -http://edamontology.org/format_1569,IntAct entry format, -http://edamontology.org/format_1570,InterPro entry format, -http://edamontology.org/format_1571,InterPro entry abstract format, -http://edamontology.org/format_1572,Gene3D entry format, -http://edamontology.org/format_1573,PIRSF entry format, -http://edamontology.org/format_1574,PRINTS entry format, -http://edamontology.org/format_1575,Panther Families and HMMs entry format, -http://edamontology.org/format_1576,Pfam entry format, -http://edamontology.org/format_1577,SMART entry format, -http://edamontology.org/format_1578,Superfamily entry format, -http://edamontology.org/format_1579,TIGRFam entry format, -http://edamontology.org/format_1580,ProDom entry format, -http://edamontology.org/format_1581,FSSP entry format, -http://edamontology.org/format_1582,findkm, -http://edamontology.org/format_1603,Ensembl gene report format, -http://edamontology.org/format_1604,DictyBase gene report format, -http://edamontology.org/format_1605,CGD gene report format, -http://edamontology.org/format_1606,DragonDB gene report format, -http://edamontology.org/format_1607,EcoCyc gene report format, -http://edamontology.org/format_1608,FlyBase gene report format, -http://edamontology.org/format_1609,Gramene gene report format, -http://edamontology.org/format_1610,KEGG GENES gene report format, -http://edamontology.org/format_1611,MaizeGDB gene report format, -http://edamontology.org/format_1612,MGD gene report format, -http://edamontology.org/format_1613,RGD gene report format, -http://edamontology.org/format_1614,SGD gene report format, -http://edamontology.org/format_1615,GeneDB gene report format, -http://edamontology.org/format_1616,TAIR gene report format, -http://edamontology.org/format_1617,WormBase gene report format, -http://edamontology.org/format_1618,ZFIN gene report format, -http://edamontology.org/format_1619,TIGR gene report format, -http://edamontology.org/format_1620,dbSNP polymorphism report format, -http://edamontology.org/format_1623,OMIM entry format, -http://edamontology.org/format_1624,HGVbase entry format, -http://edamontology.org/format_1625,HIVDB entry format, -http://edamontology.org/format_1626,KEGG DISEASE entry format, -http://edamontology.org/format_1627,Primer3 primer, -http://edamontology.org/format_1628,ABI, -http://edamontology.org/format_1629,mira, -http://edamontology.org/format_1630,CAF, -http://edamontology.org/format_1631,EXP, -http://edamontology.org/format_1632,SCF, -http://edamontology.org/format_1633,PHD, -http://edamontology.org/format_1637,dat, -http://edamontology.org/format_1638,cel, -http://edamontology.org/format_1639,affymetrix, -http://edamontology.org/format_1640,ArrayExpress entry format, -http://edamontology.org/format_1641,affymetrix-exp, -http://edamontology.org/format_1644,CHP, -http://edamontology.org/format_1645,EMDB entry format, -http://edamontology.org/format_1647,KEGG PATHWAY entry format, -http://edamontology.org/format_1648,MetaCyc entry format, -http://edamontology.org/format_1649,HumanCyc entry format, -http://edamontology.org/format_1650,INOH entry format, -http://edamontology.org/format_1651,PATIKA entry format, -http://edamontology.org/format_1652,Reactome entry format, -http://edamontology.org/format_1653,aMAZE entry format, -http://edamontology.org/format_1654,CPDB entry format, -http://edamontology.org/format_1655,Panther Pathways entry format, -http://edamontology.org/format_1665,Taverna workflow format, -http://edamontology.org/format_1666,BioModel mathematical model format, -http://edamontology.org/format_1697,KEGG LIGAND entry format, -http://edamontology.org/format_1698,KEGG COMPOUND entry format, -http://edamontology.org/format_1699,KEGG PLANT entry format, -http://edamontology.org/format_1700,KEGG GLYCAN entry format, -http://edamontology.org/format_1701,PubChem entry format, -http://edamontology.org/format_1702,ChemSpider entry format, -http://edamontology.org/format_1703,ChEBI entry format, -http://edamontology.org/format_1704,MSDchem ligand dictionary entry format, -http://edamontology.org/format_1705,HET group dictionary entry format, -http://edamontology.org/format_1706,KEGG DRUG entry format, -http://edamontology.org/format_1734,PubMed citation, -http://edamontology.org/format_1735,Medline Display Format, -http://edamontology.org/format_1736,CiteXplore-core, -http://edamontology.org/format_1737,CiteXplore-all, -http://edamontology.org/format_1739,pmc, -http://edamontology.org/format_1740,iHOP format, -http://edamontology.org/format_1741,OSCAR format, -http://edamontology.org/format_1747,PDB atom record format, -http://edamontology.org/format_1760,CATH chain report format, -http://edamontology.org/format_1761,CATH PDB report format, -http://edamontology.org/format_1782,NCBI gene report format, -http://edamontology.org/format_1808,GeneIlluminator gene report format, -http://edamontology.org/format_1809,BacMap gene card format, -http://edamontology.org/format_1810,ColiCard report format, -http://edamontology.org/format_1861,PlasMapper TextMap, -http://edamontology.org/format_1910,newick, -http://edamontology.org/format_1911,TreeCon format, -http://edamontology.org/format_1912,Nexus format, -http://edamontology.org/format_1915,Format, -http://edamontology.org/format_1918,Atomic data format, -http://edamontology.org/format_1919,Sequence record format, -http://edamontology.org/format_1920,Sequence feature annotation format, -http://edamontology.org/format_1921,Alignment format, -http://edamontology.org/format_1923,acedb, -http://edamontology.org/format_1924,clustal sequence format, -http://edamontology.org/format_1925,codata, -http://edamontology.org/format_1926,dbid, -http://edamontology.org/format_1927,EMBL format, -http://edamontology.org/format_1928,Staden experiment format, -http://edamontology.org/format_1929,FASTA, -http://edamontology.org/format_1930,FASTQ,fq|fastq -http://edamontology.org/format_1931,FASTQ-illumina, -http://edamontology.org/format_1932,FASTQ-sanger, -http://edamontology.org/format_1933,FASTQ-solexa, -http://edamontology.org/format_1934,fitch program, -http://edamontology.org/format_1935,GCG, -http://edamontology.org/format_1936,GenBank format, -http://edamontology.org/format_1937,genpept, -http://edamontology.org/format_1938,GFF2-seq, -http://edamontology.org/format_1939,GFF3-seq, -http://edamontology.org/format_1940,giFASTA format, -http://edamontology.org/format_1941,hennig86, -http://edamontology.org/format_1942,ig, -http://edamontology.org/format_1943,igstrict, -http://edamontology.org/format_1944,jackknifer, -http://edamontology.org/format_1945,mase format, -http://edamontology.org/format_1946,mega-seq, -http://edamontology.org/format_1947,GCG MSF, -http://edamontology.org/format_1948,nbrf/pir, -http://edamontology.org/format_1949,nexus-seq, -http://edamontology.org/format_1950,pdbatom, -http://edamontology.org/format_1951,pdbatomnuc, -http://edamontology.org/format_1952,pdbseqresnuc, -http://edamontology.org/format_1953,pdbseqres, -http://edamontology.org/format_1954,Pearson format, -http://edamontology.org/format_1955,phylip sequence format, -http://edamontology.org/format_1956,phylipnon sequence format, -http://edamontology.org/format_1957,raw, -http://edamontology.org/format_1958,refseqp, -http://edamontology.org/format_1959,selex sequence format, -http://edamontology.org/format_1960,Staden format, -http://edamontology.org/format_1961,Stockholm format, -http://edamontology.org/format_1962,strider format, -http://edamontology.org/format_1963,UniProtKB format, -http://edamontology.org/format_1964,plain text format (unformatted), -http://edamontology.org/format_1965,treecon sequence format, -http://edamontology.org/format_1966,ASN.1 sequence format, -http://edamontology.org/format_1967,DAS format, -http://edamontology.org/format_1968,dasdna, -http://edamontology.org/format_1969,debug-seq, -http://edamontology.org/format_1970,jackknifernon, -http://edamontology.org/format_1971,meganon sequence format, -http://edamontology.org/format_1972,NCBI format, -http://edamontology.org/format_1973,nexusnon, -http://edamontology.org/format_1974,GFF2, -http://edamontology.org/format_1975,GFF3, -http://edamontology.org/format_1976,pir, -http://edamontology.org/format_1977,swiss feature, -http://edamontology.org/format_1978,DASGFF, -http://edamontology.org/format_1979,debug-feat, -http://edamontology.org/format_1980,EMBL feature, -http://edamontology.org/format_1981,GenBank feature, -http://edamontology.org/format_1982,ClustalW format, -http://edamontology.org/format_1983,debug, -http://edamontology.org/format_1984,FASTA-aln, -http://edamontology.org/format_1985,markx0, -http://edamontology.org/format_1986,markx1, -http://edamontology.org/format_1987,markx10, -http://edamontology.org/format_1988,markx2, -http://edamontology.org/format_1989,markx3, -http://edamontology.org/format_1990,match, -http://edamontology.org/format_1991,mega, -http://edamontology.org/format_1992,meganon, -http://edamontology.org/format_1993,msf alignment format, -http://edamontology.org/format_1994,nexus alignment format, -http://edamontology.org/format_1995,nexusnon alignment format, -http://edamontology.org/format_1996,pair, -http://edamontology.org/format_1997,PHYLIP format, -http://edamontology.org/format_1998,PHYLIP sequential, -http://edamontology.org/format_1999,scores format, -http://edamontology.org/format_2000,selex, -http://edamontology.org/format_2001,EMBOSS simple format, -http://edamontology.org/format_2002,srs format, -http://edamontology.org/format_2003,srspair, -http://edamontology.org/format_2004,T-Coffee format, -http://edamontology.org/format_2005,TreeCon-seq, -http://edamontology.org/format_2006,Phylogenetic tree format, -http://edamontology.org/format_2013,Biological pathway or network format, -http://edamontology.org/format_2014,Sequence-profile alignment format, -http://edamontology.org/format_2015,Sequence-profile alignment (HMM) format, -http://edamontology.org/format_2017,Amino acid index format, -http://edamontology.org/format_2020,Article format, -http://edamontology.org/format_2021,Text mining report format, -http://edamontology.org/format_2027,Enzyme kinetics report format, -http://edamontology.org/format_2030,Chemical data format, -http://edamontology.org/format_2031,Gene annotation format, -http://edamontology.org/format_2032,Workflow format, -http://edamontology.org/format_2033,Tertiary structure format, -http://edamontology.org/format_2034,Biological model format, -http://edamontology.org/format_2035,Chemical formula format, -http://edamontology.org/format_2036,Phylogenetic character data format, -http://edamontology.org/format_2037,Phylogenetic continuous quantitative character format, -http://edamontology.org/format_2038,Phylogenetic discrete states format, -http://edamontology.org/format_2039,Phylogenetic tree report (cliques) format, -http://edamontology.org/format_2040,Phylogenetic tree report (invariants) format, -http://edamontology.org/format_2045,Electron microscopy model format, -http://edamontology.org/format_2049,Phylogenetic tree report (tree distances) format, -http://edamontology.org/format_2051,Polymorphism report format, -http://edamontology.org/format_2052,Protein family report format, -http://edamontology.org/format_2054,Protein interaction format, -http://edamontology.org/format_2055,Sequence assembly format, -http://edamontology.org/format_2056,Microarray experiment data format, -http://edamontology.org/format_2057,Sequence trace format, -http://edamontology.org/format_2058,Gene expression report format, -http://edamontology.org/format_2059,Genotype and phenotype annotation format, -http://edamontology.org/format_2060,Map format, -http://edamontology.org/format_2061,Nucleic acid features (primers) format, -http://edamontology.org/format_2062,Protein report format, -http://edamontology.org/format_2063,Protein report (enzyme) format, -http://edamontology.org/format_2064,3D-1D scoring matrix format, -http://edamontology.org/format_2065,Protein structure report (quality evaluation) format, -http://edamontology.org/format_2066,Database hits (sequence) format, -http://edamontology.org/format_2067,Sequence distance matrix format, -http://edamontology.org/format_2068,Sequence motif format, -http://edamontology.org/format_2069,Sequence profile format, -http://edamontology.org/format_2072,Hidden Markov model format, -http://edamontology.org/format_2074,Dirichlet distribution format, -http://edamontology.org/format_2075,HMM emission and transition counts format, -http://edamontology.org/format_2076,RNA secondary structure format, -http://edamontology.org/format_2077,Protein secondary structure format, -http://edamontology.org/format_2078,Sequence range format, -http://edamontology.org/format_2094,pure, -http://edamontology.org/format_2095,unpure, -http://edamontology.org/format_2096,unambiguous sequence, -http://edamontology.org/format_2097,ambiguous, -http://edamontology.org/format_2155,Sequence features (repeats) format, -http://edamontology.org/format_2158,Nucleic acid features (restriction sites) format, -http://edamontology.org/format_2159,Gene features (coding region) format, -http://edamontology.org/format_2170,Sequence cluster format, -http://edamontology.org/format_2171,Sequence cluster format (protein), -http://edamontology.org/format_2172,Sequence cluster format (nucleic acid), -http://edamontology.org/format_2175,Gene cluster format, -http://edamontology.org/format_2181,EMBL-like (text), -http://edamontology.org/format_2182,FASTQ-like format (text), -http://edamontology.org/format_2183,EMBLXML, -http://edamontology.org/format_2184,cdsxml, -http://edamontology.org/format_2185,insdxml, -http://edamontology.org/format_2186,geneseq, -http://edamontology.org/format_2187,UniProt-like (text), -http://edamontology.org/format_2188,UniProt format, -http://edamontology.org/format_2189,ipi, -http://edamontology.org/format_2194,medline, -http://edamontology.org/format_2195,Ontology format, -http://edamontology.org/format_2196,OBO format, -http://edamontology.org/format_2197,OWL format, -http://edamontology.org/format_2200,FASTA-like (text), -http://edamontology.org/format_2202,Sequence record full format, -http://edamontology.org/format_2203,Sequence record lite format, -http://edamontology.org/format_2204,EMBL format (XML), -http://edamontology.org/format_2205,GenBank-like format (text), -http://edamontology.org/format_2206,Sequence feature table format (text), -http://edamontology.org/format_2210,Strain data format, -http://edamontology.org/format_2211,CIP strain data format, -http://edamontology.org/format_2243,phylip property values, -http://edamontology.org/format_2303,STRING entry format (HTML), -http://edamontology.org/format_2304,STRING entry format (XML), -http://edamontology.org/format_2305,GFF, -http://edamontology.org/format_2306,GTF, -http://edamontology.org/format_2310,FASTA-HTML, -http://edamontology.org/format_2311,EMBL-HTML, -http://edamontology.org/format_2322,BioCyc enzyme report format, -http://edamontology.org/format_2323,ENZYME enzyme report format, -http://edamontology.org/format_2328,PseudoCAP gene report format, -http://edamontology.org/format_2329,GeneCards gene report format, -http://edamontology.org/format_2330,Textual format, -http://edamontology.org/format_2331,HTML, -http://edamontology.org/format_2332,XML,xml -http://edamontology.org/format_2333,Binary format, -http://edamontology.org/format_2334,URI format, -http://edamontology.org/format_2341,NCI-Nature pathway entry format, -http://edamontology.org/format_2350,Format (by type of data), -http://edamontology.org/format_2352,BioXSD (XML), -http://edamontology.org/format_2376,RDF format, -http://edamontology.org/format_2532,GenBank-HTML, -http://edamontology.org/format_2542,Protein features (domains) format, -http://edamontology.org/format_2543,EMBL-like format, -http://edamontology.org/format_2545,FASTQ-like format, -http://edamontology.org/format_2546,FASTA-like, -http://edamontology.org/format_2547,uniprotkb-like format, -http://edamontology.org/format_2548,Sequence feature table format, -http://edamontology.org/format_2549,OBO, -http://edamontology.org/format_2550,OBO-XML, -http://edamontology.org/format_2551,Sequence record format (text), -http://edamontology.org/format_2552,Sequence record format (XML), -http://edamontology.org/format_2553,Sequence feature table format (XML), -http://edamontology.org/format_2554,Alignment format (text), -http://edamontology.org/format_2555,Alignment format (XML), -http://edamontology.org/format_2556,Phylogenetic tree format (text), -http://edamontology.org/format_2557,Phylogenetic tree format (XML), -http://edamontology.org/format_2558,EMBL-like (XML), -http://edamontology.org/format_2559,GenBank-like format, -http://edamontology.org/format_2560,STRING entry format, -http://edamontology.org/format_2561,Sequence assembly format (text), -http://edamontology.org/format_2562,Amino acid identifier format, -http://edamontology.org/format_2566,completely unambiguous, -http://edamontology.org/format_2567,completely unambiguous pure, -http://edamontology.org/format_2568,completely unambiguous pure nucleotide, -http://edamontology.org/format_2569,completely unambiguous pure dna, -http://edamontology.org/format_2570,completely unambiguous pure rna sequence, -http://edamontology.org/format_2571,Raw sequence format, -http://edamontology.org/format_2572,BAM, -http://edamontology.org/format_2573,SAM, -http://edamontology.org/format_2585,SBML, -http://edamontology.org/format_2607,completely unambiguous pure protein, -http://edamontology.org/format_2848,Bibliographic reference format, -http://edamontology.org/format_2919,Sequence annotation track format, -http://edamontology.org/format_2920,Alignment format (pair only), -http://edamontology.org/format_2921,Sequence variation annotation format, -http://edamontology.org/format_2922,markx0 variant, -http://edamontology.org/format_2923,mega variant, -http://edamontology.org/format_2924,Phylip format variant, -http://edamontology.org/format_3000,AB1, -http://edamontology.org/format_3001,ACE, -http://edamontology.org/format_3003,BED, -http://edamontology.org/format_3004,bigBed, -http://edamontology.org/format_3005,WIG, -http://edamontology.org/format_3006,bigWig, -http://edamontology.org/format_3007,PSL, -http://edamontology.org/format_3008,MAF, -http://edamontology.org/format_3009,2bit, -http://edamontology.org/format_3010,.nib, -http://edamontology.org/format_3011,genePred, -http://edamontology.org/format_3012,pgSnp, -http://edamontology.org/format_3013,axt, -http://edamontology.org/format_3014,LAV, -http://edamontology.org/format_3015,Pileup, -http://edamontology.org/format_3016,VCF, -http://edamontology.org/format_3017,SRF, -http://edamontology.org/format_3018,ZTR, -http://edamontology.org/format_3019,GVF, -http://edamontology.org/format_3020,BCF, -http://edamontology.org/format_3033,Matrix format, -http://edamontology.org/format_3097,Protein domain classification format, -http://edamontology.org/format_3098,Raw SCOP domain classification format, -http://edamontology.org/format_3099,Raw CATH domain classification format, -http://edamontology.org/format_3100,CATH domain report format, -http://edamontology.org/format_3155,SBRML, -http://edamontology.org/format_3156,BioPAX, -http://edamontology.org/format_3157,EBI Application Result XML, -http://edamontology.org/format_3158,PSI MI XML (MIF), -http://edamontology.org/format_3159,phyloXML, -http://edamontology.org/format_3160,NeXML, -http://edamontology.org/format_3161,MAGE-ML, -http://edamontology.org/format_3162,MAGE-TAB, -http://edamontology.org/format_3163,GCDML, -http://edamontology.org/format_3164,GTrack, -http://edamontology.org/format_3166,Biological pathway or network report format, -http://edamontology.org/format_3167,Experiment annotation format, -http://edamontology.org/format_3235,Cytoband format, -http://edamontology.org/format_3239,CopasiML, -http://edamontology.org/format_3240,CellML, -http://edamontology.org/format_3242,PSI MI TAB (MITAB), -http://edamontology.org/format_3243,PSI-PAR, -http://edamontology.org/format_3244,mzML, -http://edamontology.org/format_3245,Mass spectrometry data format, -http://edamontology.org/format_3246,TraML, -http://edamontology.org/format_3247,mzIdentML, -http://edamontology.org/format_3248,mzQuantML, -http://edamontology.org/format_3249,GelML, -http://edamontology.org/format_3250,spML, -http://edamontology.org/format_3252,OWL Functional Syntax, -http://edamontology.org/format_3253,Manchester OWL Syntax, -http://edamontology.org/format_3254,KRSS2 Syntax, -http://edamontology.org/format_3255,Turtle, -http://edamontology.org/format_3256,N-Triples,nt -http://edamontology.org/format_3257,Notation3,n3 -http://edamontology.org/format_3261,RDF/XML,rdf -http://edamontology.org/format_3262,OWL/XML, -http://edamontology.org/format_3281,A2M, -http://edamontology.org/format_3284,SFF, -http://edamontology.org/format_3285,MAP, -http://edamontology.org/format_3286,PED, -http://edamontology.org/format_3287,Individual genetic data format, -http://edamontology.org/format_3288,PED/MAP, -http://edamontology.org/format_3309,CT, -http://edamontology.org/format_3310,SS, -http://edamontology.org/format_3311,RNAML, -http://edamontology.org/format_3312,GDE, -http://edamontology.org/format_3313,BLC, -http://edamontology.org/format_3326,Data index format, -http://edamontology.org/format_3327,BAI, -http://edamontology.org/format_3328,HMMER2, -http://edamontology.org/format_3329,HMMER3, -http://edamontology.org/format_3330,PO, -http://edamontology.org/format_3331,BLAST XML results format, -http://edamontology.org/format_3462,CRAM, -http://edamontology.org/format_3464,JSON,json -http://edamontology.org/format_3466,EPS, -http://edamontology.org/format_3467,GIF, -http://edamontology.org/format_3468,xls, -http://edamontology.org/format_3475,TSV,tsv|tab -http://edamontology.org/format_3476,Gene expression data format, -http://edamontology.org/format_3477,Cytoscape input file format, -http://edamontology.org/format_3484,ebwt, -http://edamontology.org/format_3485,RSF, -http://edamontology.org/format_3486,GCG format variant, -http://edamontology.org/format_3487,BSML, -http://edamontology.org/format_3491,ebwtl, -http://edamontology.org/format_3499,Ensembl variation file format, -http://edamontology.org/format_3506,docx, -http://edamontology.org/format_3507,Document format, -http://edamontology.org/format_3508,PDF, -http://edamontology.org/format_3547,Image format, -http://edamontology.org/format_3548,DICOM format, -http://edamontology.org/format_3549,nii, -http://edamontology.org/format_3550,mhd, -http://edamontology.org/format_3551,nrrd, -http://edamontology.org/format_3554,R file format, -http://edamontology.org/format_3555,SPSS, -http://edamontology.org/format_3556,MHTML,mhtml|mht|eml -http://edamontology.org/format_3578,IDAT, -http://edamontology.org/format_3579,JPG, -http://edamontology.org/format_3580,rcc, -http://edamontology.org/format_3581,arff, -http://edamontology.org/format_3582,afg, -http://edamontology.org/format_3583,bedgraph, -http://edamontology.org/format_3584,bedstrict, -http://edamontology.org/format_3585,bed6, -http://edamontology.org/format_3586,bed12, -http://edamontology.org/format_3587,chrominfo, -http://edamontology.org/format_3588,customtrack, -http://edamontology.org/format_3589,csfasta, -http://edamontology.org/format_3590,HDF5, -http://edamontology.org/format_3591,TIFF, -http://edamontology.org/format_3592,BMP, -http://edamontology.org/format_3593,im, -http://edamontology.org/format_3594,pcd, -http://edamontology.org/format_3595,pcx, -http://edamontology.org/format_3596,ppm, -http://edamontology.org/format_3597,psd, -http://edamontology.org/format_3598,xbm, -http://edamontology.org/format_3599,xpm, -http://edamontology.org/format_3600,rgb, -http://edamontology.org/format_3601,pbm, -http://edamontology.org/format_3602,pgm, -http://edamontology.org/format_3603,PNG, -http://edamontology.org/format_3604,SVG, -http://edamontology.org/format_3605,rast, -http://edamontology.org/format_3606,Sequence quality report format (text), -http://edamontology.org/format_3607,qual, -http://edamontology.org/format_3608,qualsolexa, -http://edamontology.org/format_3609,qualillumina, -http://edamontology.org/format_3610,qualsolid, -http://edamontology.org/format_3611,qual454, -http://edamontology.org/format_3612,ENCODE peak format, -http://edamontology.org/format_3613,ENCODE narrow peak format, -http://edamontology.org/format_3614,ENCODE broad peak format, -http://edamontology.org/format_3615,bgzip, -http://edamontology.org/format_3616,tabix, -http://edamontology.org/format_3617,Graph format, -http://edamontology.org/format_3618,xgmml, -http://edamontology.org/format_3619,sif, -http://edamontology.org/format_3620,xlsx, -http://edamontology.org/format_3621,SQLite format, -http://edamontology.org/format_3622,Gemini SQLite format, -http://edamontology.org/format_3623,Index format, -http://edamontology.org/format_3624,snpeffdb, -http://edamontology.org/format_3626,MAT, -http://edamontology.org/format_3650,netCDF, -http://edamontology.org/format_3651,MGF, -http://edamontology.org/format_3652,dta, -http://edamontology.org/format_3653,pkl, -http://edamontology.org/format_3654,mzXML, -http://edamontology.org/format_3655,pepXML, -http://edamontology.org/format_3657,GPML, -http://edamontology.org/format_3665,K-mer countgraph,oxlicg -http://edamontology.org/format_3681,mzTab, -http://edamontology.org/format_3682,imzML metadata file,imzML -http://edamontology.org/format_3683,qcML, -http://edamontology.org/format_3684,PRIDE XML, -http://edamontology.org/format_3685,SED-ML, -http://edamontology.org/format_3686,COMBINE OMEX, -http://edamontology.org/format_3687,ISA-TAB, -http://edamontology.org/format_3688,SBtab, -http://edamontology.org/format_3689,BCML, -http://edamontology.org/format_3690,BDML, -http://edamontology.org/format_3691,BEL, -http://edamontology.org/format_3692,SBGN-ML, -http://edamontology.org/format_3693,AGP, -http://edamontology.org/format_3696,PS, -http://edamontology.org/format_3698,SRA format, -http://edamontology.org/format_3699,VDB, -http://edamontology.org/format_3700,Tabix index file format, -http://edamontology.org/format_3701,Sequin format, -http://edamontology.org/format_3702,MSF, -http://edamontology.org/format_3706,Biodiversity data format, -http://edamontology.org/format_3708,ABCD format, -http://edamontology.org/format_3709,GCT/Res format, -http://edamontology.org/format_3710,WIFF format,wiff -http://edamontology.org/format_3711,X!Tandem XML, -http://edamontology.org/format_3712,Thermo RAW, -http://edamontology.org/format_3713,Mascot .dat file, -http://edamontology.org/format_3714,MaxQuant APL peaklist format, -http://edamontology.org/format_3725,SBOL, -http://edamontology.org/format_3726,PMML, -http://edamontology.org/format_3727,OME-TIFF, -http://edamontology.org/format_3728,LocARNA PP, -http://edamontology.org/format_3729,dbGaP format, -http://edamontology.org/format_3746,BIOM format,biom -http://edamontology.org/format_3747,protXML, -http://edamontology.org/format_3748,Linked data format, -http://edamontology.org/format_3749,JSON-LD,jsonld -http://edamontology.org/format_3750,YAML,yaml|yml -http://edamontology.org/format_3751,DSV, -http://edamontology.org/format_3752,CSV,csv -http://edamontology.org/format_3758,SEQUEST .out file, -http://edamontology.org/format_3764,idXML, -http://edamontology.org/format_3765,KNIME datatable format, -http://edamontology.org/format_3770,UniProtKB XML, -http://edamontology.org/format_3771,UniProtKB RDF, -http://edamontology.org/format_3772,BioJSON (BioXSD), -http://edamontology.org/format_3773,BioYAML, -http://edamontology.org/format_3774,BioJSON (Jalview), -http://edamontology.org/format_3775,GSuite, -http://edamontology.org/format_3776,BTrack, -http://edamontology.org/format_3777,MCPD, -http://edamontology.org/format_3780,Annotated text format, -http://edamontology.org/format_3781,PubAnnotation format, -http://edamontology.org/format_3782,BioC, -http://edamontology.org/format_3783,PubTator format, -http://edamontology.org/format_3784,Open Annotation format, -http://edamontology.org/format_3785,BioNLP Shared Task format, -http://edamontology.org/format_3787,Query language, -http://edamontology.org/format_3788,SQL,sql -http://edamontology.org/format_3789,XQuery,xq|xqy|xquery -http://edamontology.org/format_3790,SPARQL, -http://edamontology.org/format_3804,xsd, -http://edamontology.org/format_3811,XMFA, -http://edamontology.org/format_3812,GEN, -http://edamontology.org/format_3813,SAMPLE file format, -http://edamontology.org/format_3814,SDF, -http://edamontology.org/format_3815,Molfile, -http://edamontology.org/format_3816,Mol2, -http://edamontology.org/format_3817,latex, -http://edamontology.org/format_3818,ELAND format, -http://edamontology.org/format_3819,Relaxed PHYLIP Interleaved, -http://edamontology.org/format_3820,Relaxed PHYLIP Sequential, -http://edamontology.org/format_3821,VisML, -http://edamontology.org/format_3822,GML, -http://edamontology.org/format_3823,FASTG, -http://edamontology.org/format_3824,NMR data format, -http://edamontology.org/format_3825,nmrML, -http://edamontology.org/format_3826,proBAM, -http://edamontology.org/format_3827,proBED, -http://edamontology.org/format_3828,Raw microarray data format, -http://edamontology.org/format_3829,GPR, -http://edamontology.org/format_3830,ARB, -http://edamontology.org/format_3832,consensusXML, -http://edamontology.org/format_3833,featureXML, -http://edamontology.org/format_3834,mzData, -http://edamontology.org/format_3835,TIDE TXT, -http://edamontology.org/format_3836,BLAST XML v2 results format, -http://edamontology.org/format_3838,pptx, -http://edamontology.org/format_3839,ibd,ibd -http://edamontology.org/format_3841,NLP format, -http://edamontology.org/format_3843,BEAST, -http://edamontology.org/format_3844,Chado-XML, -http://edamontology.org/format_3845,HSAML, -http://edamontology.org/format_3846,InterProScan XML, -http://edamontology.org/format_3847,KGML, -http://edamontology.org/format_3848,PubMed XML, -http://edamontology.org/format_3849,MSAML, -http://edamontology.org/format_3850,OrthoXML, -http://edamontology.org/format_3851,PSDML, -http://edamontology.org/format_3852,SeqXML, -http://edamontology.org/format_3853,UniParc XML, -http://edamontology.org/format_3854,UniRef XML, -http://edamontology.org/format_3857,CWL,cwl -http://edamontology.org/format_3858,Waters RAW, -http://edamontology.org/format_3859,JCAMP-DX, -http://edamontology.org/format_3862,NLP annotation format, -http://edamontology.org/format_3863,NLP corpus format, -http://edamontology.org/format_3864,mirGFF3, -http://edamontology.org/format_3865,RNA annotation format, -http://edamontology.org/format_3866,Trajectory format, -http://edamontology.org/format_3867,Trajectory format (binary), -http://edamontology.org/format_3868,Trajectory format (text), -http://edamontology.org/format_3873,HDF, -http://edamontology.org/format_3874,PCAzip, -http://edamontology.org/format_3875,XTC, -http://edamontology.org/format_3876,TNG, -http://edamontology.org/format_3877,XYZ, -http://edamontology.org/format_3878,mdcrd, -http://edamontology.org/format_3879,Topology format, -http://edamontology.org/format_3880,GROMACS top, -http://edamontology.org/format_3881,AMBER top, -http://edamontology.org/format_3882,PSF, -http://edamontology.org/format_3883,GROMACS itp, -http://edamontology.org/format_3884,FF parameter format, -http://edamontology.org/format_3885,BinPos, -http://edamontology.org/format_3886,RST, -http://edamontology.org/format_3887,CHARMM rtf, -http://edamontology.org/format_3888,AMBER frcmod, -http://edamontology.org/format_3889,AMBER off, -http://edamontology.org/format_3906,NMReDATA, -http://edamontology.org/format_3909,BpForms, -http://edamontology.org/format_3910,trr, -http://edamontology.org/format_3911,msh,msh -http://edamontology.org/format_3913,Loom,loom -http://edamontology.org/format_3915,Zarr,zarray|zgroup -http://edamontology.org/format_3916,MTX,mtx -http://edamontology.org/format_3951,BcForms, -http://edamontology.org/format_3956,N-Quads,nq -http://edamontology.org/format_3969,Vega,json -http://edamontology.org/format_3970,Vega-lite,json -http://edamontology.org/format_3971,NeuroML, -http://edamontology.org/format_3972,BNGL,bngl -http://edamontology.org/format_3973,Docker image format,dockerfile -http://edamontology.org/format_3975,GFA 1,gfa -http://edamontology.org/format_3976,GFA 2,gfa -http://edamontology.org/format_3977,ObjTables,xlsx -http://edamontology.org/format_3978,CONTIG,contig -http://edamontology.org/format_3979,WEGO,wego -http://edamontology.org/format_3980,RPKM,rpkm -http://edamontology.org/format_3981,TAR format,tar -http://edamontology.org/format_3982,CHAIN,chain -http://edamontology.org/format_3983,NET,net -http://edamontology.org/format_3984,QMAP,qmap -http://edamontology.org/format_3985,gxformat2,ga -http://edamontology.org/format_3986,WMV,wmv -http://edamontology.org/format_3987,ZIP format,zip -http://edamontology.org/format_3988,LSM,lsm -http://edamontology.org/format_3989,GZIP format,gz|gzip -http://edamontology.org/format_3990,AVI,avi -http://edamontology.org/format_3991,TrackDB,trackDb -http://edamontology.org/format_3992,CIGAR format,cigar -http://edamontology.org/format_3993,Stereolithography format,stl -http://edamontology.org/format_3994,U3D,u3d -http://edamontology.org/format_3995,Texture file format,tex -http://edamontology.org/format_3996,Python script,py -http://edamontology.org/format_3997,MPEG-4,mp4 -http://edamontology.org/format_3998,Perl script,pl -http://edamontology.org/format_3999,R script,R -http://edamontology.org/format_4000,R markdown,Rmd -http://edamontology.org/format_4001,NIFTI format,nii -http://edamontology.org/format_4002,pickle,pickle -http://edamontology.org/format_4003,NumPy format,npy -http://edamontology.org/format_4004,SimTools repertoire file format,repz -http://edamontology.org/format_4005,Configuration file format,cfg -http://edamontology.org/format_4006,Zstandard format,zst -http://edamontology.org/format_4007,MATLAB script,m -http://edamontology.org/operation_0004,Operation, -http://edamontology.org/operation_0224,Query and retrieval, -http://edamontology.org/operation_0225,Data retrieval (database cross-reference), -http://edamontology.org/operation_0226,Annotation, -http://edamontology.org/operation_0227,Indexing, -http://edamontology.org/operation_0228,Data index analysis, -http://edamontology.org/operation_0229,Annotation retrieval (sequence), -http://edamontology.org/operation_0230,Sequence generation, -http://edamontology.org/operation_0231,Sequence editing, -http://edamontology.org/operation_0232,Sequence merging, -http://edamontology.org/operation_0233,Sequence conversion, -http://edamontology.org/operation_0234,Sequence complexity calculation, -http://edamontology.org/operation_0235,Sequence ambiguity calculation, -http://edamontology.org/operation_0236,Sequence composition calculation, -http://edamontology.org/operation_0237,Repeat sequence analysis, -http://edamontology.org/operation_0238,Sequence motif discovery, -http://edamontology.org/operation_0239,Sequence motif recognition, -http://edamontology.org/operation_0240,Sequence motif comparison, -http://edamontology.org/operation_0241,Transcription regulatory sequence analysis, -http://edamontology.org/operation_0242,Conserved transcription regulatory sequence identification, -http://edamontology.org/operation_0243,Protein property calculation (from structure), -http://edamontology.org/operation_0244,Simulation analysis, -http://edamontology.org/operation_0245,Structural motif discovery, -http://edamontology.org/operation_0246,Protein domain recognition, -http://edamontology.org/operation_0247,Protein architecture analysis, -http://edamontology.org/operation_0248,Residue interaction calculation, -http://edamontology.org/operation_0249,Protein geometry calculation, -http://edamontology.org/operation_0250,Protein property calculation, -http://edamontology.org/operation_0252,Peptide immunogenicity prediction, -http://edamontology.org/operation_0253,Sequence feature detection, -http://edamontology.org/operation_0254,Data retrieval (feature table), -http://edamontology.org/operation_0255,Feature table query, -http://edamontology.org/operation_0256,Sequence feature comparison, -http://edamontology.org/operation_0257,Data retrieval (sequence alignment), -http://edamontology.org/operation_0258,Sequence alignment analysis, -http://edamontology.org/operation_0259,Sequence alignment comparison, -http://edamontology.org/operation_0260,Sequence alignment conversion, -http://edamontology.org/operation_0261,Nucleic acid property processing, -http://edamontology.org/operation_0262,Nucleic acid property calculation, -http://edamontology.org/operation_0264,Alternative splicing prediction, -http://edamontology.org/operation_0265,Frameshift detection, -http://edamontology.org/operation_0266,Vector sequence detection, -http://edamontology.org/operation_0267,Protein secondary structure prediction, -http://edamontology.org/operation_0268,Protein super-secondary structure prediction, -http://edamontology.org/operation_0269,Transmembrane protein prediction, -http://edamontology.org/operation_0270,Transmembrane protein analysis, -http://edamontology.org/operation_0271,Structure prediction, -http://edamontology.org/operation_0272,Residue contact prediction, -http://edamontology.org/operation_0273,Protein interaction raw data analysis, -http://edamontology.org/operation_0274,Protein-protein interaction prediction (from protein sequence), -http://edamontology.org/operation_0275,Protein-protein interaction prediction (from protein structure), -http://edamontology.org/operation_0276,Protein interaction network analysis, -http://edamontology.org/operation_0277,Pathway or network comparison, -http://edamontology.org/operation_0278,RNA secondary structure prediction, -http://edamontology.org/operation_0279,Nucleic acid folding analysis, -http://edamontology.org/operation_0280,Data retrieval (restriction enzyme annotation), -http://edamontology.org/operation_0281,Genetic marker identification, -http://edamontology.org/operation_0282,Genetic mapping, -http://edamontology.org/operation_0283,Linkage analysis, -http://edamontology.org/operation_0284,Codon usage table generation, -http://edamontology.org/operation_0285,Codon usage table comparison, -http://edamontology.org/operation_0286,Codon usage analysis, -http://edamontology.org/operation_0287,Base position variability plotting, -http://edamontology.org/operation_0288,Sequence word comparison, -http://edamontology.org/operation_0289,Sequence distance matrix generation, -http://edamontology.org/operation_0290,Sequence redundancy removal, -http://edamontology.org/operation_0291,Sequence clustering, -http://edamontology.org/operation_0292,Sequence alignment, -http://edamontology.org/operation_0293,Hybrid sequence alignment construction, -http://edamontology.org/operation_0294,Structure-based sequence alignment, -http://edamontology.org/operation_0295,Structure alignment, -http://edamontology.org/operation_0296,Sequence profile generation, -http://edamontology.org/operation_0297,3D profile generation, -http://edamontology.org/operation_0298,Profile-profile alignment, -http://edamontology.org/operation_0299,3D profile-to-3D profile alignment, -http://edamontology.org/operation_0300,Sequence profile alignment, -http://edamontology.org/operation_0301,Sequence-to-3D-profile alignment, -http://edamontology.org/operation_0302,Protein threading, -http://edamontology.org/operation_0303,Fold recognition, -http://edamontology.org/operation_0304,Metadata retrieval, -http://edamontology.org/operation_0305,Literature search, -http://edamontology.org/operation_0306,Text mining, -http://edamontology.org/operation_0307,Virtual PCR, -http://edamontology.org/operation_0308,PCR primer design, -http://edamontology.org/operation_0309,Microarray probe design, -http://edamontology.org/operation_0310,Sequence assembly, -http://edamontology.org/operation_0311,Microarray data standardisation and normalisation, -http://edamontology.org/operation_0312,Sequencing-based expression profile data processing, -http://edamontology.org/operation_0313,Expression profile clustering, -http://edamontology.org/operation_0314,Gene expression profiling, -http://edamontology.org/operation_0315,Expression profile comparison, -http://edamontology.org/operation_0316,Functional profiling, -http://edamontology.org/operation_0317,EST and cDNA sequence analysis, -http://edamontology.org/operation_0318,Structural genomics target selection, -http://edamontology.org/operation_0319,Protein secondary structure assignment, -http://edamontology.org/operation_0320,Protein structure assignment, -http://edamontology.org/operation_0321,Protein structure validation, -http://edamontology.org/operation_0322,Molecular model refinement, -http://edamontology.org/operation_0323,Phylogenetic inference, -http://edamontology.org/operation_0324,Phylogenetic analysis, -http://edamontology.org/operation_0325,Phylogenetic tree comparison, -http://edamontology.org/operation_0326,Phylogenetic tree editing, -http://edamontology.org/operation_0327,Phylogenetic footprinting, -http://edamontology.org/operation_0328,Protein folding simulation, -http://edamontology.org/operation_0329,Protein folding pathway prediction, -http://edamontology.org/operation_0330,Protein SNP mapping, -http://edamontology.org/operation_0331,Variant effect prediction, -http://edamontology.org/operation_0332,Immunogen design, -http://edamontology.org/operation_0333,Zinc finger prediction, -http://edamontology.org/operation_0334,Enzyme kinetics calculation, -http://edamontology.org/operation_0335,Formatting, -http://edamontology.org/operation_0336,Format validation, -http://edamontology.org/operation_0337,Visualisation, -http://edamontology.org/operation_0338,Sequence database search, -http://edamontology.org/operation_0339,Structure database search, -http://edamontology.org/operation_0340,Protein secondary database search, -http://edamontology.org/operation_0341,Motif database search, -http://edamontology.org/operation_0342,Sequence profile database search, -http://edamontology.org/operation_0343,Transmembrane protein database search, -http://edamontology.org/operation_0344,Sequence retrieval (by code), -http://edamontology.org/operation_0345,Sequence retrieval (by keyword), -http://edamontology.org/operation_0346,Sequence similarity search, -http://edamontology.org/operation_0347,Sequence database search (by motif or pattern), -http://edamontology.org/operation_0348,Sequence database search (by amino acid composition), -http://edamontology.org/operation_0349,Sequence database search (by property), -http://edamontology.org/operation_0350,Sequence database search (by sequence using word-based methods), -http://edamontology.org/operation_0351,Sequence database search (by sequence using profile-based methods), -http://edamontology.org/operation_0352,Sequence database search (by sequence using local alignment-based methods), -http://edamontology.org/operation_0353,Sequence database search (by sequence using global alignment-based methods), -http://edamontology.org/operation_0354,Sequence database search (by sequence for primer sequences), -http://edamontology.org/operation_0355,Sequence database search (by molecular weight), -http://edamontology.org/operation_0356,Sequence database search (by isoelectric point), -http://edamontology.org/operation_0357,Structure retrieval (by code), -http://edamontology.org/operation_0358,Structure retrieval (by keyword), -http://edamontology.org/operation_0359,Structure database search (by sequence), -http://edamontology.org/operation_0360,Structural similarity search, -http://edamontology.org/operation_0361,Sequence annotation, -http://edamontology.org/operation_0362,Genome annotation, -http://edamontology.org/operation_0363,Reverse complement, -http://edamontology.org/operation_0364,Random sequence generation, -http://edamontology.org/operation_0365,Restriction digest, -http://edamontology.org/operation_0366,Protein sequence cleavage, -http://edamontology.org/operation_0367,Sequence mutation and randomisation, -http://edamontology.org/operation_0368,Sequence masking, -http://edamontology.org/operation_0369,Sequence cutting, -http://edamontology.org/operation_0370,Restriction site creation, -http://edamontology.org/operation_0371,DNA translation, -http://edamontology.org/operation_0372,DNA transcription, -http://edamontology.org/operation_0377,Sequence composition calculation (nucleic acid), -http://edamontology.org/operation_0378,Sequence composition calculation (protein), -http://edamontology.org/operation_0379,Repeat sequence detection, -http://edamontology.org/operation_0380,Repeat sequence organisation analysis, -http://edamontology.org/operation_0383,Protein hydropathy calculation (from structure), -http://edamontology.org/operation_0384,Accessible surface calculation, -http://edamontology.org/operation_0385,Protein hydropathy cluster calculation, -http://edamontology.org/operation_0386,Protein dipole moment calculation, -http://edamontology.org/operation_0387,Molecular surface calculation, -http://edamontology.org/operation_0388,Protein binding site prediction (from structure), -http://edamontology.org/operation_0389,Protein-nucleic acid interaction analysis, -http://edamontology.org/operation_0390,Protein peeling, -http://edamontology.org/operation_0391,Protein distance matrix calculation, -http://edamontology.org/operation_0392,Contact map calculation, -http://edamontology.org/operation_0393,Residue cluster calculation, -http://edamontology.org/operation_0394,Hydrogen bond calculation, -http://edamontology.org/operation_0395,Residue non-canonical interaction detection, -http://edamontology.org/operation_0396,Ramachandran plot calculation, -http://edamontology.org/operation_0397,Ramachandran plot validation, -http://edamontology.org/operation_0398,Protein molecular weight calculation, -http://edamontology.org/operation_0399,Protein extinction coefficient calculation, -http://edamontology.org/operation_0400,Protein pKa calculation, -http://edamontology.org/operation_0401,Protein hydropathy calculation (from sequence), -http://edamontology.org/operation_0402,Protein titration curve plotting, -http://edamontology.org/operation_0403,Protein isoelectric point calculation, -http://edamontology.org/operation_0404,Protein hydrogen exchange rate calculation, -http://edamontology.org/operation_0405,Protein hydrophobic region calculation, -http://edamontology.org/operation_0406,Protein aliphatic index calculation, -http://edamontology.org/operation_0407,Protein hydrophobic moment plotting, -http://edamontology.org/operation_0408,Protein globularity prediction, -http://edamontology.org/operation_0409,Protein solubility prediction, -http://edamontology.org/operation_0410,Protein crystallizability prediction, -http://edamontology.org/operation_0411,Protein signal peptide detection (eukaryotes), -http://edamontology.org/operation_0412,Protein signal peptide detection (bacteria), -http://edamontology.org/operation_0413,MHC peptide immunogenicity prediction, -http://edamontology.org/operation_0414,Protein feature prediction (from sequence), -http://edamontology.org/operation_0415,Nucleic acid feature detection, -http://edamontology.org/operation_0416,Epitope mapping, -http://edamontology.org/operation_0417,PTM site prediction, -http://edamontology.org/operation_0418,Protein signal peptide detection, -http://edamontology.org/operation_0419,Protein binding site prediction (from sequence), -http://edamontology.org/operation_0420,Nucleic acids-binding site prediction, -http://edamontology.org/operation_0421,Protein folding site prediction, -http://edamontology.org/operation_0422,Protein cleavage site prediction, -http://edamontology.org/operation_0423,Epitope mapping (MHC Class I), -http://edamontology.org/operation_0424,Epitope mapping (MHC Class II), -http://edamontology.org/operation_0425,Whole gene prediction, -http://edamontology.org/operation_0426,Gene component prediction, -http://edamontology.org/operation_0427,Transposon prediction, -http://edamontology.org/operation_0428,PolyA signal detection, -http://edamontology.org/operation_0429,Quadruplex formation site detection, -http://edamontology.org/operation_0430,CpG island and isochore detection, -http://edamontology.org/operation_0431,Restriction site recognition, -http://edamontology.org/operation_0432,Nucleosome position prediction, -http://edamontology.org/operation_0433,Splice site prediction, -http://edamontology.org/operation_0434,Integrated gene prediction, -http://edamontology.org/operation_0435,Operon prediction, -http://edamontology.org/operation_0436,Coding region prediction, -http://edamontology.org/operation_0437,SECIS element prediction, -http://edamontology.org/operation_0438,Transcriptional regulatory element prediction, -http://edamontology.org/operation_0439,Translation initiation site prediction, -http://edamontology.org/operation_0440,Promoter prediction, -http://edamontology.org/operation_0441,cis-regulatory element prediction, -http://edamontology.org/operation_0442,Transcriptional regulatory element prediction (RNA-cis), -http://edamontology.org/operation_0443,trans-regulatory element prediction, -http://edamontology.org/operation_0444,S/MAR prediction, -http://edamontology.org/operation_0445,Transcription factor binding site prediction, -http://edamontology.org/operation_0446,Exonic splicing enhancer prediction, -http://edamontology.org/operation_0447,Sequence alignment validation, -http://edamontology.org/operation_0448,Sequence alignment analysis (conservation), -http://edamontology.org/operation_0449,Sequence alignment analysis (site correlation), -http://edamontology.org/operation_0450,Chimera detection, -http://edamontology.org/operation_0451,Recombination detection, -http://edamontology.org/operation_0452,Indel detection, -http://edamontology.org/operation_0453,Nucleosome formation potential prediction, -http://edamontology.org/operation_0455,Nucleic acid thermodynamic property calculation, -http://edamontology.org/operation_0456,Nucleic acid melting profile plotting, -http://edamontology.org/operation_0457,Nucleic acid stitch profile plotting, -http://edamontology.org/operation_0458,Nucleic acid melting curve plotting, -http://edamontology.org/operation_0459,Nucleic acid probability profile plotting, -http://edamontology.org/operation_0460,Nucleic acid temperature profile plotting, -http://edamontology.org/operation_0461,Nucleic acid curvature calculation, -http://edamontology.org/operation_0463,miRNA target prediction, -http://edamontology.org/operation_0464,tRNA gene prediction, -http://edamontology.org/operation_0465,siRNA binding specificity prediction, -http://edamontology.org/operation_0467,Protein secondary structure prediction (integrated), -http://edamontology.org/operation_0468,Protein secondary structure prediction (helices), -http://edamontology.org/operation_0469,Protein secondary structure prediction (turns), -http://edamontology.org/operation_0470,Protein secondary structure prediction (coils), -http://edamontology.org/operation_0471,Disulfide bond prediction, -http://edamontology.org/operation_0472,GPCR prediction, -http://edamontology.org/operation_0473,GPCR analysis, -http://edamontology.org/operation_0474,Protein structure prediction, -http://edamontology.org/operation_0475,Nucleic acid structure prediction, -http://edamontology.org/operation_0476,Ab initio structure prediction, -http://edamontology.org/operation_0477,Protein modelling, -http://edamontology.org/operation_0478,Molecular docking, -http://edamontology.org/operation_0479,Backbone modelling, -http://edamontology.org/operation_0480,Side chain modelling, -http://edamontology.org/operation_0481,Loop modelling, -http://edamontology.org/operation_0482,Protein-ligand docking, -http://edamontology.org/operation_0483,RNA inverse folding, -http://edamontology.org/operation_0484,SNP detection, -http://edamontology.org/operation_0485,Radiation Hybrid Mapping, -http://edamontology.org/operation_0486,Functional mapping, -http://edamontology.org/operation_0487,Haplotype mapping, -http://edamontology.org/operation_0488,Linkage disequilibrium calculation, -http://edamontology.org/operation_0489,Genetic code prediction, -http://edamontology.org/operation_0490,Dot plot plotting, -http://edamontology.org/operation_0491,Pairwise sequence alignment, -http://edamontology.org/operation_0492,Multiple sequence alignment, -http://edamontology.org/operation_0493,Pairwise sequence alignment generation (local), -http://edamontology.org/operation_0494,Pairwise sequence alignment generation (global), -http://edamontology.org/operation_0495,Local alignment, -http://edamontology.org/operation_0496,Global alignment, -http://edamontology.org/operation_0497,Constrained sequence alignment, -http://edamontology.org/operation_0498,Consensus-based sequence alignment, -http://edamontology.org/operation_0499,Tree-based sequence alignment, -http://edamontology.org/operation_0500,Secondary structure alignment generation, -http://edamontology.org/operation_0501,Protein secondary structure alignment generation, -http://edamontology.org/operation_0502,RNA secondary structure alignment, -http://edamontology.org/operation_0503,Pairwise structure alignment, -http://edamontology.org/operation_0504,Multiple structure alignment, -http://edamontology.org/operation_0505,Structure alignment (protein), -http://edamontology.org/operation_0506,Structure alignment (RNA), -http://edamontology.org/operation_0507,Pairwise structure alignment generation (local), -http://edamontology.org/operation_0508,Pairwise structure alignment generation (global), -http://edamontology.org/operation_0509,Local structure alignment, -http://edamontology.org/operation_0510,Global structure alignment, -http://edamontology.org/operation_0511,Profile-profile alignment (pairwise), -http://edamontology.org/operation_0512,Sequence alignment generation (multiple profile), -http://edamontology.org/operation_0513,3D profile-to-3D profile alignment (pairwise), -http://edamontology.org/operation_0514,Structural profile alignment generation (multiple), -http://edamontology.org/operation_0515,Data retrieval (tool metadata), -http://edamontology.org/operation_0516,Data retrieval (database metadata), -http://edamontology.org/operation_0517,PCR primer design (for large scale sequencing), -http://edamontology.org/operation_0518,PCR primer design (for genotyping polymorphisms), -http://edamontology.org/operation_0519,PCR primer design (for gene transcription profiling), -http://edamontology.org/operation_0520,PCR primer design (for conserved primers), -http://edamontology.org/operation_0521,PCR primer design (based on gene structure), -http://edamontology.org/operation_0522,PCR primer design (for methylation PCRs), -http://edamontology.org/operation_0523,Mapping assembly, -http://edamontology.org/operation_0524,De-novo assembly, -http://edamontology.org/operation_0525,Genome assembly, -http://edamontology.org/operation_0526,EST assembly, -http://edamontology.org/operation_0527,Sequence tag mapping, -http://edamontology.org/operation_0528,SAGE data processing, -http://edamontology.org/operation_0529,MPSS data processing, -http://edamontology.org/operation_0530,SBS data processing, -http://edamontology.org/operation_0531,Heat map generation, -http://edamontology.org/operation_0532,Gene expression profile analysis, -http://edamontology.org/operation_0533,Expression profile pathway mapping, -http://edamontology.org/operation_0534,Protein secondary structure assignment (from coordinate data), -http://edamontology.org/operation_0535,Protein secondary structure assignment (from CD data), -http://edamontology.org/operation_0536,Protein structure assignment (from X-ray crystallographic data), -http://edamontology.org/operation_0537,Protein structure assignment (from NMR data), -http://edamontology.org/operation_0538,Phylogenetic inference (data centric), -http://edamontology.org/operation_0539,Phylogenetic inference (method centric), -http://edamontology.org/operation_0540,Phylogenetic inference (from molecular sequences), -http://edamontology.org/operation_0541,Phylogenetic inference (from continuous quantitative characters), -http://edamontology.org/operation_0542,Phylogenetic inference (from gene frequencies), -http://edamontology.org/operation_0543,Phylogenetic inference (from polymorphism data), -http://edamontology.org/operation_0544,Species tree construction, -http://edamontology.org/operation_0545,Phylogenetic inference (parsimony methods), -http://edamontology.org/operation_0546,Phylogenetic inference (minimum distance methods), -http://edamontology.org/operation_0547,Phylogenetic inference (maximum likelihood and Bayesian methods), -http://edamontology.org/operation_0548,Phylogenetic inference (quartet methods), -http://edamontology.org/operation_0549,Phylogenetic inference (AI methods), -http://edamontology.org/operation_0550,DNA substitution modelling, -http://edamontology.org/operation_0551,Phylogenetic tree topology analysis, -http://edamontology.org/operation_0552,Phylogenetic tree bootstrapping, -http://edamontology.org/operation_0553,Gene tree construction, -http://edamontology.org/operation_0554,Allele frequency distribution analysis, -http://edamontology.org/operation_0555,Consensus tree construction, -http://edamontology.org/operation_0556,Phylogenetic sub/super tree construction, -http://edamontology.org/operation_0557,Phylogenetic tree distances calculation, -http://edamontology.org/operation_0558,Phylogenetic tree annotation, -http://edamontology.org/operation_0559,Immunogenicity prediction, -http://edamontology.org/operation_0560,DNA vaccine design, -http://edamontology.org/operation_0561,Sequence formatting, -http://edamontology.org/operation_0562,Sequence alignment formatting, -http://edamontology.org/operation_0563,Codon usage table formatting, -http://edamontology.org/operation_0564,Sequence visualisation, -http://edamontology.org/operation_0565,Sequence alignment visualisation, -http://edamontology.org/operation_0566,Sequence cluster visualisation, -http://edamontology.org/operation_0567,Phylogenetic tree visualisation, -http://edamontology.org/operation_0568,RNA secondary structure visualisation, -http://edamontology.org/operation_0569,Protein secondary structure visualisation, -http://edamontology.org/operation_0570,Structure visualisation, -http://edamontology.org/operation_0571,Expression data visualisation, -http://edamontology.org/operation_0572,Protein interaction network visualisation, -http://edamontology.org/operation_0573,Map drawing, -http://edamontology.org/operation_0574,Sequence motif rendering, -http://edamontology.org/operation_0575,Restriction map drawing, -http://edamontology.org/operation_0577,DNA linear map rendering, -http://edamontology.org/operation_0578,Plasmid map drawing, -http://edamontology.org/operation_0579,Operon drawing, -http://edamontology.org/operation_1768,Nucleic acid folding family identification, -http://edamontology.org/operation_1769,Nucleic acid folding energy calculation, -http://edamontology.org/operation_1774,Annotation retrieval, -http://edamontology.org/operation_1777,Protein function prediction, -http://edamontology.org/operation_1778,Protein function comparison, -http://edamontology.org/operation_1780,Sequence submission, -http://edamontology.org/operation_1781,Gene regulatory network analysis, -http://edamontology.org/operation_1812,Parsing, -http://edamontology.org/operation_1813,Sequence retrieval, -http://edamontology.org/operation_1814,Structure retrieval, -http://edamontology.org/operation_1816,Surface rendering, -http://edamontology.org/operation_1817,Protein atom surface calculation (accessible), -http://edamontology.org/operation_1818,Protein atom surface calculation (accessible molecular), -http://edamontology.org/operation_1819,Protein residue surface calculation (accessible), -http://edamontology.org/operation_1820,Protein residue surface calculation (vacuum accessible), -http://edamontology.org/operation_1821,Protein residue surface calculation (accessible molecular), -http://edamontology.org/operation_1822,Protein residue surface calculation (vacuum molecular), -http://edamontology.org/operation_1823,Protein surface calculation (accessible molecular), -http://edamontology.org/operation_1824,Protein surface calculation (accessible), -http://edamontology.org/operation_1825,Backbone torsion angle calculation, -http://edamontology.org/operation_1826,Full torsion angle calculation, -http://edamontology.org/operation_1827,Cysteine torsion angle calculation, -http://edamontology.org/operation_1828,Tau angle calculation, -http://edamontology.org/operation_1829,Cysteine bridge detection, -http://edamontology.org/operation_1830,Free cysteine detection, -http://edamontology.org/operation_1831,Metal-bound cysteine detection, -http://edamontology.org/operation_1832,Residue contact calculation (residue-nucleic acid), -http://edamontology.org/operation_1834,Protein-metal contact calculation, -http://edamontology.org/operation_1835,Residue contact calculation (residue-negative ion), -http://edamontology.org/operation_1836,Residue bump detection, -http://edamontology.org/operation_1837,Residue symmetry contact calculation, -http://edamontology.org/operation_1838,Residue contact calculation (residue-ligand), -http://edamontology.org/operation_1839,Salt bridge calculation, -http://edamontology.org/operation_1841,Rotamer likelihood prediction, -http://edamontology.org/operation_1842,Proline mutation value calculation, -http://edamontology.org/operation_1843,Residue packing validation, -http://edamontology.org/operation_1844,Protein geometry validation, -http://edamontology.org/operation_1845,PDB file sequence retrieval, -http://edamontology.org/operation_1846,HET group detection, -http://edamontology.org/operation_1847,DSSP secondary structure assignment, -http://edamontology.org/operation_1848,Structure formatting, -http://edamontology.org/operation_1850,Protein cysteine and disulfide bond assignment, -http://edamontology.org/operation_1913,Residue validation, -http://edamontology.org/operation_1914,Structure retrieval (water), -http://edamontology.org/operation_2008,siRNA duplex prediction, -http://edamontology.org/operation_2089,Sequence alignment refinement, -http://edamontology.org/operation_2120,Listfile processing, -http://edamontology.org/operation_2121,Sequence file editing, -http://edamontology.org/operation_2122,Sequence alignment file processing, -http://edamontology.org/operation_2123,Small molecule data processing, -http://edamontology.org/operation_2222,Data retrieval (ontology annotation), -http://edamontology.org/operation_2224,Data retrieval (ontology concept), -http://edamontology.org/operation_2233,Representative sequence identification, -http://edamontology.org/operation_2234,Structure file processing, -http://edamontology.org/operation_2237,Data retrieval (sequence profile), -http://edamontology.org/operation_2238,Statistical calculation, -http://edamontology.org/operation_2239,3D-1D scoring matrix generation, -http://edamontology.org/operation_2241,Transmembrane protein visualisation, -http://edamontology.org/operation_2246,Demonstration, -http://edamontology.org/operation_2264,Data retrieval (pathway or network), -http://edamontology.org/operation_2265,Data retrieval (identifier), -http://edamontology.org/operation_2284,Nucleic acid density plotting, -http://edamontology.org/operation_2403,Sequence analysis, -http://edamontology.org/operation_2404,Sequence motif analysis, -http://edamontology.org/operation_2405,Protein interaction data processing, -http://edamontology.org/operation_2406,Protein structure analysis, -http://edamontology.org/operation_2407,Annotation processing, -http://edamontology.org/operation_2408,Sequence feature analysis, -http://edamontology.org/operation_2409,Data handling, -http://edamontology.org/operation_2410,Gene expression analysis, -http://edamontology.org/operation_2411,Structural profile processing, -http://edamontology.org/operation_2412,Data index processing, -http://edamontology.org/operation_2413,Sequence profile processing, -http://edamontology.org/operation_2414,Protein function analysis, -http://edamontology.org/operation_2415,Protein folding analysis, -http://edamontology.org/operation_2416,Protein secondary structure analysis, -http://edamontology.org/operation_2417,Physicochemical property data processing, -http://edamontology.org/operation_2419,Primer and probe design, -http://edamontology.org/operation_2420,Operation (typed), -http://edamontology.org/operation_2421,Database search, -http://edamontology.org/operation_2422,Data retrieval, -http://edamontology.org/operation_2423,Prediction and recognition, -http://edamontology.org/operation_2424,Comparison, -http://edamontology.org/operation_2425,Optimisation and refinement, -http://edamontology.org/operation_2426,Modelling and simulation, -http://edamontology.org/operation_2427,Data handling, -http://edamontology.org/operation_2428,Validation, -http://edamontology.org/operation_2429,Mapping, -http://edamontology.org/operation_2430,Design, -http://edamontology.org/operation_2432,Microarray data processing, -http://edamontology.org/operation_2433,Codon usage table processing, -http://edamontology.org/operation_2434,Data retrieval (codon usage table), -http://edamontology.org/operation_2435,Gene expression profile processing, -http://edamontology.org/operation_2436,Gene-set enrichment analysis, -http://edamontology.org/operation_2437,Gene regulatory network prediction, -http://edamontology.org/operation_2438,Pathway or network processing, -http://edamontology.org/operation_2439,RNA secondary structure analysis, -http://edamontology.org/operation_2440,Structure processing (RNA), -http://edamontology.org/operation_2441,RNA structure prediction, -http://edamontology.org/operation_2442,DNA structure prediction, -http://edamontology.org/operation_2443,Phylogenetic tree processing, -http://edamontology.org/operation_2444,Protein secondary structure processing, -http://edamontology.org/operation_2445,Protein interaction network processing, -http://edamontology.org/operation_2446,Sequence processing, -http://edamontology.org/operation_2447,Sequence processing (protein), -http://edamontology.org/operation_2448,Sequence processing (nucleic acid), -http://edamontology.org/operation_2451,Sequence comparison, -http://edamontology.org/operation_2452,Sequence cluster processing, -http://edamontology.org/operation_2453,Feature table processing, -http://edamontology.org/operation_2454,Gene prediction, -http://edamontology.org/operation_2456,GPCR classification, -http://edamontology.org/operation_2457,GPCR coupling selectivity prediction, -http://edamontology.org/operation_2459,Structure processing (protein), -http://edamontology.org/operation_2460,Protein atom surface calculation, -http://edamontology.org/operation_2461,Protein residue surface calculation, -http://edamontology.org/operation_2462,Protein surface calculation, -http://edamontology.org/operation_2463,Sequence alignment processing, -http://edamontology.org/operation_2464,Protein-protein binding site prediction, -http://edamontology.org/operation_2465,Structure processing, -http://edamontology.org/operation_2466,Map annotation, -http://edamontology.org/operation_2467,Data retrieval (protein annotation), -http://edamontology.org/operation_2468,Data retrieval (phylogenetic tree), -http://edamontology.org/operation_2469,Data retrieval (protein interaction annotation), -http://edamontology.org/operation_2470,Data retrieval (protein family annotation), -http://edamontology.org/operation_2471,Data retrieval (RNA family annotation), -http://edamontology.org/operation_2472,Data retrieval (gene annotation), -http://edamontology.org/operation_2473,Data retrieval (genotype and phenotype annotation), -http://edamontology.org/operation_2474,Protein architecture comparison, -http://edamontology.org/operation_2475,Protein architecture recognition, -http://edamontology.org/operation_2476,Molecular dynamics, -http://edamontology.org/operation_2478,Nucleic acid sequence analysis, -http://edamontology.org/operation_2479,Protein sequence analysis, -http://edamontology.org/operation_2480,Structure analysis, -http://edamontology.org/operation_2481,Nucleic acid structure analysis, -http://edamontology.org/operation_2482,Secondary structure processing, -http://edamontology.org/operation_2483,Structure comparison, -http://edamontology.org/operation_2485,Helical wheel drawing, -http://edamontology.org/operation_2486,Topology diagram drawing, -http://edamontology.org/operation_2487,Protein structure comparison, -http://edamontology.org/operation_2488,Protein secondary structure comparison, -http://edamontology.org/operation_2489,Subcellular localisation prediction, -http://edamontology.org/operation_2490,Residue contact calculation (residue-residue), -http://edamontology.org/operation_2491,Hydrogen bond calculation (inter-residue), -http://edamontology.org/operation_2492,Protein interaction prediction, -http://edamontology.org/operation_2493,Codon usage data processing, -http://edamontology.org/operation_2495,Expression analysis, -http://edamontology.org/operation_2496,Gene regulatory network processing, -http://edamontology.org/operation_2497,Pathway or network analysis, -http://edamontology.org/operation_2498,Sequencing-based expression profile data analysis, -http://edamontology.org/operation_2499,Splicing analysis, -http://edamontology.org/operation_2500,Microarray raw data analysis, -http://edamontology.org/operation_2501,Nucleic acid analysis, -http://edamontology.org/operation_2502,Protein analysis, -http://edamontology.org/operation_2503,Sequence data processing, -http://edamontology.org/operation_2504,Structural data processing, -http://edamontology.org/operation_2505,Text processing, -http://edamontology.org/operation_2506,Protein sequence alignment analysis, -http://edamontology.org/operation_2507,Nucleic acid sequence alignment analysis, -http://edamontology.org/operation_2508,Nucleic acid sequence comparison, -http://edamontology.org/operation_2509,Protein sequence comparison, -http://edamontology.org/operation_2510,DNA back-translation, -http://edamontology.org/operation_2511,Sequence editing (nucleic acid), -http://edamontology.org/operation_2512,Sequence editing (protein), -http://edamontology.org/operation_2513,Sequence generation (nucleic acid), -http://edamontology.org/operation_2514,Sequence generation (protein), -http://edamontology.org/operation_2515,Nucleic acid sequence visualisation, -http://edamontology.org/operation_2516,Protein sequence visualisation, -http://edamontology.org/operation_2518,Nucleic acid structure comparison, -http://edamontology.org/operation_2519,Structure processing (nucleic acid), -http://edamontology.org/operation_2520,DNA mapping, -http://edamontology.org/operation_2521,Map data processing, -http://edamontology.org/operation_2574,Protein hydropathy calculation, -http://edamontology.org/operation_2575,Binding site prediction, -http://edamontology.org/operation_2844,Structure clustering, -http://edamontology.org/operation_2871,Sequence tagged site (STS) mapping, -http://edamontology.org/operation_2928,Alignment, -http://edamontology.org/operation_2929,Protein fragment weight comparison, -http://edamontology.org/operation_2930,Protein property comparison, -http://edamontology.org/operation_2931,Secondary structure comparison, -http://edamontology.org/operation_2932,Hopp and Woods plotting, -http://edamontology.org/operation_2934,Cluster textual view generation, -http://edamontology.org/operation_2935,Clustering profile plotting, -http://edamontology.org/operation_2936,Dendrograph plotting, -http://edamontology.org/operation_2937,Proximity map plotting, -http://edamontology.org/operation_2938,Dendrogram visualisation, -http://edamontology.org/operation_2939,Principal component visualisation, -http://edamontology.org/operation_2940,Scatter plot plotting, -http://edamontology.org/operation_2941,Whole microarray graph plotting, -http://edamontology.org/operation_2942,Treemap visualisation, -http://edamontology.org/operation_2943,Box-Whisker plot plotting, -http://edamontology.org/operation_2944,Physical mapping, -http://edamontology.org/operation_2945,Analysis, -http://edamontology.org/operation_2946,Alignment analysis, -http://edamontology.org/operation_2947,Article analysis, -http://edamontology.org/operation_2948,Molecular interaction analysis, -http://edamontology.org/operation_2949,Protein-protein interaction analysis, -http://edamontology.org/operation_2950,Residue distance calculation, -http://edamontology.org/operation_2951,Alignment processing, -http://edamontology.org/operation_2952,Structure alignment processing, -http://edamontology.org/operation_2962,Codon usage bias calculation, -http://edamontology.org/operation_2963,Codon usage bias plotting, -http://edamontology.org/operation_2964,Codon usage fraction calculation, -http://edamontology.org/operation_2990,Classification, -http://edamontology.org/operation_2993,Molecular interaction data processing, -http://edamontology.org/operation_2995,Sequence classification, -http://edamontology.org/operation_2996,Structure classification, -http://edamontology.org/operation_2997,Protein comparison, -http://edamontology.org/operation_2998,Nucleic acid comparison, -http://edamontology.org/operation_3023,Prediction and recognition (protein), -http://edamontology.org/operation_3024,Prediction and recognition (nucleic acid), -http://edamontology.org/operation_3080,Structure editing, -http://edamontology.org/operation_3081,Sequence alignment editing, -http://edamontology.org/operation_3083,Pathway or network visualisation, -http://edamontology.org/operation_3084,Protein function prediction (from sequence), -http://edamontology.org/operation_3087,Protein sequence feature detection, -http://edamontology.org/operation_3088,Protein property calculation (from sequence), -http://edamontology.org/operation_3090,Protein feature prediction (from structure), -http://edamontology.org/operation_3092,Protein feature detection, -http://edamontology.org/operation_3093,Database search (by sequence), -http://edamontology.org/operation_3094,Protein interaction network prediction, -http://edamontology.org/operation_3095,Nucleic acid design, -http://edamontology.org/operation_3096,Editing, -http://edamontology.org/operation_3180,Sequence assembly validation, -http://edamontology.org/operation_3182,Genome alignment, -http://edamontology.org/operation_3183,Localised reassembly, -http://edamontology.org/operation_3184,Sequence assembly visualisation, -http://edamontology.org/operation_3185,Base-calling, -http://edamontology.org/operation_3186,Bisulfite mapping, -http://edamontology.org/operation_3187,Sequence contamination filtering, -http://edamontology.org/operation_3189,Trim ends, -http://edamontology.org/operation_3190,Trim vector, -http://edamontology.org/operation_3191,Trim to reference, -http://edamontology.org/operation_3192,Sequence trimming, -http://edamontology.org/operation_3194,Genome feature comparison, -http://edamontology.org/operation_3195,Sequencing error detection, -http://edamontology.org/operation_3196,Genotyping, -http://edamontology.org/operation_3197,Genetic variation analysis, -http://edamontology.org/operation_3198,Read mapping, -http://edamontology.org/operation_3199,Split read mapping, -http://edamontology.org/operation_3200,DNA barcoding, -http://edamontology.org/operation_3201,SNP calling, -http://edamontology.org/operation_3202,Polymorphism detection, -http://edamontology.org/operation_3203,Chromatogram visualisation, -http://edamontology.org/operation_3204,Methylation analysis, -http://edamontology.org/operation_3205,Methylation calling, -http://edamontology.org/operation_3206,Whole genome methylation analysis, -http://edamontology.org/operation_3207,Gene methylation analysis, -http://edamontology.org/operation_3208,Genome visualisation, -http://edamontology.org/operation_3209,Genome comparison, -http://edamontology.org/operation_3211,Genome indexing, -http://edamontology.org/operation_3212,Genome indexing (Burrows-Wheeler), -http://edamontology.org/operation_3213,Genome indexing (suffix arrays), -http://edamontology.org/operation_3214,Spectral analysis, -http://edamontology.org/operation_3215,Peak detection, -http://edamontology.org/operation_3216,Scaffolding, -http://edamontology.org/operation_3217,Scaffold gap completion, -http://edamontology.org/operation_3218,Sequencing quality control, -http://edamontology.org/operation_3219,Read pre-processing, -http://edamontology.org/operation_3221,Species frequency estimation, -http://edamontology.org/operation_3222,Peak calling, -http://edamontology.org/operation_3223,Differential gene expression profiling, -http://edamontology.org/operation_3224,Gene set testing, -http://edamontology.org/operation_3225,Variant classification, -http://edamontology.org/operation_3226,Variant prioritisation, -http://edamontology.org/operation_3227,Variant calling, -http://edamontology.org/operation_3228,Structural variation detection, -http://edamontology.org/operation_3229,Exome assembly, -http://edamontology.org/operation_3230,Read depth analysis, -http://edamontology.org/operation_3232,Gene expression QTL analysis, -http://edamontology.org/operation_3233,Copy number estimation, -http://edamontology.org/operation_3237,Primer removal, -http://edamontology.org/operation_3258,Transcriptome assembly, -http://edamontology.org/operation_3259,Transcriptome assembly (de novo), -http://edamontology.org/operation_3260,Transcriptome assembly (mapping), -http://edamontology.org/operation_3267,Sequence coordinate conversion, -http://edamontology.org/operation_3278,Document similarity calculation, -http://edamontology.org/operation_3279,Document clustering, -http://edamontology.org/operation_3280,Named-entity and concept recognition, -http://edamontology.org/operation_3282,ID mapping, -http://edamontology.org/operation_3283,Anonymisation, -http://edamontology.org/operation_3289,ID retrieval, -http://edamontology.org/operation_3348,Sequence checksum generation, -http://edamontology.org/operation_3349,Bibliography generation, -http://edamontology.org/operation_3350,Protein quaternary structure prediction, -http://edamontology.org/operation_3351,Molecular surface analysis, -http://edamontology.org/operation_3352,Ontology comparison, -http://edamontology.org/operation_3353,Ontology comparison, -http://edamontology.org/operation_3357,Format detection, -http://edamontology.org/operation_3359,Splitting, -http://edamontology.org/operation_3429,Generation, -http://edamontology.org/operation_3430,Nucleic acid sequence feature detection, -http://edamontology.org/operation_3431,Deposition, -http://edamontology.org/operation_3432,Clustering, -http://edamontology.org/operation_3433,Assembly, -http://edamontology.org/operation_3434,Conversion, -http://edamontology.org/operation_3435,Standardisation and normalisation, -http://edamontology.org/operation_3436,Aggregation, -http://edamontology.org/operation_3437,Article comparison, -http://edamontology.org/operation_3438,Calculation, -http://edamontology.org/operation_3439,Pathway or network prediction, -http://edamontology.org/operation_3440,Genome assembly, -http://edamontology.org/operation_3441,Plotting, -http://edamontology.org/operation_3443,Image analysis, -http://edamontology.org/operation_3445,Diffraction data analysis, -http://edamontology.org/operation_3446,Cell migration analysis, -http://edamontology.org/operation_3447,Diffraction data reduction, -http://edamontology.org/operation_3450,Neurite measurement, -http://edamontology.org/operation_3453,Diffraction data integration, -http://edamontology.org/operation_3454,Phasing, -http://edamontology.org/operation_3455,Molecular replacement, -http://edamontology.org/operation_3456,Rigid body refinement, -http://edamontology.org/operation_3457,Single particle analysis, -http://edamontology.org/operation_3458,Single particle alignment and classification, -http://edamontology.org/operation_3459,Functional clustering, -http://edamontology.org/operation_3460,Taxonomic classification, -http://edamontology.org/operation_3461,Virulence prediction, -http://edamontology.org/operation_3463,Expression correlation analysis, -http://edamontology.org/operation_3465,Correlation, -http://edamontology.org/operation_3469,RNA structure covariance model generation, -http://edamontology.org/operation_3470,RNA secondary structure prediction (shape-based), -http://edamontology.org/operation_3471,Nucleic acid folding prediction (alignment-based), -http://edamontology.org/operation_3472,k-mer counting, -http://edamontology.org/operation_3478,Phylogenetic reconstruction, -http://edamontology.org/operation_3480,Probabilistic data generation, -http://edamontology.org/operation_3481,Probabilistic sequence generation, -http://edamontology.org/operation_3482,Antimicrobial resistance prediction, -http://edamontology.org/operation_3501,Enrichment analysis, -http://edamontology.org/operation_3502,Chemical similarity enrichment, -http://edamontology.org/operation_3503,Incident curve plotting, -http://edamontology.org/operation_3504,Variant pattern analysis, -http://edamontology.org/operation_3545,Mathematical modelling, -http://edamontology.org/operation_3552,Microscope image visualisation, -http://edamontology.org/operation_3553,Image annotation, -http://edamontology.org/operation_3557,Imputation, -http://edamontology.org/operation_3559,Ontology visualisation, -http://edamontology.org/operation_3560,Maximum occurence analysis, -http://edamontology.org/operation_3561,Database comparison, -http://edamontology.org/operation_3562,Network simulation, -http://edamontology.org/operation_3563,RNA-seq read count analysis, -http://edamontology.org/operation_3564,Chemical redundancy removal, -http://edamontology.org/operation_3565,RNA-seq time series data analysis, -http://edamontology.org/operation_3566,Simulated gene expression data generation, -http://edamontology.org/operation_3625,Relation extraction, -http://edamontology.org/operation_3627,Mass spectra calibration, -http://edamontology.org/operation_3628,Chromatographic alignment, -http://edamontology.org/operation_3629,Deisotoping, -http://edamontology.org/operation_3630,Protein quantification, -http://edamontology.org/operation_3631,Peptide identification, -http://edamontology.org/operation_3632,Isotopic distributions calculation, -http://edamontology.org/operation_3633,Retention time prediction, -http://edamontology.org/operation_3634,Label-free quantification, -http://edamontology.org/operation_3635,Labeled quantification, -http://edamontology.org/operation_3636,MRM/SRM, -http://edamontology.org/operation_3637,Spectral counting, -http://edamontology.org/operation_3638,SILAC, -http://edamontology.org/operation_3639,iTRAQ, -http://edamontology.org/operation_3640,18O labeling, -http://edamontology.org/operation_3641,TMT-tag, -http://edamontology.org/operation_3642,Dimethyl, -http://edamontology.org/operation_3643,Tag-based peptide identification, -http://edamontology.org/operation_3644,de Novo sequencing, -http://edamontology.org/operation_3645,PTM identification, -http://edamontology.org/operation_3646,Peptide database search, -http://edamontology.org/operation_3647,Blind peptide database search, -http://edamontology.org/operation_3648,Validation of peptide-spectrum matches, -http://edamontology.org/operation_3649,Target-Decoy, -http://edamontology.org/operation_3658,Statistical inference, -http://edamontology.org/operation_3659,Regression analysis, -http://edamontology.org/operation_3660,Metabolic network modelling, -http://edamontology.org/operation_3661,SNP annotation, -http://edamontology.org/operation_3662,Ab-initio gene prediction, -http://edamontology.org/operation_3663,Homology-based gene prediction, -http://edamontology.org/operation_3664,Statistical modelling, -http://edamontology.org/operation_3666,Molecular surface comparison, -http://edamontology.org/operation_3672,Gene functional annotation, -http://edamontology.org/operation_3675,Variant filtering, -http://edamontology.org/operation_3677,Differential binding analysis, -http://edamontology.org/operation_3680,RNA-Seq analysis, -http://edamontology.org/operation_3694,Mass spectrum visualisation, -http://edamontology.org/operation_3695,Filtering, -http://edamontology.org/operation_3703,Reference identification, -http://edamontology.org/operation_3704,Ion counting, -http://edamontology.org/operation_3705,Isotope-coded protein label, -http://edamontology.org/operation_3715,Metabolic labeling, -http://edamontology.org/operation_3730,Cross-assembly, -http://edamontology.org/operation_3731,Sample comparison, -http://edamontology.org/operation_3741,Differential protein expression profiling, -http://edamontology.org/operation_3742,Differential gene expression analysis, -http://edamontology.org/operation_3744,Multiple sample visualisation, -http://edamontology.org/operation_3745,Ancestral reconstruction, -http://edamontology.org/operation_3755,PTM localisation, -http://edamontology.org/operation_3760,Service management, -http://edamontology.org/operation_3761,Service discovery, -http://edamontology.org/operation_3762,Service composition, -http://edamontology.org/operation_3763,Service invocation, -http://edamontology.org/operation_3766,Weighted correlation network analysis, -http://edamontology.org/operation_3767,Protein identification, -http://edamontology.org/operation_3778,Text annotation, -http://edamontology.org/operation_3791,Collapsing methods, -http://edamontology.org/operation_3792,miRNA expression analysis, -http://edamontology.org/operation_3793,Read summarisation, -http://edamontology.org/operation_3795,In vitro selection, -http://edamontology.org/operation_3797,Rarefaction, -http://edamontology.org/operation_3798,Read binning, -http://edamontology.org/operation_3799,Quantification, -http://edamontology.org/operation_3800,RNA-Seq quantification, -http://edamontology.org/operation_3801,Spectral library search, -http://edamontology.org/operation_3802,Sorting, -http://edamontology.org/operation_3803,Natural product identification, -http://edamontology.org/operation_3809,DMR identification, -http://edamontology.org/operation_3840,Multilocus sequence typing, -http://edamontology.org/operation_3860,Spectrum calculation, -http://edamontology.org/operation_3890,Trajectory visualization, -http://edamontology.org/operation_3891,Essential dynamics, -http://edamontology.org/operation_3893,Forcefield parameterisation, -http://edamontology.org/operation_3894,DNA profiling, -http://edamontology.org/operation_3896,Active site prediction, -http://edamontology.org/operation_3897,Ligand-binding site prediction, -http://edamontology.org/operation_3898,Metal-binding site prediction, -http://edamontology.org/operation_3899,Protein-protein docking, -http://edamontology.org/operation_3900,DNA-binding protein prediction, -http://edamontology.org/operation_3901,RNA-binding protein prediction, -http://edamontology.org/operation_3902,RNA binding site prediction, -http://edamontology.org/operation_3903,DNA binding site prediction, -http://edamontology.org/operation_3904,Protein disorder prediction, -http://edamontology.org/operation_3907,Information extraction, -http://edamontology.org/operation_3908,Information retrieval, -http://edamontology.org/operation_3918,Genome analysis, -http://edamontology.org/operation_3919,Methylation calling, -http://edamontology.org/operation_3920,DNA testing, -http://edamontology.org/operation_3921,Sequence read processing, -http://edamontology.org/operation_3923,Genome resequencing, -http://edamontology.org/operation_3925,Network visualisation, -http://edamontology.org/operation_3926,Pathway visualisation, -http://edamontology.org/operation_3927,Network analysis, -http://edamontology.org/operation_3928,Pathway analysis, -http://edamontology.org/operation_3929,Metabolic pathway prediction, -http://edamontology.org/operation_3931,Chemometrics, -http://edamontology.org/operation_3933,Demultiplexing, -http://edamontology.org/operation_3935,Dimensionality reduction, -http://edamontology.org/operation_3936,Feature selection, -http://edamontology.org/operation_3937,Feature extraction, -http://edamontology.org/operation_3938,Virtual screening, -http://edamontology.org/operation_3939,Metabolic engineering, -http://edamontology.org/operation_3942,Tree dating, -http://edamontology.org/operation_3946,Ecological modelling, -http://edamontology.org/operation_3947,Phylogenetic tree reconciliation, -http://edamontology.org/operation_3950,Selection detection, -http://edamontology.org/operation_3960,Principal component analysis, -http://edamontology.org/operation_3961,Copy number variation detection, -http://edamontology.org/operation_3962,Deletion detection, -http://edamontology.org/operation_3963,Duplication detection, -http://edamontology.org/operation_3964,Complex CNV detection, -http://edamontology.org/operation_3965,Amplification detection, -http://edamontology.org/operation_3968,Adhesin prediction, -http://edamontology.org/operation_4008,Protein design, -http://edamontology.org/operation_4009,Small molecule design, -http://edamontology.org/topic_0003,Topic, -http://edamontology.org/topic_0077,Nucleic acids, -http://edamontology.org/topic_0078,Proteins, -http://edamontology.org/topic_0079,Metabolites, -http://edamontology.org/topic_0080,Sequence analysis, -http://edamontology.org/topic_0081,Structure analysis, -http://edamontology.org/topic_0082,Structure prediction, -http://edamontology.org/topic_0083,Alignment, -http://edamontology.org/topic_0084,Phylogeny, -http://edamontology.org/topic_0085,Functional genomics, -http://edamontology.org/topic_0089,Ontology and terminology, -http://edamontology.org/topic_0090,Information retrieval, -http://edamontology.org/topic_0091,Bioinformatics, -http://edamontology.org/topic_0092,Data visualisation, -http://edamontology.org/topic_0094,Nucleic acid thermodynamics, -http://edamontology.org/topic_0097,Nucleic acid structure analysis, -http://edamontology.org/topic_0099,RNA, -http://edamontology.org/topic_0100,Nucleic acid restriction, -http://edamontology.org/topic_0102,Mapping, -http://edamontology.org/topic_0107,Genetic codes and codon usage, -http://edamontology.org/topic_0108,Protein expression, -http://edamontology.org/topic_0109,Gene finding, -http://edamontology.org/topic_0110,Transcription, -http://edamontology.org/topic_0111,Promoters, -http://edamontology.org/topic_0112,Nucleic acid folding, -http://edamontology.org/topic_0114,Gene structure, -http://edamontology.org/topic_0121,Proteomics, -http://edamontology.org/topic_0122,Structural genomics, -http://edamontology.org/topic_0123,Protein properties, -http://edamontology.org/topic_0128,Protein interactions, -http://edamontology.org/topic_0130,"Protein folding, stability and design", -http://edamontology.org/topic_0133,Two-dimensional gel electrophoresis, -http://edamontology.org/topic_0134,Mass spectrometry, -http://edamontology.org/topic_0135,Protein microarrays, -http://edamontology.org/topic_0137,Protein hydropathy, -http://edamontology.org/topic_0140,Protein targeting and localisation, -http://edamontology.org/topic_0141,Protein cleavage sites and proteolysis, -http://edamontology.org/topic_0143,Protein structure comparison, -http://edamontology.org/topic_0144,Protein residue interactions, -http://edamontology.org/topic_0147,Protein-protein interactions, -http://edamontology.org/topic_0148,Protein-ligand interactions, -http://edamontology.org/topic_0149,Protein-nucleic acid interactions, -http://edamontology.org/topic_0150,Protein design, -http://edamontology.org/topic_0151,G protein-coupled receptors (GPCR), -http://edamontology.org/topic_0152,Carbohydrates, -http://edamontology.org/topic_0153,Lipids, -http://edamontology.org/topic_0154,Small molecules, -http://edamontology.org/topic_0156,Sequence editing, -http://edamontology.org/topic_0157,"Sequence composition, complexity and repeats", -http://edamontology.org/topic_0158,Sequence motifs, -http://edamontology.org/topic_0159,Sequence comparison, -http://edamontology.org/topic_0160,"Sequence sites, features and motifs", -http://edamontology.org/topic_0163,Sequence database search, -http://edamontology.org/topic_0164,Sequence clustering, -http://edamontology.org/topic_0166,Protein structural motifs and surfaces, -http://edamontology.org/topic_0167,Structural (3D) profiles, -http://edamontology.org/topic_0172,Protein structure prediction, -http://edamontology.org/topic_0173,Nucleic acid structure prediction, -http://edamontology.org/topic_0174,Ab initio structure prediction, -http://edamontology.org/topic_0175,Homology modelling, -http://edamontology.org/topic_0176,Molecular dynamics, -http://edamontology.org/topic_0177,Molecular docking, -http://edamontology.org/topic_0178,Protein secondary structure prediction, -http://edamontology.org/topic_0179,Protein tertiary structure prediction, -http://edamontology.org/topic_0180,Protein fold recognition, -http://edamontology.org/topic_0182,Sequence alignment, -http://edamontology.org/topic_0183,Structure alignment, -http://edamontology.org/topic_0184,Threading, -http://edamontology.org/topic_0188,Sequence profiles and HMMs, -http://edamontology.org/topic_0191,Phylogeny reconstruction, -http://edamontology.org/topic_0194,Phylogenomics, -http://edamontology.org/topic_0195,Virtual PCR, -http://edamontology.org/topic_0196,Sequence assembly, -http://edamontology.org/topic_0199,Genetic variation, -http://edamontology.org/topic_0200,Microarrays, -http://edamontology.org/topic_0202,Pharmacology, -http://edamontology.org/topic_0203,Gene expression, -http://edamontology.org/topic_0204,Gene regulation, -http://edamontology.org/topic_0208,Pharmacogenomics, -http://edamontology.org/topic_0209,Medicinal chemistry, -http://edamontology.org/topic_0210,Fish, -http://edamontology.org/topic_0211,Flies, -http://edamontology.org/topic_0213,Mice or rats, -http://edamontology.org/topic_0215,Worms, -http://edamontology.org/topic_0217,Literature analysis, -http://edamontology.org/topic_0218,Natural language processing, -http://edamontology.org/topic_0219,"Data submission, annotation and curation", -http://edamontology.org/topic_0220,"Document, record and content management", -http://edamontology.org/topic_0221,Sequence annotation, -http://edamontology.org/topic_0222,Genome annotation, -http://edamontology.org/topic_0593,NMR, -http://edamontology.org/topic_0594,Sequence classification, -http://edamontology.org/topic_0595,Protein classification, -http://edamontology.org/topic_0598,Sequence motif or profile, -http://edamontology.org/topic_0601,Protein modifications, -http://edamontology.org/topic_0602,"Molecular interactions, pathways and networks", -http://edamontology.org/topic_0605,Informatics, -http://edamontology.org/topic_0606,Literature data resources, -http://edamontology.org/topic_0607,Laboratory information management, -http://edamontology.org/topic_0608,Cell and tissue culture, -http://edamontology.org/topic_0610,Ecology, -http://edamontology.org/topic_0611,Electron microscopy, -http://edamontology.org/topic_0612,Cell cycle, -http://edamontology.org/topic_0613,Peptides and amino acids, -http://edamontology.org/topic_0616,Organelles, -http://edamontology.org/topic_0617,Ribosomes, -http://edamontology.org/topic_0618,Scents, -http://edamontology.org/topic_0620,Drugs and target structures, -http://edamontology.org/topic_0621,Model organisms, -http://edamontology.org/topic_0622,Genomics, -http://edamontology.org/topic_0623,Gene and protein families, -http://edamontology.org/topic_0624,Chromosomes, -http://edamontology.org/topic_0625,Genotype and phenotype, -http://edamontology.org/topic_0629,Gene expression and microarray, -http://edamontology.org/topic_0632,Probes and primers, -http://edamontology.org/topic_0634,Pathology, -http://edamontology.org/topic_0635,Specific protein resources, -http://edamontology.org/topic_0637,Taxonomy, -http://edamontology.org/topic_0639,Protein sequence analysis, -http://edamontology.org/topic_0640,Nucleic acid sequence analysis, -http://edamontology.org/topic_0641,Repeat sequences, -http://edamontology.org/topic_0642,Low complexity sequences, -http://edamontology.org/topic_0644,Proteome, -http://edamontology.org/topic_0654,DNA, -http://edamontology.org/topic_0655,Coding RNA, -http://edamontology.org/topic_0659,"Functional, regulatory and non-coding RNA", -http://edamontology.org/topic_0660,rRNA, -http://edamontology.org/topic_0663,tRNA, -http://edamontology.org/topic_0694,Protein secondary structure, -http://edamontology.org/topic_0697,RNA structure, -http://edamontology.org/topic_0698,Protein tertiary structure, -http://edamontology.org/topic_0722,Nucleic acid classification, -http://edamontology.org/topic_0724,Protein families, -http://edamontology.org/topic_0736,Protein folds and structural domains, -http://edamontology.org/topic_0740,Nucleic acid sequence alignment, -http://edamontology.org/topic_0741,Protein sequence alignment, -http://edamontology.org/topic_0747,Nucleic acid sites and features, -http://edamontology.org/topic_0748,Protein sites and features, -http://edamontology.org/topic_0749,Transcription factors and regulatory sites, -http://edamontology.org/topic_0751,Phosphorylation sites, -http://edamontology.org/topic_0753,Metabolic pathways, -http://edamontology.org/topic_0754,Signaling pathways, -http://edamontology.org/topic_0767,Protein and peptide identification, -http://edamontology.org/topic_0769,Workflows, -http://edamontology.org/topic_0770,Data types and objects, -http://edamontology.org/topic_0771,Theoretical biology, -http://edamontology.org/topic_0779,Mitochondria, -http://edamontology.org/topic_0780,Plant biology, -http://edamontology.org/topic_0781,Virology, -http://edamontology.org/topic_0782,Fungi, -http://edamontology.org/topic_0783,Pathogens, -http://edamontology.org/topic_0786,Arabidopsis, -http://edamontology.org/topic_0787,Rice, -http://edamontology.org/topic_0796,Genetic mapping and linkage, -http://edamontology.org/topic_0797,Comparative genomics, -http://edamontology.org/topic_0798,Mobile genetic elements, -http://edamontology.org/topic_0803,Human disease, -http://edamontology.org/topic_0804,Immunology, -http://edamontology.org/topic_0820,Membrane and lipoproteins, -http://edamontology.org/topic_0821,Enzymes, -http://edamontology.org/topic_0922,Primers, -http://edamontology.org/topic_1302,PolyA signal or sites, -http://edamontology.org/topic_1304,CpG island and isochores, -http://edamontology.org/topic_1305,Restriction sites, -http://edamontology.org/topic_1307,Splice sites, -http://edamontology.org/topic_1308,Matrix/scaffold attachment sites, -http://edamontology.org/topic_1311,Operon, -http://edamontology.org/topic_1312,Promoters, -http://edamontology.org/topic_1317,Structural biology, -http://edamontology.org/topic_1456,Protein membrane regions, -http://edamontology.org/topic_1770,Structure comparison, -http://edamontology.org/topic_1775,Function analysis, -http://edamontology.org/topic_1811,Prokaryotes and Archaea, -http://edamontology.org/topic_2225,Protein databases, -http://edamontology.org/topic_2226,Structure determination, -http://edamontology.org/topic_2229,Cell biology, -http://edamontology.org/topic_2230,Classification, -http://edamontology.org/topic_2232,Lipoproteins, -http://edamontology.org/topic_2257,Phylogeny visualisation, -http://edamontology.org/topic_2258,Cheminformatics, -http://edamontology.org/topic_2259,Systems biology, -http://edamontology.org/topic_2269,Statistics and probability, -http://edamontology.org/topic_2271,Structure database search, -http://edamontology.org/topic_2275,Molecular modelling, -http://edamontology.org/topic_2276,Protein function prediction, -http://edamontology.org/topic_2277,SNP, -http://edamontology.org/topic_2278,Transmembrane protein prediction, -http://edamontology.org/topic_2280,Nucleic acid structure comparison, -http://edamontology.org/topic_2397,Exons, -http://edamontology.org/topic_2399,Gene transcription, -http://edamontology.org/topic_2533,DNA mutation, -http://edamontology.org/topic_2640,Oncology, -http://edamontology.org/topic_2661,Toxins and targets, -http://edamontology.org/topic_2754,Introns, -http://edamontology.org/topic_2807,Tool topic, -http://edamontology.org/topic_2809,Study topic, -http://edamontology.org/topic_2811,Nomenclature, -http://edamontology.org/topic_2813,Disease genes and proteins, -http://edamontology.org/topic_2814,Protein structure analysis, -http://edamontology.org/topic_2815,Human biology, -http://edamontology.org/topic_2816,Gene resources, -http://edamontology.org/topic_2817,Yeast, -http://edamontology.org/topic_2818,Eukaryotes, -http://edamontology.org/topic_2819,Invertebrates, -http://edamontology.org/topic_2820,Vertebrates, -http://edamontology.org/topic_2821,Unicellular eukaryotes, -http://edamontology.org/topic_2826,Protein structure alignment, -http://edamontology.org/topic_2828,X-ray diffraction, -http://edamontology.org/topic_2829,"Ontologies, nomenclature and classification", -http://edamontology.org/topic_2830,Immunoproteins and antigens, -http://edamontology.org/topic_2839,Molecules, -http://edamontology.org/topic_2840,Toxicology, -http://edamontology.org/topic_2842,High-throughput sequencing, -http://edamontology.org/topic_2846,Gene regulatory networks, -http://edamontology.org/topic_2847,Disease (specific), -http://edamontology.org/topic_2867,VNTR, -http://edamontology.org/topic_2868,Microsatellites, -http://edamontology.org/topic_2869,RFLP, -http://edamontology.org/topic_2885,DNA polymorphism, -http://edamontology.org/topic_2953,Nucleic acid design, -http://edamontology.org/topic_3032,Primer or probe design, -http://edamontology.org/topic_3038,Structure databases, -http://edamontology.org/topic_3039,Nucleic acid structure, -http://edamontology.org/topic_3041,Sequence databases, -http://edamontology.org/topic_3042,Nucleic acid sequences, -http://edamontology.org/topic_3043,Protein sequences, -http://edamontology.org/topic_3044,Protein interaction networks, -http://edamontology.org/topic_3047,Molecular biology, -http://edamontology.org/topic_3048,Mammals, -http://edamontology.org/topic_3050,Biodiversity, -http://edamontology.org/topic_3052,Sequence clusters and classification, -http://edamontology.org/topic_3053,Genetics, -http://edamontology.org/topic_3055,Quantitative genetics, -http://edamontology.org/topic_3056,Population genetics, -http://edamontology.org/topic_3060,Regulatory RNA, -http://edamontology.org/topic_3061,Documentation and help, -http://edamontology.org/topic_3062,Genetic organisation, -http://edamontology.org/topic_3063,Medical informatics, -http://edamontology.org/topic_3064,Developmental biology, -http://edamontology.org/topic_3065,Embryology, -http://edamontology.org/topic_3067,Anatomy, -http://edamontology.org/topic_3068,Literature and language, -http://edamontology.org/topic_3070,Biology, -http://edamontology.org/topic_3071,Biological databases, -http://edamontology.org/topic_3072,Sequence feature detection, -http://edamontology.org/topic_3073,Nucleic acid feature detection, -http://edamontology.org/topic_3074,Protein feature detection, -http://edamontology.org/topic_3075,Biological system modelling, -http://edamontology.org/topic_3077,Data acquisition, -http://edamontology.org/topic_3078,Genes and proteins resources, -http://edamontology.org/topic_3118,Protein topological domains, -http://edamontology.org/topic_3120,Protein variants, -http://edamontology.org/topic_3123,Expression signals, -http://edamontology.org/topic_3125,DNA binding sites, -http://edamontology.org/topic_3126,Nucleic acid repeats, -http://edamontology.org/topic_3127,DNA replication and recombination, -http://edamontology.org/topic_3135,Signal or transit peptide, -http://edamontology.org/topic_3139,Sequence tagged sites, -http://edamontology.org/topic_3168,Sequencing, -http://edamontology.org/topic_3169,ChIP-seq, -http://edamontology.org/topic_3170,RNA-Seq, -http://edamontology.org/topic_3171,DNA methylation, -http://edamontology.org/topic_3172,Metabolomics, -http://edamontology.org/topic_3173,Epigenomics, -http://edamontology.org/topic_3174,Metagenomics, -http://edamontology.org/topic_3175,Structural variation, -http://edamontology.org/topic_3176,DNA packaging, -http://edamontology.org/topic_3177,DNA-Seq, -http://edamontology.org/topic_3178,RNA-Seq alignment, -http://edamontology.org/topic_3179,ChIP-on-chip, -http://edamontology.org/topic_3263,Data security, -http://edamontology.org/topic_3277,Sample collections, -http://edamontology.org/topic_3292,Biochemistry, -http://edamontology.org/topic_3293,Phylogenetics, -http://edamontology.org/topic_3295,Epigenetics, -http://edamontology.org/topic_3297,Biotechnology, -http://edamontology.org/topic_3298,Phenomics, -http://edamontology.org/topic_3299,Evolutionary biology, -http://edamontology.org/topic_3300,Physiology, -http://edamontology.org/topic_3301,Microbiology, -http://edamontology.org/topic_3302,Parasitology, -http://edamontology.org/topic_3303,Medicine, -http://edamontology.org/topic_3304,Neurobiology, -http://edamontology.org/topic_3305,Public health and epidemiology, -http://edamontology.org/topic_3306,Biophysics, -http://edamontology.org/topic_3307,Computational biology, -http://edamontology.org/topic_3308,Transcriptomics, -http://edamontology.org/topic_3314,Chemistry, -http://edamontology.org/topic_3315,Mathematics, -http://edamontology.org/topic_3316,Computer science, -http://edamontology.org/topic_3318,Physics, -http://edamontology.org/topic_3320,RNA splicing, -http://edamontology.org/topic_3321,Molecular genetics, -http://edamontology.org/topic_3322,Respiratory medicine, -http://edamontology.org/topic_3323,Metabolic disease, -http://edamontology.org/topic_3324,Infectious disease, -http://edamontology.org/topic_3325,Rare diseases, -http://edamontology.org/topic_3332,Computational chemistry, -http://edamontology.org/topic_3334,Neurology, -http://edamontology.org/topic_3335,Cardiology, -http://edamontology.org/topic_3336,Drug discovery, -http://edamontology.org/topic_3337,Biobank, -http://edamontology.org/topic_3338,Mouse clinic, -http://edamontology.org/topic_3339,Microbial collection, -http://edamontology.org/topic_3340,Cell culture collection, -http://edamontology.org/topic_3341,Clone library, -http://edamontology.org/topic_3342,Translational medicine, -http://edamontology.org/topic_3343,Compound libraries and screening, -http://edamontology.org/topic_3344,Biomedical science, -http://edamontology.org/topic_3345,Data identity and mapping, -http://edamontology.org/topic_3346,Sequence search, -http://edamontology.org/topic_3360,Biomarkers, -http://edamontology.org/topic_3361,Laboratory techniques, -http://edamontology.org/topic_3365,"Data architecture, analysis and design", -http://edamontology.org/topic_3366,Data integration and warehousing, -http://edamontology.org/topic_3368,Biomaterials, -http://edamontology.org/topic_3369,Chemical biology, -http://edamontology.org/topic_3370,Analytical chemistry, -http://edamontology.org/topic_3371,Synthetic chemistry, -http://edamontology.org/topic_3372,Software engineering, -http://edamontology.org/topic_3373,Drug development, -http://edamontology.org/topic_3374,Biotherapeutics, -http://edamontology.org/topic_3375,Drug metabolism, -http://edamontology.org/topic_3376,Medicines research and development, -http://edamontology.org/topic_3377,Safety sciences, -http://edamontology.org/topic_3378,Pharmacovigilance, -http://edamontology.org/topic_3379,Preclinical and clinical studies, -http://edamontology.org/topic_3382,Imaging, -http://edamontology.org/topic_3383,Bioimaging, -http://edamontology.org/topic_3384,Medical imaging, -http://edamontology.org/topic_3385,Light microscopy, -http://edamontology.org/topic_3386,Laboratory animal science, -http://edamontology.org/topic_3387,Marine biology, -http://edamontology.org/topic_3388,Molecular medicine, -http://edamontology.org/topic_3390,Nutritional science, -http://edamontology.org/topic_3391,Omics, -http://edamontology.org/topic_3393,Quality affairs, -http://edamontology.org/topic_3394,Regulatory affairs, -http://edamontology.org/topic_3395,Regenerative medicine, -http://edamontology.org/topic_3396,Systems medicine, -http://edamontology.org/topic_3397,Veterinary medicine, -http://edamontology.org/topic_3398,Bioengineering, -http://edamontology.org/topic_3399,Geriatric medicine, -http://edamontology.org/topic_3400,"Allergy, clinical immunology and immunotherapeutics", -http://edamontology.org/topic_3401,Pain medicine, -http://edamontology.org/topic_3402,Anaesthesiology, -http://edamontology.org/topic_3403,Critical care medicine, -http://edamontology.org/topic_3404,Dermatology, -http://edamontology.org/topic_3405,Dentistry, -http://edamontology.org/topic_3406,"Ear, nose and throat medicine", -http://edamontology.org/topic_3407,Endocrinology and metabolism, -http://edamontology.org/topic_3408,Haematology, -http://edamontology.org/topic_3409,Gastroenterology, -http://edamontology.org/topic_3410,Gender medicine, -http://edamontology.org/topic_3411,Gynaecology and obstetrics, -http://edamontology.org/topic_3412,Hepatic and biliary medicine, -http://edamontology.org/topic_3413,Infectious tropical disease, -http://edamontology.org/topic_3414,Trauma medicine, -http://edamontology.org/topic_3415,Medical toxicology, -http://edamontology.org/topic_3416,Musculoskeletal medicine, -http://edamontology.org/topic_3417,Opthalmology, -http://edamontology.org/topic_3418,Paediatrics, -http://edamontology.org/topic_3419,Psychiatry, -http://edamontology.org/topic_3420,Reproductive health, -http://edamontology.org/topic_3421,Surgery, -http://edamontology.org/topic_3422,Urology and nephrology, -http://edamontology.org/topic_3423,Complementary medicine, -http://edamontology.org/topic_3444,MRI, -http://edamontology.org/topic_3448,Neutron diffraction, -http://edamontology.org/topic_3452,Tomography, -http://edamontology.org/topic_3473,Data mining, -http://edamontology.org/topic_3474,Machine learning, -http://edamontology.org/topic_3489,Database management, -http://edamontology.org/topic_3500,Zoology, -http://edamontology.org/topic_3510,"Protein sites, features and motifs", -http://edamontology.org/topic_3511,"Nucleic acid sites, features and motifs", -http://edamontology.org/topic_3512,Gene transcripts, -http://edamontology.org/topic_3514,Protein-ligand interactions, -http://edamontology.org/topic_3515,Protein-drug interactions, -http://edamontology.org/topic_3516,Genotyping experiment, -http://edamontology.org/topic_3517,GWAS study, -http://edamontology.org/topic_3518,Microarray experiment, -http://edamontology.org/topic_3519,PCR experiment, -http://edamontology.org/topic_3520,Proteomics experiment, -http://edamontology.org/topic_3521,2D PAGE experiment, -http://edamontology.org/topic_3522,Northern blot experiment, -http://edamontology.org/topic_3523,RNAi experiment, -http://edamontology.org/topic_3524,Simulation experiment, -http://edamontology.org/topic_3525,Protein-nucleic acid interactions, -http://edamontology.org/topic_3526,Protein-protein interactions, -http://edamontology.org/topic_3527,Cellular process pathways, -http://edamontology.org/topic_3528,Disease pathways, -http://edamontology.org/topic_3529,Environmental information processing pathways, -http://edamontology.org/topic_3530,Genetic information processing pathways, -http://edamontology.org/topic_3531,Protein super-secondary structure, -http://edamontology.org/topic_3533,Protein active sites, -http://edamontology.org/topic_3534,Protein binding sites, -http://edamontology.org/topic_3535,Protein-nucleic acid binding sites, -http://edamontology.org/topic_3536,Protein cleavage sites, -http://edamontology.org/topic_3537,Protein chemical modifications, -http://edamontology.org/topic_3538,Protein disordered structure, -http://edamontology.org/topic_3539,Protein domains, -http://edamontology.org/topic_3540,Protein key folding sites, -http://edamontology.org/topic_3541,Protein post-translational modifications, -http://edamontology.org/topic_3542,Protein secondary structure, -http://edamontology.org/topic_3543,Protein sequence repeats, -http://edamontology.org/topic_3544,Protein signal peptides, -http://edamontology.org/topic_3569,Applied mathematics, -http://edamontology.org/topic_3570,Pure mathematics, -http://edamontology.org/topic_3571,Data governance, -http://edamontology.org/topic_3572,Data quality management, -http://edamontology.org/topic_3573,Freshwater biology, -http://edamontology.org/topic_3574,Human genetics, -http://edamontology.org/topic_3575,Tropical medicine, -http://edamontology.org/topic_3576,Medical biotechnology, -http://edamontology.org/topic_3577,Personalised medicine, -http://edamontology.org/topic_3656,Immunoprecipitation experiment, -http://edamontology.org/topic_3673,Whole genome sequencing, -http://edamontology.org/topic_3674,Methylated DNA immunoprecipitation, -http://edamontology.org/topic_3676,Exome sequencing, -http://edamontology.org/topic_3678,Experimental design and studies, -http://edamontology.org/topic_3679,Animal study, -http://edamontology.org/topic_3697,Microbial ecology, -http://edamontology.org/topic_3794,RNA immunoprecipitation, -http://edamontology.org/topic_3796,Population genomics, -http://edamontology.org/topic_3810,Agricultural science, -http://edamontology.org/topic_3837,Metagenomic sequencing, -http://edamontology.org/topic_3855,Environmental science, -http://edamontology.org/topic_3892,Biomolecular simulation, -http://edamontology.org/topic_3895,Synthetic biology, -http://edamontology.org/topic_3912,Genetic engineering, -http://edamontology.org/topic_3922,Proteogenomics, -http://edamontology.org/topic_3930,Immunogenetics, -http://edamontology.org/topic_3934,Cytometry, -http://edamontology.org/topic_3940,Chromosome conformation capture, -http://edamontology.org/topic_3941,Metatranscriptomics, -http://edamontology.org/topic_3943,Paleogenomics, -http://edamontology.org/topic_3944,Cladistics, -http://edamontology.org/topic_3945,Molecular evolution, -http://edamontology.org/topic_3948,Immunoinformatics, -http://edamontology.org/topic_3954,Echography, -http://edamontology.org/topic_3955,Fluxomics, -http://edamontology.org/topic_3957,Protein interaction experiment, -http://edamontology.org/topic_3958,Copy number variation, -http://edamontology.org/topic_3959,Cytogenetics, -http://edamontology.org/topic_3966,Vaccinology, -http://edamontology.org/topic_3967,Immunomics, -http://edamontology.org/topic_3974,Epistasis, -http://www.geneontology.org/formats/oboInOwl#ObsoleteClass,Obsolete concept (EDAM), -http://www.w3.org/2002/07/owl#DeprecatedClass,DeprecatedClass diff --git a/nf_core/assets/get_latest_edam.sh b/nf_core/assets/get_latest_edam.sh new file mode 100644 index 0000000000..eeb46bdf2b --- /dev/null +++ b/nf_core/assets/get_latest_edam.sh @@ -0,0 +1,4 @@ +# Run the following command to update to the latest EDAM file +curl -4 -fsSL https://edamontology.org/EDAM.tsv | \ + awk -F'\t' 'NF>=15 && $15!="" {print $1,$2,$15}' \ + > nf_core/assets/EDAM.tsv diff --git a/nf_core/modules/modules_utils.py b/nf_core/modules/modules_utils.py index 461816bb39..fe5daf36a3 100644 --- a/nf_core/modules/modules_utils.py +++ b/nf_core/modules/modules_utils.py @@ -97,7 +97,7 @@ def get_installed_modules(directory: Path, repo_type="modules") -> tuple[list[st def load_edam(): """Load the EDAM ontology from the nf-core repository""" edam_formats = {} - local_path = Path(__file__).parent.parent / "assets" / "EDAM_1.25.csv" + local_path = Path(__file__).parent.parent / "assets" / "EDAM.tsv" try: with local_path.open("rb") as f: data_bytes = f.read() @@ -105,7 +105,7 @@ def load_edam(): log.warning(f"Failed to load EDAM ontology: {e}") return {} for line in data_bytes.splitlines(): - fields = line.decode("utf-8").split(",") + fields = line.decode("utf-8").split("\t") if fields[0].split("/")[-1].startswith("format") and fields[2]: # We choose an already provided extension extensions = fields[2].split("|") for extension in extensions: From db12b9c71f2a624ca215e1eb3eb831ad2f99d00c Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Wed, 29 Apr 2026 11:08:36 +0200 Subject: [PATCH 004/135] Add edam_load test --- tests/modules/test_modules_utils.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/modules/test_modules_utils.py b/tests/modules/test_modules_utils.py index 8ef8d9d404..aff464e2fe 100644 --- a/tests/modules/test_modules_utils.py +++ b/tests/modules/test_modules_utils.py @@ -82,3 +82,9 @@ def test_filter_modules_by_name_empty_list(self): filtered = nf_core.modules.modules_utils.filter_modules_by_name(modules, "fastqc") assert len(filtered) == 0 + + def test_load_edam(self): + """Test edam ontology loading""" + edam_formats = nf_core.modules.modules_utils.load_edam() + assert len(edam_formats) == 62 + assert len(edam_formats[1]) == 2 From bc839987dd20e2b32954504e1a48536dddd6a07e Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Wed, 29 Apr 2026 11:19:19 +0200 Subject: [PATCH 005/135] Fix linting --- tests/modules/test_modules_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/test_modules_utils.py b/tests/modules/test_modules_utils.py index aff464e2fe..aba2eb3f79 100644 --- a/tests/modules/test_modules_utils.py +++ b/tests/modules/test_modules_utils.py @@ -82,7 +82,7 @@ def test_filter_modules_by_name_empty_list(self): filtered = nf_core.modules.modules_utils.filter_modules_by_name(modules, "fastqc") assert len(filtered) == 0 - + def test_load_edam(self): """Test edam ontology loading""" edam_formats = nf_core.modules.modules_utils.load_edam() From a8d97d0a669cacc07f0c441c61ff17b6d6d2a579 Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Wed, 29 Apr 2026 12:12:19 +0200 Subject: [PATCH 006/135] Fix test --- nf_core/assets/EDAM.tsv | 124 ++++++++++++++-------------- nf_core/assets/get_latest_edam.sh | 2 +- tests/modules/test_modules_utils.py | 5 +- 3 files changed, 66 insertions(+), 65 deletions(-) diff --git a/nf_core/assets/EDAM.tsv b/nf_core/assets/EDAM.tsv index f77ef5c107..4fddf177a5 100644 --- a/nf_core/assets/EDAM.tsv +++ b/nf_core/assets/EDAM.tsv @@ -1,62 +1,62 @@ -Class ID Preferred Label File extension -http://edamontology.org/format_1930 FASTQ fq|fastq -http://edamontology.org/format_2332 XML xml -http://edamontology.org/format_3256 N-Triples nt -http://edamontology.org/format_3257 Notation3 n3 -http://edamontology.org/format_3261 RDF/XML rdf -http://edamontology.org/format_3464 JSON json -http://edamontology.org/format_3475 TSV tsv|tab -http://edamontology.org/format_3556 MHTML mhtml|mht|eml -http://edamontology.org/format_3665 K-mer countgraph oxlicg -http://edamontology.org/format_3682 imzML metadata file imzML -http://edamontology.org/format_3710 WIFF format wiff -http://edamontology.org/format_3746 BIOM format biom -http://edamontology.org/format_3749 JSON-LD jsonld -http://edamontology.org/format_3750 YAML yaml|yml -http://edamontology.org/format_3752 CSV csv -http://edamontology.org/format_3788 SQL sql -http://edamontology.org/format_3789 XQuery xq|xqy|xquery -http://edamontology.org/format_3839 ibd ibd -http://edamontology.org/format_3857 CWL cwl -http://edamontology.org/format_3911 msh msh -http://edamontology.org/format_3913 Loom loom -http://edamontology.org/format_3915 Zarr zarray|zgroup -http://edamontology.org/format_3916 MTX mtx -http://edamontology.org/format_3956 N-Quads nq -http://edamontology.org/format_3969 Vega json -http://edamontology.org/format_3970 Vega-lite json -http://edamontology.org/format_3972 BNGL bngl -http://edamontology.org/format_3973 Docker image format dockerfile -http://edamontology.org/format_3975 GFA 1 gfa -http://edamontology.org/format_3976 GFA 2 gfa -http://edamontology.org/format_3977 ObjTables xlsx -http://edamontology.org/format_3978 CONTIG contig -http://edamontology.org/format_3979 WEGO wego -http://edamontology.org/format_3980 RPKM rpkm -http://edamontology.org/format_3981 TAR format tar -http://edamontology.org/format_3982 CHAIN chain -http://edamontology.org/format_3983 NET net -http://edamontology.org/format_3984 QMAP qmap -http://edamontology.org/format_3985 gxformat2 ga -http://edamontology.org/format_3986 WMV wmv -http://edamontology.org/format_3987 ZIP format zip -http://edamontology.org/format_3988 LSM lsm -http://edamontology.org/format_3989 GZIP format gz|gzip -http://edamontology.org/format_3990 AVI avi -http://edamontology.org/format_3991 TrackDB trackDb -http://edamontology.org/format_3992 CIGAR format cigar -http://edamontology.org/format_3993 Stereolithography format stl -http://edamontology.org/format_3994 U3D u3d -http://edamontology.org/format_3995 Texture file format tex -http://edamontology.org/format_3996 Python script py -http://edamontology.org/format_3997 MPEG-4 mp4 -http://edamontology.org/format_3998 Perl script pl -http://edamontology.org/format_3999 R script R -http://edamontology.org/format_4000 R markdown Rmd -http://edamontology.org/format_4001 NIFTI format nii -http://edamontology.org/format_4002 pickle pickle -http://edamontology.org/format_4003 NumPy format npy -http://edamontology.org/format_4004 SimTools repertoire file format repz -http://edamontology.org/format_4005 Configuration file format cfg -http://edamontology.org/format_4006 Zstandard format zst -http://edamontology.org/format_4007 MATLAB script m +Class ID Preferred Label File extension +http://edamontology.org/format_1930 FASTQ fq|fastq +http://edamontology.org/format_2332 XML xml +http://edamontology.org/format_3256 N-Triples nt +http://edamontology.org/format_3257 Notation3 n3 +http://edamontology.org/format_3261 RDF/XML rdf +http://edamontology.org/format_3464 JSON json +http://edamontology.org/format_3475 TSV tsv|tab +http://edamontology.org/format_3556 MHTML mhtml|mht|eml +http://edamontology.org/format_3665 K-mer countgraph oxlicg +http://edamontology.org/format_3682 imzML metadata file imzML +http://edamontology.org/format_3710 WIFF format wiff +http://edamontology.org/format_3746 BIOM format biom +http://edamontology.org/format_3749 JSON-LD jsonld +http://edamontology.org/format_3750 YAML yaml|yml +http://edamontology.org/format_3752 CSV csv +http://edamontology.org/format_3788 SQL sql +http://edamontology.org/format_3789 XQuery xq|xqy|xquery +http://edamontology.org/format_3839 ibd ibd +http://edamontology.org/format_3857 CWL cwl +http://edamontology.org/format_3911 msh msh +http://edamontology.org/format_3913 Loom loom +http://edamontology.org/format_3915 Zarr zarray|zgroup +http://edamontology.org/format_3916 MTX mtx +http://edamontology.org/format_3956 N-Quads nq +http://edamontology.org/format_3969 Vega json +http://edamontology.org/format_3970 Vega-lite json +http://edamontology.org/format_3972 BNGL bngl +http://edamontology.org/format_3973 Docker image format dockerfile +http://edamontology.org/format_3975 GFA 1 gfa +http://edamontology.org/format_3976 GFA 2 gfa +http://edamontology.org/format_3977 ObjTables xlsx +http://edamontology.org/format_3978 CONTIG contig +http://edamontology.org/format_3979 WEGO wego +http://edamontology.org/format_3980 RPKM rpkm +http://edamontology.org/format_3981 TAR format tar +http://edamontology.org/format_3982 CHAIN chain +http://edamontology.org/format_3983 NET net +http://edamontology.org/format_3984 QMAP qmap +http://edamontology.org/format_3985 gxformat2 ga +http://edamontology.org/format_3986 WMV wmv +http://edamontology.org/format_3987 ZIP format zip +http://edamontology.org/format_3988 LSM lsm +http://edamontology.org/format_3989 GZIP format gz|gzip +http://edamontology.org/format_3990 AVI avi +http://edamontology.org/format_3991 TrackDB trackDb +http://edamontology.org/format_3992 CIGAR format cigar +http://edamontology.org/format_3993 Stereolithography format stl +http://edamontology.org/format_3994 U3D u3d +http://edamontology.org/format_3995 Texture file format tex +http://edamontology.org/format_3996 Python script py +http://edamontology.org/format_3997 MPEG-4 mp4 +http://edamontology.org/format_3998 Perl script pl +http://edamontology.org/format_3999 R script R +http://edamontology.org/format_4000 R markdown Rmd +http://edamontology.org/format_4001 NIFTI format nii +http://edamontology.org/format_4002 pickle pickle +http://edamontology.org/format_4003 NumPy format npy +http://edamontology.org/format_4004 SimTools repertoire file format repz +http://edamontology.org/format_4005 Configuration file format cfg +http://edamontology.org/format_4006 Zstandard format zst +http://edamontology.org/format_4007 MATLAB script m diff --git a/nf_core/assets/get_latest_edam.sh b/nf_core/assets/get_latest_edam.sh index eeb46bdf2b..9f38162881 100644 --- a/nf_core/assets/get_latest_edam.sh +++ b/nf_core/assets/get_latest_edam.sh @@ -1,4 +1,4 @@ # Run the following command to update to the latest EDAM file curl -4 -fsSL https://edamontology.org/EDAM.tsv | \ - awk -F'\t' 'NF>=15 && $15!="" {print $1,$2,$15}' \ + awk -F'\t' -v OFS='\t' 'NF>=15 && $15!="" {print $1,$2,$15}' \ > nf_core/assets/EDAM.tsv diff --git a/tests/modules/test_modules_utils.py b/tests/modules/test_modules_utils.py index aba2eb3f79..3f6751bab9 100644 --- a/tests/modules/test_modules_utils.py +++ b/tests/modules/test_modules_utils.py @@ -86,5 +86,6 @@ def test_filter_modules_by_name_empty_list(self): def test_load_edam(self): """Test edam ontology loading""" edam_formats = nf_core.modules.modules_utils.load_edam() - assert len(edam_formats) == 62 - assert len(edam_formats[1]) == 2 + assert len(edam_formats) == 67 + first_item = next(iter(edam_formats)) + assert len(first_item) == 2 From fd064515bcc3875a8ce2d9748713c47dcc2d1e09 Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Wed, 29 Apr 2026 12:21:04 +0200 Subject: [PATCH 007/135] Fix changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 610a35647b..9453c9892f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ - switch changelog bot trigger only on comments ([#4241](https://github.com/nf-core/tools/pull/4241)) - fix indentation in generated api docs ([#4245](https://github.com/nf-core/tools/pull/4245)) +### Linting + - use static edam.csv and fix yaml comment loss ([#4242](https://github.com/nf-core/tools/pull/4242)) ### Modules From 952bbe3d3a95e356d1d1cb374d83edb883ad34ca Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Wed, 29 Apr 2026 12:47:04 +0200 Subject: [PATCH 008/135] Remove unecessary --- nf_core/modules/lint/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/nf_core/modules/lint/__init__.py b/nf_core/modules/lint/__init__.py index 7f01f7f4a2..2f80b9f974 100644 --- a/nf_core/modules/lint/__init__.py +++ b/nf_core/modules/lint/__init__.py @@ -689,16 +689,13 @@ def _add_edam_ontologies(section, edam_formats, desc): def _ensure_string_keys(obj): """Recursively ensure all dict keys are strings (e.g., convert 1.2 -> "1.2")""" + # This first block is needed to keep the comments in the yml if isinstance(obj, ruamel.yaml.comments.CommentedMap): for key in list(obj.keys()): value = obj.pop(key) new_key = str(key) if not isinstance(key, str) else key obj[new_key] = _ensure_string_keys(value) return obj - elif isinstance(obj, ruamel.yaml.comments.CommentedSeq): - for i, item in enumerate(obj): - obj[i] = _ensure_string_keys(item) - return obj elif isinstance(obj, dict): return {str(k) if not isinstance(k, str) else k: _ensure_string_keys(v) for k, v in obj.items()} elif isinstance(obj, list): From c5f2f29804366bae016de5f67747a358e178db97 Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Wed, 29 Apr 2026 13:20:17 +0200 Subject: [PATCH 009/135] Use NFCORE_CACHE_DIR --- CHANGELOG.md | 2 +- nf_core/assets/EDAM.tsv | 62 ------------------------------- nf_core/assets/get_latest_edam.sh | 4 -- nf_core/modules/modules_utils.py | 29 +++++++++++---- 4 files changed, 23 insertions(+), 74 deletions(-) delete mode 100644 nf_core/assets/EDAM.tsv delete mode 100644 nf_core/assets/get_latest_edam.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 9453c9892f..6f50b9a683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ ### Linting -- use static edam.csv and fix yaml comment loss ([#4242](https://github.com/nf-core/tools/pull/4242)) +- Store `EDAM.tsv` in `NFCORE_CACHE_DIR` and fix yaml comment loss ([#4242](https://github.com/nf-core/tools/pull/4242)) ### Modules diff --git a/nf_core/assets/EDAM.tsv b/nf_core/assets/EDAM.tsv deleted file mode 100644 index 4fddf177a5..0000000000 --- a/nf_core/assets/EDAM.tsv +++ /dev/null @@ -1,62 +0,0 @@ -Class ID Preferred Label File extension -http://edamontology.org/format_1930 FASTQ fq|fastq -http://edamontology.org/format_2332 XML xml -http://edamontology.org/format_3256 N-Triples nt -http://edamontology.org/format_3257 Notation3 n3 -http://edamontology.org/format_3261 RDF/XML rdf -http://edamontology.org/format_3464 JSON json -http://edamontology.org/format_3475 TSV tsv|tab -http://edamontology.org/format_3556 MHTML mhtml|mht|eml -http://edamontology.org/format_3665 K-mer countgraph oxlicg -http://edamontology.org/format_3682 imzML metadata file imzML -http://edamontology.org/format_3710 WIFF format wiff -http://edamontology.org/format_3746 BIOM format biom -http://edamontology.org/format_3749 JSON-LD jsonld -http://edamontology.org/format_3750 YAML yaml|yml -http://edamontology.org/format_3752 CSV csv -http://edamontology.org/format_3788 SQL sql -http://edamontology.org/format_3789 XQuery xq|xqy|xquery -http://edamontology.org/format_3839 ibd ibd -http://edamontology.org/format_3857 CWL cwl -http://edamontology.org/format_3911 msh msh -http://edamontology.org/format_3913 Loom loom -http://edamontology.org/format_3915 Zarr zarray|zgroup -http://edamontology.org/format_3916 MTX mtx -http://edamontology.org/format_3956 N-Quads nq -http://edamontology.org/format_3969 Vega json -http://edamontology.org/format_3970 Vega-lite json -http://edamontology.org/format_3972 BNGL bngl -http://edamontology.org/format_3973 Docker image format dockerfile -http://edamontology.org/format_3975 GFA 1 gfa -http://edamontology.org/format_3976 GFA 2 gfa -http://edamontology.org/format_3977 ObjTables xlsx -http://edamontology.org/format_3978 CONTIG contig -http://edamontology.org/format_3979 WEGO wego -http://edamontology.org/format_3980 RPKM rpkm -http://edamontology.org/format_3981 TAR format tar -http://edamontology.org/format_3982 CHAIN chain -http://edamontology.org/format_3983 NET net -http://edamontology.org/format_3984 QMAP qmap -http://edamontology.org/format_3985 gxformat2 ga -http://edamontology.org/format_3986 WMV wmv -http://edamontology.org/format_3987 ZIP format zip -http://edamontology.org/format_3988 LSM lsm -http://edamontology.org/format_3989 GZIP format gz|gzip -http://edamontology.org/format_3990 AVI avi -http://edamontology.org/format_3991 TrackDB trackDb -http://edamontology.org/format_3992 CIGAR format cigar -http://edamontology.org/format_3993 Stereolithography format stl -http://edamontology.org/format_3994 U3D u3d -http://edamontology.org/format_3995 Texture file format tex -http://edamontology.org/format_3996 Python script py -http://edamontology.org/format_3997 MPEG-4 mp4 -http://edamontology.org/format_3998 Perl script pl -http://edamontology.org/format_3999 R script R -http://edamontology.org/format_4000 R markdown Rmd -http://edamontology.org/format_4001 NIFTI format nii -http://edamontology.org/format_4002 pickle pickle -http://edamontology.org/format_4003 NumPy format npy -http://edamontology.org/format_4004 SimTools repertoire file format repz -http://edamontology.org/format_4005 Configuration file format cfg -http://edamontology.org/format_4006 Zstandard format zst -http://edamontology.org/format_4007 MATLAB script m diff --git a/nf_core/assets/get_latest_edam.sh b/nf_core/assets/get_latest_edam.sh deleted file mode 100644 index 9f38162881..0000000000 --- a/nf_core/assets/get_latest_edam.sh +++ /dev/null @@ -1,4 +0,0 @@ -# Run the following command to update to the latest EDAM file -curl -4 -fsSL https://edamontology.org/EDAM.tsv | \ - awk -F'\t' -v OFS='\t' 'NF>=15 && $15!="" {print $1,$2,$15}' \ - > nf_core/assets/EDAM.tsv diff --git a/nf_core/modules/modules_utils.py b/nf_core/modules/modules_utils.py index fe5daf36a3..3e33351243 100644 --- a/nf_core/modules/modules_utils.py +++ b/nf_core/modules/modules_utils.py @@ -2,6 +2,10 @@ from pathlib import Path from urllib.parse import urlparse +import requests + +from nf_core.utils import NFCORE_CACHE_DIR + from ..components.nfcore_component import NFCoreComponent log = logging.getLogger(__name__) @@ -97,13 +101,24 @@ def get_installed_modules(directory: Path, repo_type="modules") -> tuple[list[st def load_edam(): """Load the EDAM ontology from the nf-core repository""" edam_formats = {} - local_path = Path(__file__).parent.parent / "assets" / "EDAM.tsv" - try: - with local_path.open("rb") as f: - data_bytes = f.read() - except (FileNotFoundError, OSError) as e: - log.warning(f"Failed to load EDAM ontology: {e}") - return {} + cache_path = Path(NFCORE_CACHE_DIR) / "EDAM.tsv" + if not cache_path.exists(): + log.debug("EDAM.tsv file not found in NFCORE_CACHE_DIR") + try: + response = requests.get("https://edamontology.org/EDAM.tsv", timeout=15) + data_bytes = response.content + with open(cache_path, "wb") as fh: + fh.write(data_bytes) + except requests.exceptions.RequestException: + return edam_formats + else: + log.debug("EDAM.tsv file found in NFCORE_CACHE_DIR") + try: + with cache_path.open("rb") as f: + data_bytes = f.read() + except (FileNotFoundError, OSError) as e: + log.warning(f"Failed to load EDAM ontology: {e}") + return edam_formats for line in data_bytes.splitlines(): fields = line.decode("utf-8").split("\t") if fields[0].split("/")[-1].startswith("format") and fields[2]: # We choose an already provided extension From f3518dd5468754ee54f4b6c493403616c6bca3ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Wed, 29 Apr 2026 13:47:40 +0200 Subject: [PATCH 010/135] Update nf_core/modules/modules_utils.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- nf_core/modules/modules_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/modules/modules_utils.py b/nf_core/modules/modules_utils.py index 3e33351243..7dd5a0e042 100644 --- a/nf_core/modules/modules_utils.py +++ b/nf_core/modules/modules_utils.py @@ -116,7 +116,7 @@ def load_edam(): try: with cache_path.open("rb") as f: data_bytes = f.read() - except (FileNotFoundError, OSError) as e: + except (OSError) as e: log.warning(f"Failed to load EDAM ontology: {e}") return edam_formats for line in data_bytes.splitlines(): From 27e470602a6c58f1985e3cfa389b7539d5dce28c Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Wed, 29 Apr 2026 14:20:16 +0200 Subject: [PATCH 011/135] Use TTL for EDAM.tsv --- nf_core/modules/modules_utils.py | 33 +++++++++++++++++++------ tests/modules/test_modules_utils.py | 38 ++++++++++++++++++++++++++--- 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/nf_core/modules/modules_utils.py b/nf_core/modules/modules_utils.py index 7dd5a0e042..14ea23e5e8 100644 --- a/nf_core/modules/modules_utils.py +++ b/nf_core/modules/modules_utils.py @@ -1,4 +1,5 @@ import logging +import time from pathlib import Path from urllib.parse import urlparse @@ -10,6 +11,9 @@ log = logging.getLogger(__name__) +EDAM_TSV_URL = "https://edamontology.org/EDAM.tsv" +EDAM_CACHE_TTL = 7 * 24 * 60 * 60 # one week + class ModuleExceptionError(Exception): """Exception raised when there was an error with module commands""" @@ -98,27 +102,40 @@ def get_installed_modules(directory: Path, repo_type="modules") -> tuple[list[st return local_modules, nfcore_modules +def cache_is_expired(path: Path) -> bool: + """Return True if the cache file is older than the configured TTL.""" + age = time.time() - path.stat().st_mtime + return age > EDAM_CACHE_TTL + + def load_edam(): """Load the EDAM ontology from the nf-core repository""" edam_formats = {} cache_path = Path(NFCORE_CACHE_DIR) / "EDAM.tsv" + + # Remove stale cache file + if cache_path.exists() and cache_is_expired(cache_path): + log.debug("Cached EDAM ontology expired; removing old cache file") + cache_path.unlink(missing_ok=True) + if not cache_path.exists(): - log.debug("EDAM.tsv file not found in NFCORE_CACHE_DIR") + log.debug("EDAM.tsv file not found in NFCORE_CACHE_DIR; downloading") try: - response = requests.get("https://edamontology.org/EDAM.tsv", timeout=15) + response = requests.get(EDAM_TSV_URL, timeout=15) + response.raise_for_status() data_bytes = response.content - with open(cache_path, "wb") as fh: - fh.write(data_bytes) - except requests.exceptions.RequestException: + cache_path.write_bytes(data_bytes) + except requests.exceptions.RequestException as e: + log.warning(f"Failed to download EDAM ontology: {e}") return edam_formats else: - log.debug("EDAM.tsv file found in NFCORE_CACHE_DIR") + log.debug("Using EDAM.tsv file found in NFCORE_CACHE_DIR") try: - with cache_path.open("rb") as f: - data_bytes = f.read() + data_bytes = cache_path.read_bytes() except (OSError) as e: log.warning(f"Failed to load EDAM ontology: {e}") return edam_formats + for line in data_bytes.splitlines(): fields = line.decode("utf-8").split("\t") if fields[0].split("/")[-1].startswith("format") and fields[2]: # We choose an already provided extension diff --git a/tests/modules/test_modules_utils.py b/tests/modules/test_modules_utils.py index 3f6751bab9..889c0ee2d4 100644 --- a/tests/modules/test_modules_utils.py +++ b/tests/modules/test_modules_utils.py @@ -1,3 +1,6 @@ +from pathlib import Path +from unittest.mock import patch + import nf_core.modules.modules_utils from ..test_modules import TestModules @@ -83,9 +86,36 @@ def test_filter_modules_by_name_empty_list(self): filtered = nf_core.modules.modules_utils.filter_modules_by_name(modules, "fastqc") assert len(filtered) == 0 + @patch("nf_core.modules.modules_utils.NFCORE_CACHE_DIR", new="test_cache") def test_load_edam(self): - """Test edam ontology loading""" + """Test EDAM ontology loading""" + + cache_dir = Path("test_cache") + cache_path = cache_dir / "EDAM.tsv" + + # Ensure clean state + if cache_dir.exists(): + for f in cache_dir.iterdir(): + f.unlink() + cache_dir.rmdir() + + cache_dir.mkdir() + + # Cache should not exist before loading + assert not cache_path.exists() + edam_formats = nf_core.modules.modules_utils.load_edam() - assert len(edam_formats) == 67 - first_item = next(iter(edam_formats)) - assert len(first_item) == 2 + + # Cache file should now exist + assert cache_path.exists() + + first_key, first_value = next(iter(edam_formats.items())) + + assert isinstance(first_key, str) + assert isinstance(first_value, tuple) + assert len(first_value) == 2 + + # Cleanup (important since we're not using tmp_path) + for f in cache_dir.iterdir(): + f.unlink() + cache_dir.rmdir() From c602f0c6f3b252253b1a23ed0338183f32590eaf Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Wed, 29 Apr 2026 14:22:35 +0200 Subject: [PATCH 012/135] Fix lint --- nf_core/modules/modules_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/modules/modules_utils.py b/nf_core/modules/modules_utils.py index 14ea23e5e8..faedf85a7e 100644 --- a/nf_core/modules/modules_utils.py +++ b/nf_core/modules/modules_utils.py @@ -132,7 +132,7 @@ def load_edam(): log.debug("Using EDAM.tsv file found in NFCORE_CACHE_DIR") try: data_bytes = cache_path.read_bytes() - except (OSError) as e: + except OSError as e: log.warning(f"Failed to load EDAM ontology: {e}") return edam_formats From 303cd484d2091711019323e88672d0846b2cbbdc Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Wed, 29 Apr 2026 14:44:57 +0200 Subject: [PATCH 013/135] Fix edam columns --- nf_core/modules/modules_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nf_core/modules/modules_utils.py b/nf_core/modules/modules_utils.py index faedf85a7e..21496fdef3 100644 --- a/nf_core/modules/modules_utils.py +++ b/nf_core/modules/modules_utils.py @@ -138,8 +138,8 @@ def load_edam(): for line in data_bytes.splitlines(): fields = line.decode("utf-8").split("\t") - if fields[0].split("/")[-1].startswith("format") and fields[2]: # We choose an already provided extension - extensions = fields[2].split("|") + if fields[0].split("/")[-1].startswith("format") and fields[14]: # We choose an already provided extension + extensions = fields[14].split("|") for extension in extensions: if extension not in edam_formats: edam_formats[extension] = (fields[0], fields[1]) # URL, name From 670f46bf0f2ce98af899fc8cd815b0a090c94f39 Mon Sep 17 00:00:00 2001 From: mashehu Date: Wed, 29 Apr 2026 15:34:45 +0200 Subject: [PATCH 014/135] bump to 4.0.2dev --- CHANGELOG.md | 18 ++++++++++++++++-- pyproject.toml | 2 +- uv.lock | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8166c4c5eb..8926f4474c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ # nf-core/tools: Changelog -## v4.0.1 +## v4.0.2dev + +### General + +### Linting + +### Modules + +### Subworkflows + +### Template + +#### Version updates + +## [v4.0.1 - Bold Boa Patch](https://github.com/nf-core/tools/releases/tag/4.0.1) - [2026-04-29] ### General @@ -13,7 +27,7 @@ - Allow task.ext.prefix2 in modules linting ([#4234](https://github.com/nf-core/tools/pull/4234)) -## [v4.0.0 - Bold Boa](https://github.com/nf-core/tools/releases/tag/4.0.0) - [2026-04-27] +## [v4.0.0 - Bold Boa](https://github.com/nf-core/tools/releases/tag/4.0.0) - [2026-04-28] ### General diff --git a/pyproject.toml b/pyproject.toml index dd9a4e73ef..fe09067ce2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ nf_core = ["**/*"] [project] name = "nf-core" -version = "4.0.1" +version = "4.0.2dev" description = "Helper tools for use with nf-core Nextflow pipelines." readme = "README.md" license = "MIT" diff --git a/uv.lock b/uv.lock index 729236584d..16da65f7fc 100644 --- a/uv.lock +++ b/uv.lock @@ -1576,7 +1576,7 @@ wheels = [ [[package]] name = "nf-core" -version = "4.0.1" +version = "4.0.2.dev0" source = { editable = "." } dependencies = [ { name = "click" }, From c78f9015c1820f51898106abdfba965440bad9e8 Mon Sep 17 00:00:00 2001 From: mashehu Date: Thu, 30 Apr 2026 11:42:39 +0200 Subject: [PATCH 015/135] fix version capture in downloads_action --- .../.github/workflows/download_pipeline.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index 370ca8203a..399a0b9d69 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -55,10 +55,9 @@ jobs: apptainer-version: 1.3.4{% raw %} - name: Read .nf-core.yml - uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 id: read_yml - with: - config: ${{ github.workspace }}/.nf-core.yml + run: | + echo "nf_core_version=$(yq '.nf_core_version' ${{ github.workspace }}/.nf-core.yml)" >> "$GITHUB_OUTPUT" - name: Install dependencies run: | From 56d179bb7e7b286f8122ddbbd1dc50c37b6dbb8d Mon Sep 17 00:00:00 2001 From: mashehu Date: Thu, 30 Apr 2026 11:48:08 +0200 Subject: [PATCH 016/135] add pipeline_dir to search directories for include statements --- nf_core/pipelines/containers_utils.py | 38 ++++++++++++++------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/nf_core/pipelines/containers_utils.py b/nf_core/pipelines/containers_utils.py index af64f9582f..611e2ed1fb 100644 --- a/nf_core/pipelines/containers_utils.py +++ b/nf_core/pipelines/containers_utils.py @@ -57,35 +57,37 @@ def parse_module_paths(self) -> dict[str, Path]: # Captures the first name (original) and the path, ignoring any alias include_pattern = re.compile(r"include\s*\{\s*(\w+).*?\}\s*from\s+['\"]([^'\"]+)['\"]") - # Search in workflows, modules, and subworkflows directories + # Search in root (main.nf), workflows, modules, and subworkflows directories search_dirs = ["workflows", "modules", "subworkflows"] + nf_files_to_search = list(self.workflow_directory.glob("*.nf")) for search_dir in search_dirs: search_path = self.workflow_directory / search_dir if not search_path.exists(): continue + nf_files_to_search.extend(search_path.rglob("*.nf")) - for nf_file in search_path.rglob("*.nf"): - try: - content = nf_file.read_text() - for match in include_pattern.finditer(content): - process_name = match.group(1) - relative_path = match.group(2) + for nf_file in nf_files_to_search: + try: + content = nf_file.read_text() + for match in include_pattern.finditer(content): + process_name = match.group(1) + relative_path = match.group(2) - # Only process paths that contain 'modules/' - if "modules/" not in relative_path: - continue + # Only process paths that contain 'modules/' + if "modules/" not in relative_path: + continue - # Extract everything from 'modules/' onwards, removing any '/main' suffix - module_path_str = relative_path[relative_path.find("modules/") :] - module_path_str = module_path_str.replace("/main", "") + # Extract everything from 'modules/' onwards, removing any '/main' suffix + module_path_str = relative_path[relative_path.find("modules/") :] + module_path_str = module_path_str.replace("/main", "") - module_paths[process_name] = Path(module_path_str) - log.debug(f"Found include: {process_name} -> {module_path_str}") + module_paths[process_name] = Path(module_path_str) + log.debug(f"Found include: {process_name} -> {module_path_str}") - except OSError as e: - log.debug(f"Error parsing {nf_file}: {e}") - continue + except OSError as e: + log.debug(f"Error parsing {nf_file}: {e}") + continue return module_paths From c0999d1853ccde939dff44ba5c12fada2e9cee93 Mon Sep 17 00:00:00 2001 From: mashehu Date: Thu, 30 Apr 2026 11:50:44 +0200 Subject: [PATCH 017/135] downgrade logging of missing container for now --- nf_core/pipelines/containers_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipelines/containers_utils.py b/nf_core/pipelines/containers_utils.py index 611e2ed1fb..93e6aeda1d 100644 --- a/nf_core/pipelines/containers_utils.py +++ b/nf_core/pipelines/containers_utils.py @@ -164,7 +164,7 @@ def generate_container_configs( has_warnings = True continue if has_warnings: - log.info( + log.debug( "Generated container configs for the pipeline. Not all containers were found. Run with `-v` to see detailed warning messages." ) else: From c1160e4ec533a6018c6d7562756b98aa451f8de8 Mon Sep 17 00:00:00 2001 From: mashehu Date: Thu, 30 Apr 2026 12:06:11 +0200 Subject: [PATCH 018/135] add checkout step --- .../pipeline-template/.github/workflows/download_pipeline.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index 399a0b9d69..65354ea1d9 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -38,6 +38,9 @@ jobs: runs-on: ubuntu-latest needs: configure steps: + - name: Check out pipeline code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 From cb85e5af11f6e2a5e7b39c89a3cb57765a7995d1 Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke <101190534+nvnieuwk@users.noreply.github.com> Date: Thu, 30 Apr 2026 13:25:32 +0200 Subject: [PATCH 019/135] Remove format constraint for igenomes_base --- nf_core/pipeline-template/nextflow_schema.json | 1 - 1 file changed, 1 deletion(-) diff --git a/nf_core/pipeline-template/nextflow_schema.json b/nf_core/pipeline-template/nextflow_schema.json index 976ae1f2cd..a6caee0b3e 100644 --- a/nf_core/pipeline-template/nextflow_schema.json +++ b/nf_core/pipeline-template/nextflow_schema.json @@ -77,7 +77,6 @@ }, "igenomes_base": { "type": "string", - "format": "directory-path", "description": "The base path to the igenomes reference files", "fa_icon": "fas fa-ban", "hidden": true, From b61c81e5052dea141bd1f669c0d056e3b25a3bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 30 Apr 2026 14:41:15 +0200 Subject: [PATCH 020/135] update env syntax in tools dockerfile (#4248) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 91e6e56ca7..d3ac94f7dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,7 @@ RUN mkdir -p /usr/share/man/man1 \ # Setup ARG for NXF_VER ENV ARG NXF_VER="" -ENV NXF_VER ${NXF_VER} +ENV NXF_VER=${NXF_VER} # Install Nextflow RUN curl -s https://get.nextflow.io | bash \ && mv nextflow /usr/local/bin \ From 9ac9191427a0cc9fc2d494add165d6f4877cdf8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 30 Apr 2026 14:47:29 +0200 Subject: [PATCH 021/135] bump to 4.0.2 (#4254) --- CHANGELOG.md | 11 ++++------- pyproject.toml | 2 +- uv.lock | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8926f4474c..d53f3ec597 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,15 @@ # nf-core/tools: Changelog -## v4.0.2dev +## [v4.0.2 - Bold Boa Patch 2](https://github.com/nf-core/tools/releases/tag/4.0.2) - [2026-04-30] ### General -### Linting - -### Modules - -### Subworkflows +- add `pipeline_dir` to search directories for include statements ([#4252](https://github.com/nf-core/tools/pull/4252)) ### Template -#### Version updates +- fix version capture in downloads_action ([#4251](https://github.com/nf-core/tools/pull/4251)) +- Remove format constraint for igenomes_base ([#4253](https://github.com/nf-core/tools/pull/4253)) ## [v4.0.1 - Bold Boa Patch](https://github.com/nf-core/tools/releases/tag/4.0.1) - [2026-04-29] diff --git a/pyproject.toml b/pyproject.toml index fe09067ce2..4f39b8b62e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ nf_core = ["**/*"] [project] name = "nf-core" -version = "4.0.2dev" +version = "4.0.2" description = "Helper tools for use with nf-core Nextflow pipelines." readme = "README.md" license = "MIT" diff --git a/uv.lock b/uv.lock index 16da65f7fc..cfa4ad4f06 100644 --- a/uv.lock +++ b/uv.lock @@ -1576,7 +1576,7 @@ wheels = [ [[package]] name = "nf-core" -version = "4.0.2.dev0" +version = "4.0.2" source = { editable = "." } dependencies = [ { name = "click" }, From fd7903d0f7c83eb486a91500607f11d20485495c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Mon, 4 May 2026 21:04:25 +0200 Subject: [PATCH 022/135] bump to 4.1.0dev (#4259) --- CHANGELOG.md | 14 ++++++++++++++ pyproject.toml | 2 +- uv.lock | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d53f3ec597..958446161f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # nf-core/tools: Changelog +## v4.1.0dev + +### General + +### Linting + +### Modules + +### Subworkflows + +### Template + +#### Version updates + ## [v4.0.2 - Bold Boa Patch 2](https://github.com/nf-core/tools/releases/tag/4.0.2) - [2026-04-30] ### General diff --git a/pyproject.toml b/pyproject.toml index 4f39b8b62e..4ee28c498c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ nf_core = ["**/*"] [project] name = "nf-core" -version = "4.0.2" +version = "4.0.3" description = "Helper tools for use with nf-core Nextflow pipelines." readme = "README.md" license = "MIT" diff --git a/uv.lock b/uv.lock index cfa4ad4f06..23d913a630 100644 --- a/uv.lock +++ b/uv.lock @@ -1576,7 +1576,7 @@ wheels = [ [[package]] name = "nf-core" -version = "4.0.2" +version = "4.0.3" source = { editable = "." } dependencies = [ { name = "click" }, From 7eb2728cc98843eeb7d6f2c041d63489fbfafe33 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 19:09:46 +0000 Subject: [PATCH 023/135] Update github/branch-deploy action to v11.1.4 (#4258) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/changelog.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/update-template-snapshots.yml | 2 +- .github/workflows/update-textual-snapshots.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index d2ce28df65..39beaade4c 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -12,7 +12,7 @@ jobs: - name: branch-deploy id: branch-deploy if: github.event_name == 'issue_comment' - uses: github/branch-deploy@fded0351b6b79f854b335c11b3d93063461dd288 # v11.1.2 + uses: github/branch-deploy@ddf8ca48e9cdb2d2c7c71dee428308b19af9313f # v11.1.4 with: trigger: "@nf-core-bot changelog" reaction: "eyes" diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 46d6d10a29..8178e8a2ab 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -12,7 +12,7 @@ jobs: steps: - name: branch-deploy id: branch-deploy - uses: github/branch-deploy@fded0351b6b79f854b335c11b3d93063461dd288 # v11.1.2 + uses: github/branch-deploy@ddf8ca48e9cdb2d2c7c71dee428308b19af9313f # v11.1.4 with: trigger: "@nf-core-bot fix linting" reaction: "eyes" diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index 05eaa2d3b2..3edff55a0f 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -15,7 +15,7 @@ jobs: steps: - name: branch-deploy id: branch-deploy - uses: github/branch-deploy@fded0351b6b79f854b335c11b3d93063461dd288 # v11.1.2 + uses: github/branch-deploy@ddf8ca48e9cdb2d2c7c71dee428308b19af9313f # v11.1.4 with: trigger: "@nf-core-bot update template snapshots" reaction: "eyes" diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index 6b185c314f..07e172b45d 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -10,7 +10,7 @@ jobs: steps: - name: branch-deploy id: branch-deploy - uses: github/branch-deploy@fded0351b6b79f854b335c11b3d93063461dd288 # v11.1.2 + uses: github/branch-deploy@ddf8ca48e9cdb2d2c7c71dee428308b19af9313f # v11.1.4 with: trigger: "@nf-core-bot update textual snapshots" reaction: "eyes" From 22fcbbcbe5c6ea2d33847998c803788dd7b54ca3 Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Tue, 5 May 2026 17:52:10 +0100 Subject: [PATCH 024/135] docs: fix two typos in pipeline CONTRIBUTING.md (focussed -> focused, duplicate 'the') Both typos in nf_core/pipeline-template/docs/CONTRIBUTING.md ship with every pipeline that adopts the 4.0 template. 'focussed' is a less-common British spelling; 'focused' is preferred in modern AmE and BrE style guides. The second hit (line 54) is a duplicated 'the the'. Caught downstream during the nf-core/rnaseq#1827 template merge review. --- nf_core/pipeline-template/docs/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nf_core/pipeline-template/docs/CONTRIBUTING.md b/nf_core/pipeline-template/docs/CONTRIBUTING.md index b82420c4db..866c124543 100644 --- a/nf_core/pipeline-template/docs/CONTRIBUTING.md +++ b/nf_core/pipeline-template/docs/CONTRIBUTING.md @@ -46,12 +46,12 @@ The nf-core stance on the use of AI and LLMs is that humans are still ultimately If you’re using AI tools, try to stick by these guidelines: -- Keep PRs as small and focussed as possible +- Keep PRs as small and focused as possible - Avoid any unnecessary changes, such as moving or refactoring code (unless that is the explicit intention of the PR) - Review all generated code yourself before opening a PR, and ensure that you understand it - Engage with the community review process and expect to make revisions -For more detail, see the the [blog post](https://nf-co.re/blog/2026/statement-on-ai) for a statement from the nf-core/core team. +For more detail, see the [blog post](https://nf-co.re/blog/2026/statement-on-ai) for a statement from the nf-core/core team. ### Getting help From 59d428e6939b0728585b9cf5bc26f60ccea8a700 Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Tue, 5 May 2026 17:57:07 +0100 Subject: [PATCH 025/135] chore: trigger CI after base branch update From c7ada6b116d035c4e44fb6e720f5d294483bc8ca Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Tue, 5 May 2026 19:22:41 +0100 Subject: [PATCH 026/135] feat(template): add process_low_memory resource label Adds a memory-only override label that mirrors the existing process_high_memory pattern, so it can be stacked with one of the cpu/time bands (e.g. `process_high` + `process_low_memory` to get lots of cpus + tight memory ceiling). Motivation: tools that are cpu-bound but memory-light (Rust streaming binaries, e.g. trim_galore 2.x ~100 MB peak_rss) had no way to express that resource shape with the existing labels - process_high pinned both cpus and memory at 12/72GB, while dropping to process_low gave up the cpus too. Wires the new label into: - pipeline-template base.config (`memory = { 1.GB * task.attempt }`) - modules lint allowlist - nf-core modules create label autocomplete Discussed in #nf-core Slack #help thread on 2026-05-05. --- CHANGELOG.md | 4 ++++ nf_core/components/create.py | 1 + nf_core/modules/lint/main_nf.py | 1 + nf_core/pipeline-template/conf/base.config | 3 +++ 4 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 958446161f..5a62cd450a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,12 +6,16 @@ ### Linting +- Accept `process_low_memory` as a standard module label. + ### Modules ### Subworkflows ### Template +- Add `process_low_memory` resource label to the pipeline-template `base.config`. Mirrors `process_high_memory` so it can be stacked with one of the cpu/time bands (e.g. `process_high` + `process_low_memory` for cpu-bound, memory-light tools). + #### Version updates ## [v4.0.2 - Bold Boa Patch 2](https://github.com/nf-core/tools/releases/tag/4.0.2) - [2026-04-30] diff --git a/nf_core/components/create.py b/nf_core/components/create.py index 334278efbc..270cf1355a 100644 --- a/nf_core/components/create.py +++ b/nf_core/components/create.py @@ -249,6 +249,7 @@ def _get_module_structure_components(self): "process_medium", "process_high", "process_long", + "process_low_memory", "process_high_memory", ] if self.process_label is None: diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index eb365a4d73..b589bc3f0c 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -621,6 +621,7 @@ def check_process_labels(self, lines): "process_medium", "process_high", "process_long", + "process_low_memory", "process_high_memory", ] all_labels = [line.strip() for line in lines if line.lstrip().startswith("label ")] diff --git a/nf_core/pipeline-template/conf/base.config b/nf_core/pipeline-template/conf/base.config index 0edc34436d..4d9519d8fd 100644 --- a/nf_core/pipeline-template/conf/base.config +++ b/nf_core/pipeline-template/conf/base.config @@ -49,6 +49,9 @@ process { withLabel:process_long { time = { 20.h * task.attempt } } + withLabel:process_low_memory { + memory = { 1.GB * task.attempt } + } withLabel:process_high_memory { memory = { 200.GB * task.attempt } } From 4c3b11c2e3a8d6ef1f6b0de709811b342c90e2aa Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Tue, 5 May 2026 19:26:14 +0100 Subject: [PATCH 027/135] docs(changelog): match existing tools changelog style --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a62cd450a..eb67517316 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ ### Linting -- Accept `process_low_memory` as a standard module label. +- accept `process_low_memory` as a standard module label ([#4264](https://github.com/nf-core/tools/pull/4264)) ### Modules @@ -14,7 +14,7 @@ ### Template -- Add `process_low_memory` resource label to the pipeline-template `base.config`. Mirrors `process_high_memory` so it can be stacked with one of the cpu/time bands (e.g. `process_high` + `process_low_memory` for cpu-bound, memory-light tools). +- add `process_low_memory` resource label to `base.config` ([#4264](https://github.com/nf-core/tools/pull/4264)) #### Version updates From 293609769428e7462f4364c17ae30238894b5d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 7 May 2026 11:44:46 +0200 Subject: [PATCH 028/135] Fix pytest for strict nextflow syntax (#4261) --- .github/workflows/pytest.yml | 21 ++-- nf_core/components/components_test.py | 8 +- nf_core/pipelines/containers_utils.py | 8 +- nf_core/pipelines/download/download.py | 17 ++- nf_core/pipelines/list.py | 65 ++++++++-- nf_core/pipelines/schema.py | 6 +- nf_core/utils.py | 16 ++- tests/pipelines/download/test_download.py | 121 ++++++++++++------- tests/pipelines/lint/test_nextflow_config.py | 5 +- tests/pipelines/test_container_configs.py | 4 +- tests/pipelines/test_list.py | 3 +- tests/pipelines/test_rocrate.py | 24 ++-- tests/pipelines/test_schema.py | 4 +- 13 files changed, 199 insertions(+), 103 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 82bdf39e12..85cbd02188 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -20,6 +20,11 @@ on: release: types: [published] workflow_dispatch: + inputs: + nextflow-version: + description: "Nextflow version to test against" + required: false + default: "latest-stable" # Cancel if a newer run with the same workflow name is queued concurrency: @@ -46,7 +51,7 @@ jobs: tests: ${{ steps.list_tests.outputs.tests }} test: - name: Run ${{matrix.test}} with Python ${{ matrix.python-version }} on ubuntu-latest + name: Run ${{matrix.test}} with Python ${{ matrix.python-version }} and Nextflow ${{ matrix.nextflow-version }} needs: list_tests runs-on: - runs-on=${{ github.run_id }}-run-test @@ -54,8 +59,9 @@ jobs: strategy: matrix: # On main branch test with 3.10 and 3.14, otherwise just 3.10 - python-version: ${{ github.base_ref == 'main' && fromJson('["3.10", "3.14"]') || fromJson('["3.10"]') }} + python-version: ${{ (github.base_ref == 'main' || github.event_name == 'push') && fromJson('["3.10", "3.14"]') || fromJson('["3.10"]') }} test: ${{ fromJson(needs.list_tests.outputs.tests).test }} + nextflow-version: ${{ (github.base_ref == 'main' || github.event_name == 'push') && fromJson('["25.10.4", "latest-stable"]') || fromJson('["25.10.4"]') }} fail-fast: false # run all tests even if one fails steps: - name: go to subdirectory and change nextflow workdir @@ -84,18 +90,17 @@ jobs: - name: Set up Apptainer if: ${{ startsWith(matrix.test, 'pipelines/download/') }} uses: eWaterCycle/setup-apptainer@4bb22c52d4f63406c49e94c804632975787312b3 # v2.0.0 - with: - apptainer-version: 1.3.4 - - - name: Get current date - id: date - run: echo "date=$(date +'%Y-%m')" >> $GITHUB_ENV - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + with: + version: ${{ github.event.inputs.nextflow-version || matrix.nextflow-version }} - name: Install nf-test uses: nf-core/setup-nf-test@4069fbbaabe94c08faba4ad261bfa88225ba133f # v2 + with: + version: 0.9.5 + install-fast-diff: true - name: move coveragerc file up run: | diff --git a/nf_core/components/components_test.py b/nf_core/components/components_test.py index 3932d88ebb..587c724384 100644 --- a/nf_core/components/components_test.py +++ b/nf_core/components/components_test.py @@ -201,7 +201,8 @@ def generate_snapshot(self) -> bool: # set verbose flag if self.verbose is True verbose = "--verbose --debug" if self.verbose else "" - update = "--update-snapshot" if self.update else "" + update_snapshot = self.update + update = "--update-snapshot" if update_snapshot else "" self.update = False # reset self.update to False to test if the new snapshot is stable tag = f"subworkflows/{self.component_name}" if self.component_type == "subworkflows" else self.component_name profile = self.profile if self.profile else os.environ["PROFILE"] @@ -221,8 +222,9 @@ def generate_snapshot(self) -> bool: self.obsolete_snapshots = True # check if nf-test was successful if "Assertion failed:" in nftest_out.decode(): - if "Different Snapshot:" not in nftest_err.decode(): - self.errors.append("Assertion failed.") + if "Different Snapshot:" in nftest_err.decode(): + return update_snapshot # snapshot was updated return False only if we don't want to update the snapshot + self.errors.append("Assertion failed.") return False elif "No tests to execute." in nftest_out.decode(): log.error("Nothing to execute. Is the file 'main.nf.test' missing?") diff --git a/nf_core/pipelines/containers_utils.py b/nf_core/pipelines/containers_utils.py index 93e6aeda1d..2ab297b091 100644 --- a/nf_core/pipelines/containers_utils.py +++ b/nf_core/pipelines/containers_utils.py @@ -112,7 +112,13 @@ def generate_container_configs( raise UserWarning("Failed to run `nextflow inspect`. Please check your Nextflow installation.") out, _ = cmd_out - out_json = json.loads(out) + out_str = out.decode("utf-8", errors="replace") + try: + # Newer Nextflow versions print [PIPELINE]/[WORKDIR] headers before and [SUCCESS] after the JSON + json_start = out_str.find("{") + out_json, _ = json.JSONDecoder().raw_decode(out_str, json_start if json_start >= 0 else 0) + except json.JSONDecodeError: + out_json = json.loads(out) except RuntimeError as e: log.error("Running 'nextflow inspect' failed with the following error:") diff --git a/nf_core/pipelines/download/download.py b/nf_core/pipelines/download/download.py index 43d706f117..fbd051f65d 100644 --- a/nf_core/pipelines/download/download.py +++ b/nf_core/pipelines/download/download.py @@ -693,10 +693,25 @@ def run_nextflow_inspect(params_file: Path | None = None) -> dict[str, Any]: try: out_json = run_nextflow_inspect() except RuntimeError as e: + # Extract Nextflow stdout from the chained CalledProcessError (errors go to stdout in NF) + nf_stdout = getattr(e.__cause__, "output", None) or b"" + + # Nextflow >= 26.04 enforces strict process directive syntax and rejects old-style + # if/else container blocks with "Invalid process directive". Users need an older NF. + if b"Invalid process directive" in nf_stdout: + raise DownloadError( + "nextflow inspect failed because the pipeline uses old-style process syntax " + "that the default strict syntax of Nextflow >= 26.04 no longer accepts.\n" + "Please downgrade to Nextflow 25.10 or lower to download this pipeline, " + "or ask the pipeline maintainers to update their container directives." + ) from e + # Some workflow revisions explicitly require an outdir parameter. If this is the # only issue, retry inspect with an ephemeral params file that provides one. if re.search( - r"missing required parameter\s*:\s*(?:--outdir|params\.outdir|outdir)\b", str(e), flags=re.IGNORECASE + r"missing required parameter\s*:\s*(?:--outdir|params\.outdir|outdir)\b", + nf_stdout.decode("utf-8", errors="replace"), + flags=re.IGNORECASE, ): try: with tempfile.TemporaryDirectory(prefix="nf-core-inspect-") as tmp_dir: diff --git a/nf_core/pipelines/list.py b/nf_core/pipelines/list.py index 2dfb5a9b01..bc9bf30205 100644 --- a/nf_core/pipelines/list.py +++ b/nf_core/pipelines/list.py @@ -25,13 +25,44 @@ def _get_nextflow_assets_dir() -> Path: """Return the Nextflow assets directory used for local workflow caches.""" nxf_assets = os.environ.get("NXF_ASSETS") if nxf_assets: - return Path(nxf_assets) + base = Path(nxf_assets) + elif nxf_home := os.environ.get("NXF_HOME"): + base = Path(nxf_home, "assets") + else: + base = Path(os.environ.get("HOME", ""), ".nextflow", "assets") + + # Newer Nextflow versions store clones under assets/.repos/ + repos_dir = base / ".repos" + if repos_dir.is_dir(): + return repos_dir + return base + - nxf_home = os.environ.get("NXF_HOME") - if nxf_home: - return Path(nxf_home, "assets") +def _resolve_wf_path(path: Path) -> Path: + """Resolve the actual pipeline working tree for a given assets dir / workflow path. - return Path(os.environ.get("HOME", ""), ".nextflow", "assets") + Nextflow 26.04+ uses a worktree layout under .repos: + //clones// ← working tree + //bare/ ← bare git repo + Prefers the clone matching the bare repo's HEAD; falls back to the most + recently modified clone if HEAD's clone is missing or the bare repo is unreadable. + Returns path unchanged for the old (pre-26.04) flat layout. + """ + clones_dir = path / "clones" + bare_dir = path / "bare" + if clones_dir.is_dir(): + if bare_dir.is_dir(): + try: + sha = git.Repo(bare_dir).head.commit.hexsha + clone = clones_dir / sha + if clone.is_dir(): + return clone + except git.GitCommandError: + pass + sha_dirs = sorted(clones_dir.iterdir(), key=lambda p: p.stat().st_mtime) + if sha_dirs: + return sha_dirs[-1] + return path def list_workflows(filter_by=None, sort_by="release", as_json=False, show_archived=False): @@ -79,7 +110,7 @@ def get_local_wf(workflow: str | Path, revision=None) -> Path | None: workflow = Path("nf-core", workflow) local_wf = LocalWorkflow(str(workflow)) - local_wf_path = _get_nextflow_assets_dir() / workflow + local_wf_path = _resolve_wf_path(_get_nextflow_assets_dir() / workflow) if local_wf_path.is_dir(): local_wf.local_path = local_wf_path local_wf.get_local_nf_workflow_details() @@ -103,7 +134,11 @@ def get_local_wf(workflow: str | Path, revision=None) -> Path | None: pull_cmd = f"pull {workflow}" if revision is not None: pull_cmd += f" -r {revision}" - nf_core.utils.run_cmd("nextflow", pull_cmd) + try: + nf_core.utils.run_cmd("nextflow", pull_cmd) + except RuntimeError as e: + log.warning(f"Could not pull workflow '{workflow}': {e}") + return None local_wf = LocalWorkflow(str(workflow)) local_wf.get_local_nf_workflow_details() return local_wf.local_path @@ -191,7 +226,7 @@ def compare_remote_local(self): if rwf.full_name == lwf.full_name: rwf.local_wf = lwf if rwf.releases: - if rwf.releases[-1]["tag_sha"] == lwf.commit_sha: + if rwf.releases[0]["tag_sha"] == lwf.commit_sha: rwf.local_is_latest = True else: rwf.local_is_latest = False @@ -229,7 +264,7 @@ def print_summary(self): if not self.sort_workflows_by or self.sort_workflows_by == "release": filtered_workflows.sort( key=lambda wf: ( - (wf.releases[-1].get("published_at_timestamp", 0) if len(wf.releases) > 0 else 0) * -1, + (wf.releases[0].get("published_at_timestamp", 0) if len(wf.releases) > 0 else 0) * -1, wf.archived, wf.full_name.lower(), ) @@ -365,7 +400,7 @@ def get_local_nf_workflow_details(self): if self.local_path is None: # Try to guess the local cache directory - nf_wfdir = _get_nextflow_assets_dir() / self.full_name + nf_wfdir = _resolve_wf_path(_get_nextflow_assets_dir() / self.full_name) if nf_wfdir.is_dir(): log.debug(f"Guessed nextflow assets workflow directory: {nf_wfdir}") self.local_path = nf_wfdir @@ -379,7 +414,10 @@ def get_local_nf_workflow_details(self): for key, pattern in re_patterns.items(): m = re.search(pattern, str(nfinfo_raw)) if m: - setattr(self, key, m.group(1)) + value = Path(m.group(1)) if key == "local_path" else m.group(1) + if key == "local_path": + value = _resolve_wf_path(value) + setattr(self, key, value) # Pull information from the local git repository if self.local_path is not None: @@ -388,7 +426,8 @@ def get_local_nf_workflow_details(self): repo = git.Repo(self.local_path) self.commit_sha = str(repo.head.commit.hexsha) self.remote_url = str(repo.remotes.origin.url) - self.last_pull = (self.local_path / ".git" / "FETCH_HEAD").stat().st_mtime + self.last_pull = Path(repo.common_dir) / "FETCH_HEAD" + self.last_pull = self.last_pull.stat().st_mtime self.last_pull_date = datetime.fromtimestamp(self.last_pull).strftime("%Y-%m-%d %H:%M:%S") self.last_pull_pretty = pretty_date(self.last_pull) @@ -410,7 +449,7 @@ def get_local_nf_workflow_details(self): f"Could not fetch status of local Nextflow copy of '{self.full_name}':" f"\n [red]{type(e).__name__}:[/] {str(e)}" "\n\nThis git repository looks broken. It's probably a good idea to delete this local copy and pull again:" - f"\n [magenta]rm -rf {self.local_path}" + f"\n [magenta]rm -rf {_get_nextflow_assets_dir() / self.full_name}" f"\n [magenta]nextflow pull {self.full_name}", ) diff --git a/nf_core/pipelines/schema.py b/nf_core/pipelines/schema.py index 090373a11f..0c42b718dc 100644 --- a/nf_core/pipelines/schema.py +++ b/nf_core/pipelines/schema.py @@ -67,8 +67,10 @@ def _update_validation_plugin_from_config(self) -> None: plugin = "nf-schema" if self.schema_filename: conf = nf_core.utils.fetch_wf_config(Path(self.schema_filename).parent) - else: + elif self.pipeline_dir is not None: conf = nf_core.utils.fetch_wf_config(Path(self.pipeline_dir)) + else: + return plugins = str(conf.get("plugins", "")).strip("'\"").strip(" ").split(",") plugin_found = False @@ -137,7 +139,7 @@ def get_schema_path(self, path: str | Path, local_only: bool = False, revision: self.pipeline_dir = nf_core.pipelines.list.get_local_wf(path, revision=revision) self.schema_filename = Path(self.pipeline_dir or "", "nextflow_schema.json") # check if the schema file exists - if not self.schema_filename.exists(): + if self.schema_filename is not None and not self.schema_filename.exists(): self.schema_filename = None # Only looking for local paths, overwrite with None to be safe else: diff --git a/nf_core/utils.py b/nf_core/utils.py index 55f2ad3447..d376559e53 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -479,8 +479,14 @@ def run_cmd(executable: str, cmd: str) -> tuple[bytes, bytes] | None: full_cmd = f"{executable} {cmd}" log.debug(f"Running command: {full_cmd}") try: - proc = subprocess.run(shlex.split(full_cmd), capture_output=True, check=True) + proc = subprocess.run(shlex.split(full_cmd), capture_output=True, check=False) + if proc.returncode != 0: + if executable == "nf-test": + return (proc.stdout, proc.stderr) + raise subprocess.CalledProcessError(proc.returncode, proc.args, output=proc.stdout, stderr=proc.stderr) return (proc.stdout, proc.stderr) + except subprocess.CalledProcessError as e: + raise RuntimeError(f"Command '{full_cmd}' failed: {e}") from e except OSError as e: if e.errno == errno.ENOENT: raise RuntimeError( @@ -488,14 +494,6 @@ def run_cmd(executable: str, cmd: str) -> tuple[bytes, bytes] | None: ) from e else: return None - except subprocess.CalledProcessError as e: - log.debug(f"Command '{full_cmd}' returned non-zero error code '{e.returncode}':\n[red]> {e.stderr.decode()}") - if executable == "nf-test": - return (e.stdout, e.stderr) - else: - raise RuntimeError( - f"Command '{full_cmd}' returned non-zero error code '{e.returncode}':\n[red]> {e.stderr.decode()}{e.stdout.decode()}" - ) from e def setup_nfcore_dir() -> bool: diff --git a/tests/pipelines/download/test_download.py b/tests/pipelines/download/test_download.py index 5e4908432e..40228994cc 100644 --- a/tests/pipelines/download/test_download.py +++ b/tests/pipelines/download/test_download.py @@ -1,10 +1,12 @@ """Tests for the download subcommand of nf-core tools""" +import contextlib import json import logging import os import re import shutil +import subprocess import tempfile import unittest from pathlib import Path @@ -20,12 +22,22 @@ from nf_core.pipelines.download.utils import DownloadError from nf_core.pipelines.download.workflow_repo import WorkflowRepo from nf_core.synced_repo import SyncedRepo -from nf_core.utils import NF_INSPECT_MIN_NF_VERSION, check_nextflow_version +from nf_core.utils import NF_INSPECT_MIN_NF_VERSION, check_nextflow_version, get_nf_version from ...utils import TEST_DATA_DIR, with_temporary_folder +NF_STRICT_SYNTAX_VERSION = (26, 4, 0, False) + class DownloadTest(unittest.TestCase): + def setUp(self): + nf_ver = get_nf_version() + self.nf_strict_syntax = nf_ver is not None and nf_ver >= NF_STRICT_SYNTAX_VERSION + + def _strict_syntax_ctx(self, match: str = "nextflow inspect"): + """Return a context manager that expects a DownloadError on NF >= 26.04, or a no-op otherwise.""" + return pytest.raises(DownloadError, match=match) if self.nf_strict_syntax else contextlib.nullcontext() + @pytest.fixture(autouse=True) def use_caplog(self, caplog): self._caplog = caplog @@ -253,22 +265,20 @@ def test_containers_pipeline_singularity(self, tmp_path, mock_fetch_wf_config): mock_fetch_wf_config.return_value = {} # Run get containers with `nextflow inspect` + # NF >= 26.04 rejects old-style if/else container directives (mock_dsl2_old uses them) entrypoint = "main_passing_test.nf" - download_obj.find_container_images(mock_pipeline_dir, "dummy-revision", entrypoint=entrypoint) - - # Store the containers found by the new method - found_containers = set(download_obj.containers) - - # Load the reference containers - with open(refererence_json_dir / f"{container_system}_containers.json") as fh: - ref_containers = json.load(fh) - ref_container_strs = set(ref_containers.values()) - - # Now check that they contain the same containers - assert found_containers == ref_container_strs, ( - f"Containers found in pipeline by `nextflow inspect`: {found_containers}\n" - f"Containers that should've been found: {ref_container_strs}" - ) + with self._strict_syntax_ctx(match="downgrade to Nextflow"): + download_obj.find_container_images(mock_pipeline_dir, "dummy-revision", entrypoint=entrypoint) + + if not self.nf_strict_syntax: + found_containers = set(download_obj.containers) + with open(refererence_json_dir / f"{container_system}_containers.json") as fh: + ref_containers = json.load(fh) + ref_container_strs = set(ref_containers.values()) + assert found_containers == ref_container_strs, ( + f"Containers found in pipeline by `nextflow inspect`: {found_containers}\n" + f"Containers that should've been found: {ref_container_strs}" + ) # # Test that `find_container_images` (uses `nextflow inspect`) fetches the correct Docker images @@ -287,27 +297,24 @@ def test_containers_pipeline_docker(self, tmp_path, mock_fetch_wf_config): container_system = "docker" mock_pipeline_dir = TEST_DATA_DIR / "mock_pipeline_containers" refererence_json_dir = mock_pipeline_dir / "per_profile_output" - # First check that `-profile singularity` produces the same output as the reference + # First check that `-profile docker` produces the same output as the reference download_obj = DownloadWorkflow(pipeline="dummy", outdir=tmp_path, container_system=container_system) mock_fetch_wf_config.return_value = {} - # Run get containers with `nextflow inspect` + # NF >= 26.04 rejects old-style if/else container directives (mock_dsl2_old uses them) entrypoint = "main_passing_test.nf" - download_obj.find_container_images(mock_pipeline_dir, "dummy-revision", entrypoint=entrypoint) - - # Store the containers found by the new method - found_containers = set(download_obj.containers) - - # Load the reference containers - with open(refererence_json_dir / f"{container_system}_containers.json") as fh: - ref_containers = json.load(fh) - ref_container_strs = set(ref_containers.values()) - - # Now check that they contain the same containers - assert found_containers == ref_container_strs, ( - f"Containers found in pipeline by `nextflow inspect`: {found_containers}\n" - f"Containers that should've been found: {ref_container_strs}" - ) + with self._strict_syntax_ctx(match="downgrade to Nextflow"): + download_obj.find_container_images(mock_pipeline_dir, "dummy-revision", entrypoint=entrypoint) + + if not self.nf_strict_syntax: + found_containers = set(download_obj.containers) + with open(refererence_json_dir / f"{container_system}_containers.json") as fh: + ref_containers = json.load(fh) + ref_container_strs = set(ref_containers.values()) + assert found_containers == ref_container_strs, ( + f"Containers found in pipeline by `nextflow inspect`: {found_containers}\n" + f"Containers that should've been found: {ref_container_strs}" + ) @mock.patch("nf_core.pipelines.download.download.run_cmd") @mock.patch("nf_core.pipelines.list.Workflows.get_remote_workflows") @@ -325,11 +332,13 @@ def _run_cmd_side_effect(_executable, cmd_params): nonlocal has_retried if not has_retried: has_retried = True - raise RuntimeError( - """The following invalid input values have been detected:\n - * Missing required parameter: --outdir - """ + nf_output = ( + b"The following invalid input values have been detected:\n * Missing required parameter: --outdir\n" ) + cause = subprocess.CalledProcessError(1, ["nextflow", "inspect"], output=nf_output) + exc = RuntimeError("Command failed") + exc.__cause__ = cause + raise exc assert "-params-file" in cmd_params params_file_match = re.search(r'-params-file\s+"([^"]+)"', cmd_params) @@ -358,6 +367,22 @@ def test_find_container_images_raises_on_unexpected_runtime_error(self, mock_get assert mock_run_cmd.call_count == 1 mock_get_remote_workflows.assert_called_once() + @mock.patch("nf_core.pipelines.download.download.run_cmd") + @mock.patch("nf_core.pipelines.list.Workflows.get_remote_workflows") + def test_find_container_images_raises_on_strict_syntax_error(self, mock_get_remote_workflows, mock_run_cmd): + """Nextflow >= 26.04 rejects old if/else container directives; tool should give actionable guidance.""" + download_obj = DownloadWorkflow(container_system="docker") + cause = subprocess.CalledProcessError(1, ["nextflow", "inspect"], output=b"Error: Invalid process directive\n") + exc = RuntimeError("Command failed") + exc.__cause__ = cause + mock_run_cmd.side_effect = exc + + with pytest.raises(DownloadError, match="downgrade to Nextflow"): + download_obj.find_container_images(Path("workflow"), "dummy-revision") + + assert mock_run_cmd.call_count == 1 + mock_get_remote_workflows.assert_called_once() + # # Tests for the main entry method 'download_workflow' # @@ -386,7 +411,9 @@ def test_download_workflow_with_success(self, tmp_dir, mock_check_and_set_implem ) download_obj.include_configs = True # suppress prompt, because stderr.is_interactive doesn't. - download_obj.download_workflow() + # NF >= 26.04 fails on old-style container directives used in bamtofastq 2.2.0 + with self._strict_syntax_ctx(): + download_obj.download_workflow() # # Test Download for Seqera Platform @@ -436,8 +463,11 @@ def test_download_workflow_for_platform( assert bool(re.search(r"nf-core-rnaseq_\d{4}-\d{2}-\d{1,2}_\d{1,2}-\d{1,2}", str(download_obj.outdir), re.S)) download_obj.output_filename = download_obj.outdir / "rnaseq.git" - download_obj.download_workflow_platform(location=tmp_dir) + # NF >= 26.04 fails on old-style container directives used in rnaseq 3.17.0 / 3.19.0 + with self._strict_syntax_ctx(): + download_obj.download_workflow_platform(location=tmp_dir) + # workflow_repo is populated before find_container_images is called, so it's accessible in both paths assert download_obj.workflow_repo assert isinstance(download_obj.workflow_repo, WorkflowRepo) assert issubclass(type(download_obj.workflow_repo), SyncedRepo) @@ -450,12 +480,13 @@ def test_download_workflow_for_platform( # assert that the download has a "latest" branch. assert "latest" in all_heads - # download_obj.download_workflow_platform(location=tmp_dir) will run `nextflow inspect` for each revision - # This means that the containers in download_obj.containers are the containers the last specified revision i.e. 3.17 - assert isinstance(download_obj.containers, list) and len(download_obj.containers) == 39 - assert ( - "https://depot.galaxyproject.org/singularity/bbmap:39.10--h92535d8_0" in download_obj.containers - ) # direct definition + if not self.nf_strict_syntax: + # download_obj.download_workflow_platform(location=tmp_dir) will run `nextflow inspect` for each revision + # This means that the containers in download_obj.containers are the containers the last specified revision i.e. 3.17 + assert isinstance(download_obj.containers, list) and len(download_obj.containers) == 39 + assert ( + "https://depot.galaxyproject.org/singularity/bbmap:39.10--h92535d8_0" in download_obj.containers + ) # direct definition # clean-up # remove "nf-core-rnaseq*" directories diff --git a/tests/pipelines/lint/test_nextflow_config.py b/tests/pipelines/lint/test_nextflow_config.py index 60de0432d9..63c58b149b 100644 --- a/tests/pipelines/lint/test_nextflow_config.py +++ b/tests/pipelines/lint/test_nextflow_config.py @@ -59,6 +59,7 @@ def test_nextflow_config_missing_test_profile_failed(self): fail_content = re.sub(r"\btest\b", "testfail", content) with open(nf_conf_file, "w") as f: f.write(fail_content) + Path(self.new_pipeline, "conf", "testfail.config").touch() lint_obj = nf_core.pipelines.lint.PipelineLint(self.new_pipeline) lint_obj.load_pipeline_config() result = lint_obj.nextflow_config() @@ -155,7 +156,7 @@ def test_default_values_float(self): content = f.read() fail_content = re.sub( r"validate_params\s*=\s*true", - "params.validate_params = true\ndummy = 0.000000001", + "validate_params = true\ndummy = 0.000000001", content, ) with open(nf_conf_file, "w") as f: @@ -187,7 +188,7 @@ def test_default_values_float_fail(self): content = f.read() fail_content = re.sub( r"validate_params\s*=\s*true", - "params.validate_params = true\ndummy = 0.000000001", + "validate_params = true\ndummy = 0.000000001", content, ) with open(nf_conf_file, "w") as f: diff --git a/tests/pipelines/test_container_configs.py b/tests/pipelines/test_container_configs.py index af9ab0064c..e90b39a021 100644 --- a/tests/pipelines/test_container_configs.py +++ b/tests/pipelines/test_container_configs.py @@ -83,7 +83,7 @@ def test_generate_container_configs_new_module_injected(self) -> None: patch("nf_core.pipelines.containers_utils.check_nextflow_version", return_value=True), patch( "nf_core.pipelines.containers_utils.run_cmd", - return_value=('{"processes": []}', ""), + return_value=(b'{"processes": []}', b""), ), ): self.container_configs.generate_container_configs( @@ -109,7 +109,7 @@ def test_generate_container_configs_removes_stale_entries(self) -> None: patch("nf_core.pipelines.containers_utils.check_nextflow_version", return_value=True), patch( "nf_core.pipelines.containers_utils.run_cmd", - return_value=('{"processes": []}', ""), + return_value=(b'{"processes": []}', b""), ), ): self.container_configs.generate_container_configs() diff --git a/tests/pipelines/test_list.py b/tests/pipelines/test_list.py index 02d95cb146..8d32436393 100644 --- a/tests/pipelines/test_list.py +++ b/tests/pipelines/test_list.py @@ -111,7 +111,7 @@ def test_parse_local_workflow_and_succeed(self): if not test_path.is_dir(): test_path.mkdir(parents=True) # Create a dummy workflow directory (not just a file) - dummy_wf_path = self.tmp_nxf / "nf-core" / "dummy-wf" + dummy_wf_path = self.tmp_nxf / ".repos" / "nf-core" / "dummy-wf" dummy_wf_path.mkdir(parents=True, exist_ok=True) assert os.environ["NXF_ASSETS"] == self.tmp_nxf_str workflows_obj = nf_core.pipelines.list.Workflows() @@ -140,6 +140,7 @@ def test_local_workflow_investigation(self, mock_repo): (git_dir / "FETCH_HEAD").touch() mock_repo.return_value.head.commit.hexsha = "h00r4y" mock_repo.return_value.remotes.origin.url = "https://github.com/nf-core/dummy" + mock_repo.return_value.common_dir = str(git_dir) local_wf.get_local_nf_workflow_details() @mock.patch("git.Repo") diff --git a/tests/pipelines/test_rocrate.py b/tests/pipelines/test_rocrate.py index 8b04eb539b..30df70f821 100644 --- a/tests/pipelines/test_rocrate.py +++ b/tests/pipelines/test_rocrate.py @@ -276,14 +276,10 @@ def test_get_git_email_for_name(self): def test_parse_manifest_contributors_logs_parse_errors(self): """Emit a clear error when manifest.contributors cannot be normalised into valid JSON""" - self._set_manifest_identity( - """contributors = [ - [ - name: 'Alice Example', - github: alice - ] - ] - """ + # Set nf_config directly to avoid running nextflow config -flat on invalid Groovy syntax + # (unquoted `alice` is valid Groovy but references an undefined variable, causing nextflow to fail) + self.rocrate_obj.pipeline_obj.nf_config["manifest.contributors"] = ( + "[[\n name: 'Alice Example',\n github: alice\n]]" ) with self.assertLogs("nf_core.pipelines.rocrate", level="ERROR") as logs: @@ -383,14 +379,14 @@ def test_parse_manifest_contributors_requires_names(self): with self.assertRaises(SystemExit): self.rocrate_obj.parse_manifest_contributors() - def test_rocrate_creation_for_fetchngs(self): - """Run the nf-core rocrate command with nf-core/fetchngs""" + def test_rocrate_creation_for_demo(self): + """Run the nf-core rocrate command with nf-core/demo""" tmp_dir = Path(tempfile.mkdtemp()) - # git clone nf-core/fetchngs - git.Repo.clone_from("https://github.com/nf-core/fetchngs", tmp_dir / "fetchngs") + # git clone nf-core/demo + git.Repo.clone_from("https://github.com/nf-core/demo", tmp_dir / "demo") # Run the command - self.rocrate_obj = nf_core.pipelines.rocrate.ROCrate(tmp_dir / "fetchngs", version="1.12.0") - assert self.rocrate_obj.create_rocrate(tmp_dir / "fetchngs", self.pipeline_dir) + self.rocrate_obj = nf_core.pipelines.rocrate.ROCrate(tmp_dir / "demo", version="1.1.0") + assert self.rocrate_obj.create_rocrate(tmp_dir / "demo", self.pipeline_dir) # Check that Sateesh Peri is mentioned in creator field diff --git a/tests/pipelines/test_schema.py b/tests/pipelines/test_schema.py index 78324ee642..5965a5c011 100644 --- a/tests/pipelines/test_schema.py +++ b/tests/pipelines/test_schema.py @@ -68,7 +68,7 @@ def test_load_lint_schema(self): def test_load_lint_schema_nofile(self): """Check that linting raises properly if a non-existent file is given""" - with pytest.raises(RuntimeError): + with pytest.raises(AssertionError): self.schema_obj.get_schema_path("fake_file") def test_load_lint_schema_notjson(self): @@ -104,7 +104,7 @@ def test_get_schema_path_path_notexist(self): def test_get_schema_path_name(self): """Get schema file from the name of a remote pipeline""" - self.schema_obj.get_schema_path("atacseq") + self.schema_obj.get_schema_path("proteinfamilies") def test_get_schema_path_name_notexist(self): """ From 3411f6b35c9d9e6ca1d9115c1b3b9de3d832b813 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 May 2026 13:45:20 +0200 Subject: [PATCH 029/135] Update pre-commit hook pre-commit/mirrors-mypy to v2 (#4270) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: mashehu Co-authored-by: nf-core-bot --- .github/workflows/pytest.yml | 8 +- .pre-commit-config.yaml | 3 +- CHANGELOG.md | 2 + pyproject.toml | 2 +- uv.lock | 699 ++++++++++++++++++----------------- 5 files changed, 379 insertions(+), 335 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 85cbd02188..26aa1cc689 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -58,10 +58,12 @@ jobs: - runner=4cpu-linux-x64 strategy: matrix: - # On main branch test with 3.10 and 3.14, otherwise just 3.10 - python-version: ${{ (github.base_ref == 'main' || github.event_name == 'push') && fromJson('["3.10", "3.14"]') || fromJson('["3.10"]') }} + # On PRs to main test with 3.10 and 3.14, otherwise just 3.10 + python-version: ${{ github.base_ref == 'main' && fromJson('["3.10", "3.14"]') || fromJson('["3.10"]') }} test: ${{ fromJson(needs.list_tests.outputs.tests).test }} - nextflow-version: ${{ (github.base_ref == 'main' || github.event_name == 'push') && fromJson('["25.10.4", "latest-stable"]') || fromJson('["25.10.4"]') }} + # On push/release test both NF versions, otherwise just 25.10.4 + # Note: python×nextflow must stay ≤2 with 88 tests to stay under GitHub's 256-config limit + nextflow-version: ${{ (github.event_name == 'push' || github.event_name == 'release') && fromJson('["25.10.4", "latest-stable"]') || fromJson('["25.10.4"]') }} fail-fast: false # run all tests even if one fails steps: - name: go to subdirectory and change nextflow workdir diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 59c29157bb..aa21f91d43 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,9 +33,10 @@ repos: tests/pipelines/__snapshots__/.* )$ - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v1.20.2" + rev: "v2.0.0" hooks: - id: mypy + args: [--ignore-missing-imports, --scripts-are-modules, -n4] additional_dependencies: - types-PyYAML - types-requests diff --git a/CHANGELOG.md b/CHANGELOG.md index eb67517316..8a49056c70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### General +- Update pre-commit hook pre-commit/mirrors-mypy to v2 ([#4270](https://github.com/nf-core/tools/pull/4270)) + ### Linting - accept `process_low_memory` as a standard module label ([#4264](https://github.com/nf-core/tools/pull/4264)) diff --git a/pyproject.toml b/pyproject.toml index 4ee28c498c..a9e78a29e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,7 +62,7 @@ dependencies = [ [project.optional-dependencies] dev = [ - "mypy", + "mypy>=2.0.0", "myst_parser", "pytest-cov", "pytest-datafiles", diff --git a/uv.lock b/uv.lock index 23d913a630..ac0b46a1df 100644 --- a/uv.lock +++ b/uv.lock @@ -199,6 +199,44 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/66/df/32574bc8f1d440d40f4aaf3b455316b2b1536c7243c985a90f8516cf3074/arcp-0.2.1-py2.py3-none-any.whl", hash = "sha256:4e09b2d8a9fc3fda7ec112b553498ff032ea7de354e27dbeb1acc53667122444", size = 15838, upload-time = "2020-02-12T12:05:05.769Z" }, ] +[[package]] +name = "ast-serialize" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/9d/912fefab0e30aee6a3af8a62bbea4a81b29afa4ba2c973d31170620a26de/ast_serialize-0.3.0.tar.gz", hash = "sha256:1bc3ca09a63a021376527c4e938deedd11d11d675ce850e6f9c7487f5889992b", size = 60689, upload-time = "2026-04-30T23:24:48.104Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/57/a54d4de491d6cdd7a4e4b0952cc3ca9f60dcefa7b5fb48d6d492debe1649/ast_serialize-0.3.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:3a867927df59f76a18dc1d874a0b2c079b42c58972dca637905576deb0912e14", size = 1182966, upload-time = "2026-04-30T23:23:57.376Z" }, + { url = "https://files.pythonhosted.org/packages/ee/9e/a5db014bb0f91b209236b57c429389e31290c0093532b8436d577699b2fa/ast_serialize-0.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a6fb063bf040abf8321e7b8113a0554eda445ffc508aa51287f8808886a5ae22", size = 1171316, upload-time = "2026-04-30T23:23:59.63Z" }, + { url = "https://files.pythonhosted.org/packages/15/59/fd55133e478c4326f60a11df02573bf7ccb2ac685810b50f1803d0f68053/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5075cd8482573d743586779e5f9b652a015e37d4e95132d7e5a9bc5c8f483d8f", size = 1232234, upload-time = "2026-04-30T23:24:01.168Z" }, + { url = "https://files.pythonhosted.org/packages/cc/79/0ca1d26357ecb4a697d74d00b73ef3137f24c140424125393a0de820eb09/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:41560b27794f4553b0f77811e9fb325b77db4a2b39018d437e09932275306e66", size = 1233437, upload-time = "2026-04-30T23:24:03.151Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/7078ec94dd6e124b8e028ac77016a4f13c83fa1c145790f2e68f3816998b/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b967c01ca74909c5d90e0fe4393401e2cc5da5ebd9a6262a19e45ffd3757dec8", size = 1440188, upload-time = "2026-04-30T23:24:04.717Z" }, + { url = "https://files.pythonhosted.org/packages/21/16/cca7195ef55a012f8013c3442afa91d287a0a36dcf88b480b262475135b3/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:424ebb8f46cd993f7cec4009d119312d8433dd90e6b0df0499cd2c91bdcc5af9", size = 1254211, upload-time = "2026-04-30T23:24:06.18Z" }, + { url = "https://files.pythonhosted.org/packages/a0/0f/f3d4dfae67dee6580534361a6343367d34217e7d25cff858bd1d8f03b8ed/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14b1d566b56e2ee70b11fec1de7e0b94ec7cd83717ec7d189967841a361190e", size = 1255973, upload-time = "2026-04-30T23:24:07.772Z" }, + { url = "https://files.pythonhosted.org/packages/14/41/55fbfe02c42f40fbe3e74eda167d977d555ff720ce1abfa08515236efd88/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7ba30b18735f047ec11103d1ab92f4789cf1fea1e0dc89b04a2f5a0632fd79de", size = 1298629, upload-time = "2026-04-30T23:24:09.4Z" }, + { url = "https://files.pythonhosted.org/packages/28/36/7d2501cacc7989fb8504aa9da2a2022a174200a59d4e6639de4367a57fdd/ast_serialize-0.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e6ea0754cb7b0f682ebb005ffb0d18f8d17993490d9c289863cd69cacc4ab8df", size = 1408435, upload-time = "2026-04-30T23:24:11.013Z" }, + { url = "https://files.pythonhosted.org/packages/03/e7/54e3b469c3fa0bf9cd532fa643d1d33b73303f8d70beac3e366b68dd64b7/ast_serialize-0.3.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:a0c5aa1073a5ba7b2abaa4b54abe8b8d75c4d1e2d54a2ff70b0ca6222fea5728", size = 1508174, upload-time = "2026-04-30T23:24:12.635Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2a/9b9621865b02c60539e26d9b114a312b4fa46aa703e33e79317174bfea21/ast_serialize-0.3.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:4e52650d834c1ea7791969a361de2c54c13b2fb4c519ec79445fa8b9021a147d", size = 1502354, upload-time = "2026-04-30T23:24:14.186Z" }, + { url = "https://files.pythonhosted.org/packages/34/dd/f138bc5c43b0c414fdd12eefe15677839323078b6e75301ad7f96cd26d45/ast_serialize-0.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:15bd6af3f136c61dae27805eb6b8f3269e85a545c4c27ffe9e530ead78d2b36d", size = 1450504, upload-time = "2026-04-30T23:24:16.076Z" }, + { url = "https://files.pythonhosted.org/packages/68/cf/97ef9e1c315601db74365955c8edd3292e3055500d6317602815dbdf08ae/ast_serialize-0.3.0-cp314-cp314t-win32.whl", hash = "sha256:d188bfe37b674b49708497683051d4b571366a668799c9b8e8a94513694969d9", size = 1058662, upload-time = "2026-04-30T23:24:17.535Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d6/e2c3483c31580fdb623f92ad38d2f856cde4b9205a3e6bd84760f3de7d82/ast_serialize-0.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:5832c2fdf8f8a6cf682b4cfcf677f5eaf39b4ddbc490f5480cfccdd1e7ce8fa1", size = 1100349, upload-time = "2026-04-30T23:24:18.992Z" }, + { url = "https://files.pythonhosted.org/packages/ab/89/29abcb1fe18a429cda60c6e0bbd1d6e90499339842a2f548d7567542357e/ast_serialize-0.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:670f177188d128fb7f9f15b5ad0e1b553d22c34e3f584dcb83eb8077600437f0", size = 1072895, upload-time = "2026-04-30T23:24:20.706Z" }, + { url = "https://files.pythonhosted.org/packages/bc/93/72abad83966ed6235647c9f956417dc1e17e997696388521910e3d1fa3f4/ast_serialize-0.3.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:2ec2fafa5e4313cc8feed96e436ebe19ac7bc6fa41fbc2827e826c48b9e4c3a9", size = 1190024, upload-time = "2026-04-30T23:24:22.486Z" }, + { url = "https://files.pythonhosted.org/packages/85/4f/eb88584b2f0234e581762011208ca203252bf6c98e59b4769daa571f3576/ast_serialize-0.3.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ef6d3c08b7b4cd29b48410338e134764a00e76d25841eb02c1084e868c888ecc", size = 1178633, upload-time = "2026-04-30T23:24:24.35Z" }, + { url = "https://files.pythonhosted.org/packages/56/51/cf1ec1ff3e616373d0dcbd5fad502e0029dc541f13ab642259762a7d127f/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d841424f41b886e98044abc80769c14a956e6e5ccd5fb5b0d9f5ead72be18a4", size = 1241351, upload-time = "2026-04-30T23:24:25.987Z" }, + { url = "https://files.pythonhosted.org/packages/0d/44/68fcf50478cf1093f2d423f034ae06453122c8b415d8e21a44668eca485d/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d21453734ad39367ede5d37efe4f59f830ce1c09f432fc72a90e368f77a4a3e7", size = 1239582, upload-time = "2026-04-30T23:24:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/9d/c1/a6c9fa284eceb5fc6f21347e968445a051d7ca2c4d34e6a04314646dbcee/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f5e110cdce2a347e1dd987529c88ef54d26f67848dce3eba1b3b2cc2cf085c94", size = 1448853, upload-time = "2026-04-30T23:24:29.534Z" }, + { url = "https://files.pythonhosted.org/packages/23/5f/8ad3829a09e4e8c5328a53ce7d4711d660944e3e164c5f6abcc2c8f27167/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b6e23a98e57560a055f5c4b68700a0fd5ce483d2814c23140b3638c7f5d1e61", size = 1262204, upload-time = "2026-04-30T23:24:31.482Z" }, + { url = "https://files.pythonhosted.org/packages/25/13/44aa28d97f10e25247e8576b5f6b2795d4fa1a80acc88acc942c508d06f7/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1c9e763d70293d65ce1e1ea8c943140c68d0953f0268c7ee0998f2e07f77dd0", size = 1266458, upload-time = "2026-04-30T23:24:33.088Z" }, + { url = "https://files.pythonhosted.org/packages/d8/58/b3a8be3777cd3744324fd5cec0d80d37cd96fc7cbb0fb010e03dff1e870f/ast_serialize-0.3.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4388a1796c228f1ce5c391426f7d21a0003ad3b47f677dbeded9bd1a85c7209f", size = 1308700, upload-time = "2026-04-30T23:24:34.657Z" }, + { url = "https://files.pythonhosted.org/packages/13/03/f8312d6b57f5471a9dc7946f22b8798a1fc296d38c25766223aacadec42c/ast_serialize-0.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5283cdcc0c64c3d8b9b688dc6aaa012d9c0cf1380a7f774a6bae6a1c01b3205a", size = 1416724, upload-time = "2026-04-30T23:24:36.562Z" }, + { url = "https://files.pythonhosted.org/packages/50/5d/13fc3789a7abac00559da2e2e9f386db4612aa1f84fc53d09bf714c37545/ast_serialize-0.3.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:f5ef88cc5842a5d7a6ac09dc0d5fc2c98f5d276c1f076f866d55047ce886785b", size = 1515441, upload-time = "2026-04-30T23:24:38.018Z" }, + { url = "https://files.pythonhosted.org/packages/eb/b9/7ab43fc7a23b1f970281093228f5f79bed6edeed7a3e672bde6d7a832a58/ast_serialize-0.3.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:cc14bf402bdc0978594ecce783793de2c7470cd4f5cd7eb286ca97ed8ff7cba9", size = 1510522, upload-time = "2026-04-30T23:24:39.798Z" }, + { url = "https://files.pythonhosted.org/packages/56/ec/d75fc2b788d319f1fad77c14156896f31afdfc68af85b505e5bdebcb9592/ast_serialize-0.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:11eae0cf1b7b3e0678133cc2daa974ea972caf02eb4b3aa062af6fa9acd52c57", size = 1460917, upload-time = "2026-04-30T23:24:41.305Z" }, + { url = "https://files.pythonhosted.org/packages/95/74/f99c81193a2725911e1911ae567ed27c2f2419332c7f3537366f9d238cac/ast_serialize-0.3.0-cp39-abi3-win32.whl", hash = "sha256:2db3dd99de5e6a5a11d7dda73de8750eb6e5baaf25245adf7bdcfe64b6108ae2", size = 1067804, upload-time = "2026-04-30T23:24:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/16/81/76af00c47daa151e89f98ae21fbbcb2840aaa9f5766579c4da76a3c57188/ast_serialize-0.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:a2cd125adccf7969470621905d302750cd25951f22ea430d9a25b7be031e5549", size = 1105561, upload-time = "2026-04-30T23:24:44.578Z" }, + { url = "https://files.pythonhosted.org/packages/bd/46/d3ec57ad500f598d1554bd14ce4df615960549ab2844961bc4e1f5fbd174/ast_serialize-0.3.0-cp39-abi3-win_arm64.whl", hash = "sha256:0dd00da29985f15f50dc35728b7e1e7c84507bccfea1d9914738530f1c72238a", size = 1077165, upload-time = "2026-04-30T23:24:46.377Z" }, +] + [[package]] name = "async-timeout" version = "5.0.1" @@ -598,62 +636,62 @@ toml = [ [[package]] name = "cryptography" -version = "47.0.0" +version = "48.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ef/b2/7ffa7fe8207a8c42147ffe70c3e360b228160c1d85dc3faff16aaa3244c0/cryptography-47.0.0.tar.gz", hash = "sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb", size = 830863, upload-time = "2026-04-24T19:54:57.056Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/98/40dfe932134bdcae4f6ab5927c87488754bf9eb79297d7e0070b78dd58e9/cryptography-47.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0", size = 7912214, upload-time = "2026-04-24T19:53:03.864Z" }, - { url = "https://files.pythonhosted.org/packages/34/c6/2733531243fba725f58611b918056b277692f1033373dcc8bd01af1c05d4/cryptography-47.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973", size = 4644617, upload-time = "2026-04-24T19:53:06.909Z" }, - { url = "https://files.pythonhosted.org/packages/00/e3/b27be1a670a9b87f855d211cf0e1174a5d721216b7616bd52d8581d912ed/cryptography-47.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8", size = 4668186, upload-time = "2026-04-24T19:53:09.053Z" }, - { url = "https://files.pythonhosted.org/packages/81/b9/8443cfe5d17d482d348cee7048acf502bb89a51b6382f06240fd290d4ca3/cryptography-47.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b", size = 4651244, upload-time = "2026-04-24T19:53:11.217Z" }, - { url = "https://files.pythonhosted.org/packages/5d/5e/13ed0cdd0eb88ba159d6dd5ebfece8cb901dbcf1ae5ac4072e28b55d3153/cryptography-47.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92", size = 5252906, upload-time = "2026-04-24T19:53:13.532Z" }, - { url = "https://files.pythonhosted.org/packages/64/16/ed058e1df0f33d440217cd120d41d5dda9dd215a80b8187f68483185af82/cryptography-47.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7", size = 4701842, upload-time = "2026-04-24T19:53:15.618Z" }, - { url = "https://files.pythonhosted.org/packages/02/e0/3d30986b30fdbd9e969abbdf8ba00ed0618615144341faeb57f395a084fe/cryptography-47.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93", size = 4289313, upload-time = "2026-04-24T19:53:17.755Z" }, - { url = "https://files.pythonhosted.org/packages/df/fd/32db38e3ad0cb331f0691cb4c7a8a6f176f679124dee746b3af6633db4d9/cryptography-47.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac", size = 4650964, upload-time = "2026-04-24T19:53:20.062Z" }, - { url = "https://files.pythonhosted.org/packages/86/53/5395d944dfd48cb1f67917f533c609c34347185ef15eb4308024c876f274/cryptography-47.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f", size = 5207817, upload-time = "2026-04-24T19:53:22.498Z" }, - { url = "https://files.pythonhosted.org/packages/34/4f/e5711b28e1901f7d480a2b1b688b645aa4c77c73f10731ed17e7f7db3f0d/cryptography-47.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8", size = 4701544, upload-time = "2026-04-24T19:53:24.356Z" }, - { url = "https://files.pythonhosted.org/packages/22/22/c8ddc25de3010fc8da447648f5a092c40e7a8fadf01dd6d255d9c0b9373d/cryptography-47.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318", size = 4783536, upload-time = "2026-04-24T19:53:26.665Z" }, - { url = "https://files.pythonhosted.org/packages/66/b6/d4a68f4ea999c6d89e8498579cba1c5fcba4276284de7773b17e4fa69293/cryptography-47.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001", size = 4926106, upload-time = "2026-04-24T19:53:28.686Z" }, - { url = "https://files.pythonhosted.org/packages/54/ed/5f524db1fade9c013aa618e1c99c6ed05e8ffc9ceee6cda22fed22dda3f4/cryptography-47.0.0-cp311-abi3-win32.whl", hash = "sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203", size = 3258581, upload-time = "2026-04-24T19:53:31.058Z" }, - { url = "https://files.pythonhosted.org/packages/b2/dc/1b901990b174786569029f67542b3edf72ac068b6c3c8683c17e6a2f5363/cryptography-47.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa", size = 3775309, upload-time = "2026-04-24T19:53:33.054Z" }, - { url = "https://files.pythonhosted.org/packages/14/88/7aa18ad9c11bc87689affa5ce4368d884b517502d75739d475fc6f4a03c7/cryptography-47.0.0-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0", size = 7904299, upload-time = "2026-04-24T19:53:35.003Z" }, - { url = "https://files.pythonhosted.org/packages/07/55/c18f75724544872f234678fdedc871391722cb34a2aee19faa9f63100bb2/cryptography-47.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7", size = 4631180, upload-time = "2026-04-24T19:53:37.517Z" }, - { url = "https://files.pythonhosted.org/packages/ee/65/31a5cc0eaca99cec5bafffe155d407115d96136bb161e8b49e0ef73f09a7/cryptography-47.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1", size = 4653529, upload-time = "2026-04-24T19:53:39.775Z" }, - { url = "https://files.pythonhosted.org/packages/e5/bc/641c0519a495f3bfd0421b48d7cd325c4336578523ccd76ea322b6c29c7a/cryptography-47.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c", size = 4638570, upload-time = "2026-04-24T19:53:42.129Z" }, - { url = "https://files.pythonhosted.org/packages/2b/f2/300327b0a47f6dc94dd8b71b57052aefe178bb51745073d73d80604f11ab/cryptography-47.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829", size = 5238019, upload-time = "2026-04-24T19:53:44.577Z" }, - { url = "https://files.pythonhosted.org/packages/e9/5a/5b5cf994391d4bf9d9c7efd4c66aabe4d95227256627f8fea6cff7dfadbd/cryptography-47.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7", size = 4686832, upload-time = "2026-04-24T19:53:47.015Z" }, - { url = "https://files.pythonhosted.org/packages/dc/2c/ae950e28fd6475c852fc21a44db3e6b5bcc1261d1e370f2b6e42fa800fef/cryptography-47.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923", size = 4269301, upload-time = "2026-04-24T19:53:48.97Z" }, - { url = "https://files.pythonhosted.org/packages/67/fb/6a39782e150ffe5cc1b0018cb6ddc48bf7ca62b498d7539ffc8a758e977d/cryptography-47.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab", size = 4638110, upload-time = "2026-04-24T19:53:51.011Z" }, - { url = "https://files.pythonhosted.org/packages/8e/d7/0b3c71090a76e5c203164a47688b697635ece006dcd2499ab3a4dbd3f0bd/cryptography-47.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736", size = 5194988, upload-time = "2026-04-24T19:53:52.962Z" }, - { url = "https://files.pythonhosted.org/packages/63/33/63a961498a9df51721ab578c5a2622661411fc520e00bd83b0cc64eb20c4/cryptography-47.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7", size = 4686563, upload-time = "2026-04-24T19:53:55.274Z" }, - { url = "https://files.pythonhosted.org/packages/b7/bf/5ee5b145248f92250de86145d1c1d6edebbd57a7fe7caa4dedb5d4cf06a1/cryptography-47.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52", size = 4770094, upload-time = "2026-04-24T19:53:57.753Z" }, - { url = "https://files.pythonhosted.org/packages/92/43/21d220b2da5d517773894dacdcdb5c682c28d3fffce65548cb06e87d5501/cryptography-47.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd", size = 4913811, upload-time = "2026-04-24T19:54:00.236Z" }, - { url = "https://files.pythonhosted.org/packages/31/98/dc4ad376ac5f1a1a7d4a83f7b0c6f2bcad36b5d2d8f30aeb482d3a7d9582/cryptography-47.0.0-cp314-cp314t-win32.whl", hash = "sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63", size = 3237158, upload-time = "2026-04-24T19:54:02.606Z" }, - { url = "https://files.pythonhosted.org/packages/bc/da/97f62d18306b5133468bc3f8cc73a3111e8cdc8cf8d3e69474d6e5fd2d1b/cryptography-47.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b", size = 3758706, upload-time = "2026-04-24T19:54:04.433Z" }, - { url = "https://files.pythonhosted.org/packages/e0/34/a4fae8ae7c3bc227460c9ae43f56abf1b911da0ec29e0ebac53bb0a4b6b7/cryptography-47.0.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4", size = 7904072, upload-time = "2026-04-24T19:54:06.411Z" }, - { url = "https://files.pythonhosted.org/packages/01/64/d7b1e54fdb69f22d24a64bb3e88dc718b31c7fb10ef0b9691a3cf7eeea6e/cryptography-47.0.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27", size = 4635767, upload-time = "2026-04-24T19:54:08.519Z" }, - { url = "https://files.pythonhosted.org/packages/8b/7b/cca826391fb2a94efdcdfe4631eb69306ee1cff0b22f664a412c90713877/cryptography-47.0.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10", size = 4654350, upload-time = "2026-04-24T19:54:10.795Z" }, - { url = "https://files.pythonhosted.org/packages/4c/65/4b57bcc823f42a991627c51c2f68c9fd6eb1393c1756aac876cba2accae2/cryptography-47.0.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b", size = 4643394, upload-time = "2026-04-24T19:54:13.275Z" }, - { url = "https://files.pythonhosted.org/packages/f4/c4/2c5fbeea70adbbca2bbae865e1d605d6a4a7f8dbd9d33eaf69645087f06c/cryptography-47.0.0-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74", size = 5225777, upload-time = "2026-04-24T19:54:15.18Z" }, - { url = "https://files.pythonhosted.org/packages/7e/b8/ac57107ef32749d2b244e36069bb688792a363aaaa3acc9e3cf84c130315/cryptography-47.0.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515", size = 4688771, upload-time = "2026-04-24T19:54:17.835Z" }, - { url = "https://files.pythonhosted.org/packages/56/fc/9f1de22ff8be99d991f240a46863c52d475404c408886c5a38d2b5c3bb26/cryptography-47.0.0-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc", size = 4270753, upload-time = "2026-04-24T19:54:19.963Z" }, - { url = "https://files.pythonhosted.org/packages/00/68/d70c852797aa68e8e48d12e5a87170c43f67bb4a59403627259dd57d15de/cryptography-47.0.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca", size = 4642911, upload-time = "2026-04-24T19:54:21.818Z" }, - { url = "https://files.pythonhosted.org/packages/a5/51/661cbee74f594c5d97ff82d34f10d5551c085ca4668645f4606ebd22bd5d/cryptography-47.0.0-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76", size = 5181411, upload-time = "2026-04-24T19:54:24.376Z" }, - { url = "https://files.pythonhosted.org/packages/94/87/f2b6c374a82cf076cfa1416992ac8e8ec94d79facc37aec87c1a5cb72352/cryptography-47.0.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe", size = 4688262, upload-time = "2026-04-24T19:54:26.946Z" }, - { url = "https://files.pythonhosted.org/packages/14/e2/8b7462f4acf21ec509616f0245018bb197194ab0b65c2ea21a0bdd53c0eb/cryptography-47.0.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31", size = 4775506, upload-time = "2026-04-24T19:54:28.926Z" }, - { url = "https://files.pythonhosted.org/packages/70/75/158e494e4c08dc05e039da5bb48553826bd26c23930cf8d3cd5f21fa8921/cryptography-47.0.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7", size = 4912060, upload-time = "2026-04-24T19:54:30.869Z" }, - { url = "https://files.pythonhosted.org/packages/06/bd/0a9d3edbf5eadbac926d7b9b3cd0c4be584eeeae4a003d24d9eda4affbbd/cryptography-47.0.0-cp38-abi3-win32.whl", hash = "sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310", size = 3248487, upload-time = "2026-04-24T19:54:33.494Z" }, - { url = "https://files.pythonhosted.org/packages/60/80/5681af756d0da3a599b7bdb586fac5a1540f1bcefd2717a20e611ddade45/cryptography-47.0.0-cp38-abi3-win_amd64.whl", hash = "sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769", size = 3755737, upload-time = "2026-04-24T19:54:35.408Z" }, - { url = "https://files.pythonhosted.org/packages/1b/a0/928c9ce0d120a40a81aa99e3ba383e87337b9ac9ef9f6db02e4d7822424d/cryptography-47.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7", size = 3909893, upload-time = "2026-04-24T19:54:38.334Z" }, - { url = "https://files.pythonhosted.org/packages/81/75/d691e284750df5d9569f2b1ce4a00a71e1d79566da83b2b3e5549c84917f/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe", size = 4587867, upload-time = "2026-04-24T19:54:40.619Z" }, - { url = "https://files.pythonhosted.org/packages/07/d6/1b90f1a4e453009730b4545286f0b39bb348d805c11181fc31544e4f9a65/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475", size = 4627192, upload-time = "2026-04-24T19:54:42.849Z" }, - { url = "https://files.pythonhosted.org/packages/dc/53/cb358a80e9e359529f496870dd08c102aa8a4b5b9f9064f00f0d6ed5b527/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50", size = 4587486, upload-time = "2026-04-24T19:54:44.908Z" }, - { url = "https://files.pythonhosted.org/packages/8b/57/aaa3d53876467a226f9a7a82fd14dd48058ad2de1948493442dfa16e2ffd/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab", size = 4626327, upload-time = "2026-04-24T19:54:47.813Z" }, - { url = "https://files.pythonhosted.org/packages/ab/9c/51f28c3550276bcf35660703ba0ab829a90b88be8cd98a71ef23c2413913/cryptography-47.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8", size = 3698916, upload-time = "2026-04-24T19:54:49.782Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/9f/a9/db8f313fdcd85d767d4973515e1db101f9c71f95fced83233de224673757/cryptography-48.0.0.tar.gz", hash = "sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920", size = 832984, upload-time = "2026-05-04T22:59:38.133Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/3d/01f6dd9190170a5a241e0e98c2d04be3664a9e6f5b9b872cde63aff1c3dd/cryptography-48.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6", size = 8001587, upload-time = "2026-05-04T22:57:36.803Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6e/e90527eef33f309beb811cf7c982c3aeffcce8e3edb178baa4ca3ae4a6fa/cryptography-48.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c", size = 4690433, upload-time = "2026-05-04T22:57:40.373Z" }, + { url = "https://files.pythonhosted.org/packages/90/04/673510ed51ddff56575f306cf1617d80411ee76831ccd3097599140efdfe/cryptography-48.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3", size = 4710620, upload-time = "2026-05-04T22:57:42.935Z" }, + { url = "https://files.pythonhosted.org/packages/14/d5/e9c4ef932c8d800490c34d8bd589d64a31d5890e27ec9e9ad532be893294/cryptography-48.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5", size = 4696283, upload-time = "2026-05-04T22:57:45.294Z" }, + { url = "https://files.pythonhosted.org/packages/0c/29/174b9dfb60b12d59ecfc6cfa04bc88c21b42a54f01b8aae09bb6e51e4c7f/cryptography-48.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c", size = 5296573, upload-time = "2026-05-04T22:57:47.933Z" }, + { url = "https://files.pythonhosted.org/packages/95/38/0d29a6fd7d0d1373f0c0c88a04ba20e359b257753ac497564cd660fc1d55/cryptography-48.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f", size = 4743677, upload-time = "2026-05-04T22:57:50.067Z" }, + { url = "https://files.pythonhosted.org/packages/30/be/eef653013d5c63b6a490529e0316f9ac14a37602965d4903efed1399f32b/cryptography-48.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25", size = 4330808, upload-time = "2026-05-04T22:57:52.301Z" }, + { url = "https://files.pythonhosted.org/packages/84/9e/500463e87abb7a0a0f9f256ec21123ecde0a7b5541a15e840ea54551fd81/cryptography-48.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602", size = 4695941, upload-time = "2026-05-04T22:57:54.603Z" }, + { url = "https://files.pythonhosted.org/packages/e3/dc/7303087450c2ec9e7fbb750e17c2abfbc658f23cbd0e54009509b7cc4091/cryptography-48.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c", size = 5252579, upload-time = "2026-05-04T22:57:57.207Z" }, + { url = "https://files.pythonhosted.org/packages/d0/c0/7101d3b7215edcdc90c45da544961fd8ed2d6448f77577460fa75a8443f7/cryptography-48.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5", size = 4743326, upload-time = "2026-05-04T22:57:59.535Z" }, + { url = "https://files.pythonhosted.org/packages/ac/d8/5b833bad13016f562ab9d063d68199a4bd121d18458e439515601d3357ec/cryptography-48.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321", size = 4826672, upload-time = "2026-05-04T22:58:01.996Z" }, + { url = "https://files.pythonhosted.org/packages/98/e1/7074eb8bf3c135558c73fc2bcf0f5633f912e6fb87e868a55c454080ef09/cryptography-48.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74", size = 4972574, upload-time = "2026-05-04T22:58:03.968Z" }, + { url = "https://files.pythonhosted.org/packages/04/70/e5a1b41d325f797f39427aa44ef8baf0be500065ab6d8e10369d850d4a4f/cryptography-48.0.0-cp311-abi3-win32.whl", hash = "sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4", size = 3294868, upload-time = "2026-05-04T22:58:06.467Z" }, + { url = "https://files.pythonhosted.org/packages/f4/ac/8ac51b4a5fc5932eb7ee5c517ba7dc8cd834f0048962b6b352f00f41ebf9/cryptography-48.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7", size = 3817107, upload-time = "2026-05-04T22:58:08.845Z" }, + { url = "https://files.pythonhosted.org/packages/6b/84/70e3feea9feea87fd7cbe77efb2712ae1e3e6edf10749dc6e95f4e60e455/cryptography-48.0.0-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec", size = 7986556, upload-time = "2026-05-04T22:58:11.172Z" }, + { url = "https://files.pythonhosted.org/packages/89/6e/18e07a618bb5442ba10cf4df16e99c071365528aa570dfcb8c02e25a303b/cryptography-48.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18", size = 4684776, upload-time = "2026-05-04T22:58:13.712Z" }, + { url = "https://files.pythonhosted.org/packages/be/6a/4ea3b4c6c6759794d5ee2103c304a5076dc4b19ae1f9fe47dba439e159e9/cryptography-48.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20", size = 4698121, upload-time = "2026-05-04T22:58:16.448Z" }, + { url = "https://files.pythonhosted.org/packages/2f/59/6ff6ad6cae03bb887da2a5860b2c9805f8dac969ef01ce563336c49bd1d1/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff", size = 4690042, upload-time = "2026-05-04T22:58:18.544Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b4/fc334ed8cfd705aca282fe4d8f5ae64a8e0f74932e9feecb344610cf6e4d/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c", size = 5282526, upload-time = "2026-05-04T22:58:20.75Z" }, + { url = "https://files.pythonhosted.org/packages/11/08/9f8c5386cc4cd90d8255c7cdd0f5baf459a08502a09de30dc51f553d38dc/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db", size = 4733116, upload-time = "2026-05-04T22:58:23.627Z" }, + { url = "https://files.pythonhosted.org/packages/b8/77/99307d7574045699f8805aa500fa0fb83422d115b5400a064ddd306d7750/cryptography-48.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741", size = 4316030, upload-time = "2026-05-04T22:58:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/fd/36/a608b98337af3cb2aff4818e406649d30572b7031918b04c87d979495348/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166", size = 4689640, upload-time = "2026-05-04T22:58:27.747Z" }, + { url = "https://files.pythonhosted.org/packages/dd/a6/825010a291b4438aecc1f568bc428189fc1175515223632477c07dc0a6df/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336", size = 5237657, upload-time = "2026-05-04T22:58:29.848Z" }, + { url = "https://files.pythonhosted.org/packages/b9/09/4e76a09b4caa29aad535ddc806f5d4c5d01885bd978bd984fbc6ca032cae/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057", size = 4732362, upload-time = "2026-05-04T22:58:32.009Z" }, + { url = "https://files.pythonhosted.org/packages/18/78/444fa04a77d0cb95f417dda20d450e13c56ba8e5220fc892a1658f44f882/cryptography-48.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae", size = 4819580, upload-time = "2026-05-04T22:58:34.254Z" }, + { url = "https://files.pythonhosted.org/packages/38/85/ea67067c70a1fd4be2c63d35eeed82658023021affccc7b17705f8527dd2/cryptography-48.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c", size = 4963283, upload-time = "2026-05-04T22:58:36.376Z" }, + { url = "https://files.pythonhosted.org/packages/75/54/cc6d0f3deac3e81c7f847e8a189a12b6cdd65059b43dad25d4316abd849a/cryptography-48.0.0-cp314-cp314t-win32.whl", hash = "sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f", size = 3270954, upload-time = "2026-05-04T22:58:38.791Z" }, + { url = "https://files.pythonhosted.org/packages/49/67/cc947e288c0758a4e5473d1dcb743037ab7785541265a969240b8885441a/cryptography-48.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12", size = 3797313, upload-time = "2026-05-04T22:58:40.746Z" }, + { url = "https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86", size = 7983482, upload-time = "2026-05-04T22:58:43.769Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ac/f5b5995b87770c693e2596559ffafe195b4033a57f14a82268a2842953f3/cryptography-48.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e", size = 4683266, upload-time = "2026-05-04T22:58:46.064Z" }, + { url = "https://files.pythonhosted.org/packages/ec/c6/8b14f67e18338fbc4adb76f66c001f5c3610b3e2d1837f268f47a347dbbb/cryptography-48.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f", size = 4696228, upload-time = "2026-05-04T22:58:48.22Z" }, + { url = "https://files.pythonhosted.org/packages/ea/73/f808fbae9514bd91b47875b003f13e284c8c6bdfd904b7944e803937eec1/cryptography-48.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7", size = 4689097, upload-time = "2026-05-04T22:58:50.9Z" }, + { url = "https://files.pythonhosted.org/packages/93/01/d86632d7d28db8ae83221995752eeb6639ffb374c2d22955648cf8d52797/cryptography-48.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832", size = 5283582, upload-time = "2026-05-04T22:58:53.017Z" }, + { url = "https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c", size = 4730479, upload-time = "2026-05-04T22:58:55.611Z" }, + { url = "https://files.pythonhosted.org/packages/6f/af/99a582b1b1641ff5911ac559beb45097cf79efd4ead4657f578ef1af2d47/cryptography-48.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a", size = 4326481, upload-time = "2026-05-04T22:58:57.607Z" }, + { url = "https://files.pythonhosted.org/packages/90/ee/89aa26a06ef0a7d7611788ffd571a7c50e368cc6a4d5eef8b4884e866edb/cryptography-48.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a", size = 4688713, upload-time = "2026-05-04T22:59:00.077Z" }, + { url = "https://files.pythonhosted.org/packages/70/ba/bcb1b0bb7a33d4c7c0c4d4c7874b4a62ae4f56113a5f4baefa362dfb1f0f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a", size = 5238165, upload-time = "2026-05-04T22:59:02.317Z" }, + { url = "https://files.pythonhosted.org/packages/c9/70/ca4003b1ce5ca3dc3186ada51908c8a9b9ff7d5cab83cc0d43ee14ec144f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239", size = 4729947, upload-time = "2026-05-04T22:59:05.255Z" }, + { url = "https://files.pythonhosted.org/packages/44/a0/4ec7cf774207905aef1a8d11c3750d5a1db805eb380ee4e16df317870128/cryptography-48.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c", size = 4822059, upload-time = "2026-05-04T22:59:07.802Z" }, + { url = "https://files.pythonhosted.org/packages/1e/75/a2e55f99c16fcac7b5d6c1eb19ad8e00799854d6be5ca845f9259eae1681/cryptography-48.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4", size = 4960575, upload-time = "2026-05-04T22:59:09.851Z" }, + { url = "https://files.pythonhosted.org/packages/b8/23/6e6f32143ab5d8b36ca848a502c4bcd477ae75b9e1677e3530d669062578/cryptography-48.0.0-cp39-abi3-win32.whl", hash = "sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd", size = 3279117, upload-time = "2026-05-04T22:59:12.019Z" }, + { url = "https://files.pythonhosted.org/packages/9d/9a/0fea98a70cf1749d41d738836f6349d97945f7c89433a259a6c2642eefeb/cryptography-48.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8", size = 3792100, upload-time = "2026-05-04T22:59:14.884Z" }, + { url = "https://files.pythonhosted.org/packages/be/d2/024b5e06be9d44cb021fb0e1a03d34d63989cf56a0fe62f3dfbab695b9b4/cryptography-48.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855", size = 3950391, upload-time = "2026-05-04T22:59:17.415Z" }, + { url = "https://files.pythonhosted.org/packages/bc/17/3861e17c56fa0fd37491a14a8673fdb77c57fc5693cafe745ea8b06dba75/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b", size = 4637126, upload-time = "2026-05-04T22:59:20.197Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0a/7e226dbff530f21480727eb764973a7bff2b912f8e15cd4f129e71b56d1d/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13", size = 4667270, upload-time = "2026-05-04T22:59:22.647Z" }, + { url = "https://files.pythonhosted.org/packages/3b/f2/5a72274ca9f1b2a8b44a662ee0bf1b435909deb473d6f97bcd035bcdbc71/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb", size = 4636797, upload-time = "2026-05-04T22:59:24.912Z" }, + { url = "https://files.pythonhosted.org/packages/b4/e1/48cedb2fe63626e91ded1edad159e2a4fb8b6906c4425eb7749673077ce7/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355", size = 4666800, upload-time = "2026-05-04T22:59:27.474Z" }, + { url = "https://files.pythonhosted.org/packages/a2/ca/7e8365deec19afb2b2c7be7c1c0aa8f99633b54e90c570999acda93260fc/cryptography-48.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a", size = 3739536, upload-time = "2026-05-04T22:59:29.61Z" }, ] [[package]] @@ -863,14 +901,14 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.49" +version = "3.1.50" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/63/210aaa302d6a0a78daa67c5c15bbac2cad361722841278b0209b6da20855/gitpython-3.1.49.tar.gz", hash = "sha256:42f9399c9eb33fc581014bedd76049dfbaf6375aa2a5754575966387280315e1", size = 219367, upload-time = "2026-04-29T00:31:20.478Z" } +sdist = { url = "https://files.pythonhosted.org/packages/33/f6/354ae6491228b5eb40e10d89c4d13c651fe1cf7556e35ebdded50cff57ce/gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc", size = 219798, upload-time = "2026-05-06T04:01:26.571Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/6f/b842bfa6f21d6f87c57f9abf7194225e55279d96d869775e19e9f7236fc5/gitpython-3.1.49-py3-none-any.whl", hash = "sha256:024b0422d7f84d15cd794844e029ffebd4c5d42a7eb9b936b458697ef550a02c", size = 212190, upload-time = "2026-04-29T00:31:18.412Z" }, + { url = "https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9", size = 212507, upload-time = "2026-05-06T04:01:23.799Z" }, ] [[package]] @@ -1003,87 +1041,87 @@ wheels = [ [[package]] name = "librt" -version = "0.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/6b/3d5c13fb3e3c4f43206c8f9dfed13778c2ed4f000bacaa0b7ce3c402a265/librt-0.9.0.tar.gz", hash = "sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d", size = 184368, upload-time = "2026-04-09T16:06:26.173Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/4a/c64265d71b84030174ff3ac2cd16d8b664072afab8c41fccd8e2ee5a6f8d/librt-0.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443", size = 67529, upload-time = "2026-04-09T16:04:27.373Z" }, - { url = "https://files.pythonhosted.org/packages/23/b1/30ca0b3a8bdac209a00145c66cf42e5e7da2cc056ffc6ebc5c7b430ddd34/librt-0.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c", size = 70248, upload-time = "2026-04-09T16:04:28.758Z" }, - { url = "https://files.pythonhosted.org/packages/fa/fc/c6018dc181478d6ac5aa24a5846b8185101eb90894346db239eb3ea53209/librt-0.9.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e", size = 202184, upload-time = "2026-04-09T16:04:29.893Z" }, - { url = "https://files.pythonhosted.org/packages/bf/58/d69629f002203370ef41ea69ff71c49a2c618aec39b226ff49986ecd8623/librt-0.9.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285", size = 212926, upload-time = "2026-04-09T16:04:31.126Z" }, - { url = "https://files.pythonhosted.org/packages/cc/55/01d859f57824e42bd02465c77bec31fa5ef9d8c2bcee702ccf8ef1b9f508/librt-0.9.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2", size = 225664, upload-time = "2026-04-09T16:04:32.352Z" }, - { url = "https://files.pythonhosted.org/packages/9b/02/32f63ad0ef085a94a70315291efe1151a48b9947af12261882f8445b2a30/librt-0.9.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce", size = 219534, upload-time = "2026-04-09T16:04:33.667Z" }, - { url = "https://files.pythonhosted.org/packages/6a/5a/9d77111a183c885acf3b3b6e4c00f5b5b07b5817028226499a55f1fedc59/librt-0.9.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f", size = 227322, upload-time = "2026-04-09T16:04:34.945Z" }, - { url = "https://files.pythonhosted.org/packages/d5/e7/05d700c93063753e12ab230b972002a3f8f3b9c95d8a980c2f646c8b6963/librt-0.9.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236", size = 223407, upload-time = "2026-04-09T16:04:36.22Z" }, - { url = "https://files.pythonhosted.org/packages/c0/26/26c3124823c67c987456977c683da9a27cc874befc194ddcead5f9988425/librt-0.9.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38", size = 221302, upload-time = "2026-04-09T16:04:37.62Z" }, - { url = "https://files.pythonhosted.org/packages/50/2b/c7cc2be5cf4ff7b017d948a789256288cb33a517687ff1995e72a7eea79f/librt-0.9.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b", size = 243893, upload-time = "2026-04-09T16:04:38.909Z" }, - { url = "https://files.pythonhosted.org/packages/62/d3/da553d37417a337d12660450535d5fd51373caffbedf6962173c87867246/librt-0.9.0-cp310-cp310-win32.whl", hash = "sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774", size = 55375, upload-time = "2026-04-09T16:04:40.148Z" }, - { url = "https://files.pythonhosted.org/packages/9b/5a/46fa357bab8311b6442a83471591f2f9e5b15ecc1d2121a43725e0c529b8/librt-0.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8", size = 62581, upload-time = "2026-04-09T16:04:41.452Z" }, - { url = "https://files.pythonhosted.org/packages/e2/1e/2ec7afcebcf3efea593d13aee18bbcfdd3a243043d848ebf385055e9f636/librt-0.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671", size = 67155, upload-time = "2026-04-09T16:04:42.933Z" }, - { url = "https://files.pythonhosted.org/packages/18/77/72b85afd4435268338ad4ec6231b3da8c77363f212a0227c1ff3b45e4d35/librt-0.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d", size = 69916, upload-time = "2026-04-09T16:04:44.042Z" }, - { url = "https://files.pythonhosted.org/packages/27/fb/948ea0204fbe2e78add6d46b48330e58d39897e425560674aee302dca81c/librt-0.9.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6", size = 199635, upload-time = "2026-04-09T16:04:45.5Z" }, - { url = "https://files.pythonhosted.org/packages/ac/cd/894a29e251b296a27957856804cfd21e93c194aa131de8bb8032021be07e/librt-0.9.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1", size = 211051, upload-time = "2026-04-09T16:04:47.016Z" }, - { url = "https://files.pythonhosted.org/packages/18/8f/dcaed0bc084a35f3721ff2d081158db569d2c57ea07d35623ddaca5cfc8e/librt-0.9.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882", size = 224031, upload-time = "2026-04-09T16:04:48.207Z" }, - { url = "https://files.pythonhosted.org/packages/03/44/88f6c1ed1132cd418601cc041fbd92fed28b3a09f39de81978e0822d13ff/librt-0.9.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990", size = 218069, upload-time = "2026-04-09T16:04:50.025Z" }, - { url = "https://files.pythonhosted.org/packages/a3/90/7d02e981c2db12188d82b4410ff3e35bfdb844b26aecd02233626f46af2b/librt-0.9.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4", size = 224857, upload-time = "2026-04-09T16:04:51.684Z" }, - { url = "https://files.pythonhosted.org/packages/ef/c3/c77e706b7215ca32e928d47535cf13dbc3d25f096f84ddf8fbc06693e229/librt-0.9.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb", size = 219865, upload-time = "2026-04-09T16:04:52.949Z" }, - { url = "https://files.pythonhosted.org/packages/52/d1/32b0c1a0eb8461c70c11656c46a29f760b7c7edf3c36d6f102470c17170f/librt-0.9.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076", size = 218451, upload-time = "2026-04-09T16:04:54.174Z" }, - { url = "https://files.pythonhosted.org/packages/74/d1/adfd0f9c44761b1d49b1bec66173389834c33ee2bd3c7fd2e2367f1942d4/librt-0.9.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a", size = 241300, upload-time = "2026-04-09T16:04:55.452Z" }, - { url = "https://files.pythonhosted.org/packages/09/b0/9074b64407712f0003c27f5b1d7655d1438979155f049720e8a1abd9b1a1/librt-0.9.0-cp311-cp311-win32.whl", hash = "sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6", size = 55668, upload-time = "2026-04-09T16:04:56.689Z" }, - { url = "https://files.pythonhosted.org/packages/24/19/40b77b77ce80b9389fb03971431b09b6b913911c38d412059e0b3e2a9ef2/librt-0.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8", size = 62976, upload-time = "2026-04-09T16:04:57.733Z" }, - { url = "https://files.pythonhosted.org/packages/70/9d/9fa7a64041e29035cb8c575af5f0e3840be1b97b4c4d9061e0713f171849/librt-0.9.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a", size = 53502, upload-time = "2026-04-09T16:04:58.806Z" }, - { url = "https://files.pythonhosted.org/packages/bf/90/89ddba8e1c20b0922783cd93ed8e64f34dc05ab59c38a9c7e313632e20ff/librt-0.9.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4", size = 68332, upload-time = "2026-04-09T16:05:00.09Z" }, - { url = "https://files.pythonhosted.org/packages/a8/40/7aa4da1fb08bdeeb540cb07bfc8207cb32c5c41642f2594dbd0098a0662d/librt-0.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d", size = 70581, upload-time = "2026-04-09T16:05:01.213Z" }, - { url = "https://files.pythonhosted.org/packages/48/ac/73a2187e1031041e93b7e3a25aae37aa6f13b838c550f7e0f06f66766212/librt-0.9.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f", size = 203984, upload-time = "2026-04-09T16:05:02.542Z" }, - { url = "https://files.pythonhosted.org/packages/5e/3d/23460d571e9cbddb405b017681df04c142fb1b04cbfce77c54b08e28b108/librt-0.9.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27", size = 215762, upload-time = "2026-04-09T16:05:04.127Z" }, - { url = "https://files.pythonhosted.org/packages/de/1e/42dc7f8ab63e65b20640d058e63e97fd3e482c1edbda3570d813b4d0b927/librt-0.9.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2", size = 230288, upload-time = "2026-04-09T16:05:05.883Z" }, - { url = "https://files.pythonhosted.org/packages/dc/08/ca812b6d8259ad9ece703397f8ad5c03af5b5fedfce64279693d3ce4087c/librt-0.9.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b", size = 224103, upload-time = "2026-04-09T16:05:07.148Z" }, - { url = "https://files.pythonhosted.org/packages/b6/3f/620490fb2fa66ffd44e7f900254bc110ebec8dac6c1b7514d64662570e6f/librt-0.9.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265", size = 232122, upload-time = "2026-04-09T16:05:08.386Z" }, - { url = "https://files.pythonhosted.org/packages/e9/83/12864700a1b6a8be458cf5d05db209b0d8e94ae281e7ec261dbe616597b4/librt-0.9.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084", size = 225045, upload-time = "2026-04-09T16:05:09.707Z" }, - { url = "https://files.pythonhosted.org/packages/fd/1b/845d339c29dc7dbc87a2e992a1ba8d28d25d0e0372f9a0a2ecebde298186/librt-0.9.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8", size = 227372, upload-time = "2026-04-09T16:05:10.942Z" }, - { url = "https://files.pythonhosted.org/packages/8d/fe/277985610269d926a64c606f761d58d3db67b956dbbf40024921e95e7fcb/librt-0.9.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f", size = 248224, upload-time = "2026-04-09T16:05:12.254Z" }, - { url = "https://files.pythonhosted.org/packages/92/1b/ee486d244b8de6b8b5dbaefabe6bfdd4a72e08f6353edf7d16d27114da8d/librt-0.9.0-cp312-cp312-win32.whl", hash = "sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f", size = 55986, upload-time = "2026-04-09T16:05:13.529Z" }, - { url = "https://files.pythonhosted.org/packages/89/7a/ba1737012308c17dc6d5516143b5dce9a2c7ba3474afd54e11f44a4d1ef3/librt-0.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745", size = 63260, upload-time = "2026-04-09T16:05:14.68Z" }, - { url = "https://files.pythonhosted.org/packages/36/e4/01752c113da15127f18f7bf11142f5640038f062407a611c059d0036c6aa/librt-0.9.0-cp312-cp312-win_arm64.whl", hash = "sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9", size = 53694, upload-time = "2026-04-09T16:05:16.095Z" }, - { url = "https://files.pythonhosted.org/packages/5f/d7/1b3e26fffde1452d82f5666164858a81c26ebe808e7ae8c9c88628981540/librt-0.9.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e", size = 68367, upload-time = "2026-04-09T16:05:17.243Z" }, - { url = "https://files.pythonhosted.org/packages/a5/5b/c61b043ad2e091fbe1f2d35d14795e545d0b56b03edaa390fa1dcee3d160/librt-0.9.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22", size = 70595, upload-time = "2026-04-09T16:05:18.471Z" }, - { url = "https://files.pythonhosted.org/packages/a3/22/2448471196d8a73370aa2f23445455dc42712c21404081fcd7a03b9e0749/librt-0.9.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a", size = 204354, upload-time = "2026-04-09T16:05:19.593Z" }, - { url = "https://files.pythonhosted.org/packages/ac/5e/39fc4b153c78cfd2c8a2dcb32700f2d41d2312aa1050513183be4540930d/librt-0.9.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5", size = 216238, upload-time = "2026-04-09T16:05:20.868Z" }, - { url = "https://files.pythonhosted.org/packages/d7/42/bc2d02d0fa7badfa63aa8d6dcd8793a9f7ef5a94396801684a51ed8d8287/librt-0.9.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11", size = 230589, upload-time = "2026-04-09T16:05:22.305Z" }, - { url = "https://files.pythonhosted.org/packages/c8/7b/e2d95cc513866373692aa5edf98080d5602dd07cabfb9e5d2f70df2f25f7/librt-0.9.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858", size = 224610, upload-time = "2026-04-09T16:05:23.647Z" }, - { url = "https://files.pythonhosted.org/packages/31/d5/6cec4607e998eaba57564d06a1295c21b0a0c8de76e4e74d699e627bd98c/librt-0.9.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e", size = 232558, upload-time = "2026-04-09T16:05:25.025Z" }, - { url = "https://files.pythonhosted.org/packages/95/8c/27f1d8d3aaf079d3eb26439bf0b32f1482340c3552e324f7db9dca858671/librt-0.9.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0", size = 225521, upload-time = "2026-04-09T16:05:26.311Z" }, - { url = "https://files.pythonhosted.org/packages/6b/d8/1e0d43b1c329b416017619469b3c3801a25a6a4ef4a1c68332aeaa6f72ca/librt-0.9.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2", size = 227789, upload-time = "2026-04-09T16:05:27.624Z" }, - { url = "https://files.pythonhosted.org/packages/2c/b4/d3d842e88610fcd4c8eec7067b0c23ef2d7d3bff31496eded6a83b0f99be/librt-0.9.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d", size = 248616, upload-time = "2026-04-09T16:05:29.181Z" }, - { url = "https://files.pythonhosted.org/packages/ec/28/527df8ad0d1eb6c8bdfa82fc190f1f7c4cca5a1b6d7b36aeabf95b52d74d/librt-0.9.0-cp313-cp313-win32.whl", hash = "sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd", size = 56039, upload-time = "2026-04-09T16:05:30.709Z" }, - { url = "https://files.pythonhosted.org/packages/f3/a7/413652ad0d92273ee5e30c000fc494b361171177c83e57c060ecd3c21538/librt-0.9.0-cp313-cp313-win_amd64.whl", hash = "sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519", size = 63264, upload-time = "2026-04-09T16:05:31.881Z" }, - { url = "https://files.pythonhosted.org/packages/a4/0a/92c244309b774e290ddb15e93363846ae7aa753d9586b8aad511c5e6145b/librt-0.9.0-cp313-cp313-win_arm64.whl", hash = "sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5", size = 53728, upload-time = "2026-04-09T16:05:33.31Z" }, - { url = "https://files.pythonhosted.org/packages/cd/c1/184e539543f06ea2912f4b92a5ffaede4f9b392689e3f00acbf8134bee92/librt-0.9.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb", size = 67830, upload-time = "2026-04-09T16:05:34.517Z" }, - { url = "https://files.pythonhosted.org/packages/f3/ad/23399bdcb7afca819acacdef31b37ee59de261bd66b503a7995c03c4b0dc/librt-0.9.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499", size = 70280, upload-time = "2026-04-09T16:05:35.649Z" }, - { url = "https://files.pythonhosted.org/packages/9f/0b/4542dc5a2b8772dbf92cafb9194701230157e73c14b017b6961a23598b03/librt-0.9.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f", size = 201925, upload-time = "2026-04-09T16:05:36.739Z" }, - { url = "https://files.pythonhosted.org/packages/31/d4/8ee7358b08fd0cfce051ef96695380f09b3c2c11b77c9bfbc367c921cce5/librt-0.9.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1", size = 212381, upload-time = "2026-04-09T16:05:38.043Z" }, - { url = "https://files.pythonhosted.org/packages/f2/94/a2025fe442abedf8b038038dab3dba942009ad42b38ea064a1a9e6094241/librt-0.9.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f", size = 227065, upload-time = "2026-04-09T16:05:39.394Z" }, - { url = "https://files.pythonhosted.org/packages/7c/e9/b9fcf6afa909f957cfbbf918802f9dada1bd5d3c1da43d722fd6a310dc3f/librt-0.9.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a", size = 221333, upload-time = "2026-04-09T16:05:40.999Z" }, - { url = "https://files.pythonhosted.org/packages/ac/7c/ba54cd6aa6a3c8cd12757a6870e0c79a64b1e6327f5248dcff98423f4d43/librt-0.9.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f", size = 229051, upload-time = "2026-04-09T16:05:42.605Z" }, - { url = "https://files.pythonhosted.org/packages/4b/4b/8cfdbad314c8677a0148bf0b70591d6d18587f9884d930276098a235461b/librt-0.9.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845", size = 222492, upload-time = "2026-04-09T16:05:43.842Z" }, - { url = "https://files.pythonhosted.org/packages/1f/d1/2eda69563a1a88706808decdce035e4b32755dbfbb0d05e1a65db9547ed1/librt-0.9.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b", size = 223849, upload-time = "2026-04-09T16:05:45.054Z" }, - { url = "https://files.pythonhosted.org/packages/04/44/b2ed37df6be5b3d42cfe36318e0598e80843d5c6308dd63d0bf4e0ce5028/librt-0.9.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b", size = 245001, upload-time = "2026-04-09T16:05:46.34Z" }, - { url = "https://files.pythonhosted.org/packages/47/e7/617e412426df89169dd2a9ed0cc8752d5763336252c65dbf945199915119/librt-0.9.0-cp314-cp314-win32.whl", hash = "sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9", size = 51799, upload-time = "2026-04-09T16:05:47.738Z" }, - { url = "https://files.pythonhosted.org/packages/24/ed/c22ca4db0ca3cbc285e4d9206108746beda561a9792289c3c31281d7e9df/librt-0.9.0-cp314-cp314-win_amd64.whl", hash = "sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e", size = 59165, upload-time = "2026-04-09T16:05:49.198Z" }, - { url = "https://files.pythonhosted.org/packages/24/56/875398fafa4cbc8f15b89366fc3287304ddd3314d861f182a4b87595ace0/librt-0.9.0-cp314-cp314-win_arm64.whl", hash = "sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f", size = 49292, upload-time = "2026-04-09T16:05:50.362Z" }, - { url = "https://files.pythonhosted.org/packages/4c/61/bc448ecbf9b2d69c5cff88fe41496b19ab2a1cbda0065e47d4d0d51c0867/librt-0.9.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4", size = 70175, upload-time = "2026-04-09T16:05:51.564Z" }, - { url = "https://files.pythonhosted.org/packages/60/f2/c47bb71069a73e2f04e70acbd196c1e5cc411578ac99039a224b98920fd4/librt-0.9.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228", size = 72951, upload-time = "2026-04-09T16:05:52.699Z" }, - { url = "https://files.pythonhosted.org/packages/29/19/0549df59060631732df758e8886d92088da5fdbedb35b80e4643664e8412/librt-0.9.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54", size = 225864, upload-time = "2026-04-09T16:05:53.895Z" }, - { url = "https://files.pythonhosted.org/packages/9d/f8/3b144396d302ac08e50f89e64452c38db84bc7b23f6c60479c5d3abd303c/librt-0.9.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71", size = 241155, upload-time = "2026-04-09T16:05:55.191Z" }, - { url = "https://files.pythonhosted.org/packages/7a/ce/ee67ec14581de4043e61d05786d2aed6c9b5338816b7859bcf07455c6a9f/librt-0.9.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938", size = 252235, upload-time = "2026-04-09T16:05:56.549Z" }, - { url = "https://files.pythonhosted.org/packages/8a/fa/0ead15daa2b293a54101550b08d4bafe387b7d4a9fc6d2b985602bae69b6/librt-0.9.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3", size = 244963, upload-time = "2026-04-09T16:05:57.858Z" }, - { url = "https://files.pythonhosted.org/packages/29/68/9fbf9a9aa704ba87689e40017e720aced8d9a4d2b46b82451d8142f91ec9/librt-0.9.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283", size = 257364, upload-time = "2026-04-09T16:05:59.686Z" }, - { url = "https://files.pythonhosted.org/packages/1a/8d/9d60869f1b6716c762e45f66ed945b1e5dd649f7377684c3b176ae424648/librt-0.9.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee", size = 247661, upload-time = "2026-04-09T16:06:00.938Z" }, - { url = "https://files.pythonhosted.org/packages/70/ff/a5c365093962310bfdb4f6af256f191085078ffb529b3f0cbebb5b33ebe2/librt-0.9.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c", size = 248238, upload-time = "2026-04-09T16:06:02.537Z" }, - { url = "https://files.pythonhosted.org/packages/a0/3c/2d34365177f412c9e19c0a29f969d70f5343f27634b76b765a54d8b27705/librt-0.9.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15", size = 269457, upload-time = "2026-04-09T16:06:03.833Z" }, - { url = "https://files.pythonhosted.org/packages/bc/cd/de45b239ea3bdf626f982a00c14bfcf2e12d261c510ba7db62c5969a27cd/librt-0.9.0-cp314-cp314t-win32.whl", hash = "sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40", size = 52453, upload-time = "2026-04-09T16:06:05.229Z" }, - { url = "https://files.pythonhosted.org/packages/7f/f9/bfb32ae428aa75c0c533915622176f0a17d6da7b72b5a3c6363685914f70/librt-0.9.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118", size = 60044, upload-time = "2026-04-09T16:06:06.398Z" }, - { url = "https://files.pythonhosted.org/packages/aa/47/7d70414bcdbb3bc1f458a8d10558f00bbfdb24e5a11740fc8197e12c3255/librt-0.9.0-cp314-cp314t-win_arm64.whl", hash = "sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61", size = 50009, upload-time = "2026-04-09T16:06:07.995Z" }, +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/39/cb/c1945e506893b5b8577fb45a60c80e3ffe4a82092a04a6f29b0b951d9a24/librt-0.10.0.tar.gz", hash = "sha256:1aba1e8aa4e3307a7be68a74149545fde7451964dc0235a8bec5704a17bdda42", size = 191799, upload-time = "2026-05-05T16:31:23.535Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/18/827e5c1262a88c2602e86f99aee0f288ffea3280dbd2ff448858ef9dc6e9/librt-0.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7dc99f9642100b86e5f6bb14cdc9970009e31a9ef7d64df6704b7018451524a3", size = 76461, upload-time = "2026-05-05T16:29:00.422Z" }, + { url = "https://files.pythonhosted.org/packages/ee/90/54254e30287f5a5abec6fef22d976987476e966be5fdff51fe8c2d5d73d1/librt-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8298cedfcfaff3790000bd057aaaa3df1b0ab54cf7b48eeab16184cbb1bc66b9", size = 79740, upload-time = "2026-05-05T16:29:01.926Z" }, + { url = "https://files.pythonhosted.org/packages/4c/20/e93264b52113669d98d3b63ff94d4ce0c4dd49ae0503f1788440a884e5f0/librt-0.10.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee7dbe312dbf76468255b79a7ba311236fde620f2f7055fc09d421e31340314e", size = 243472, upload-time = "2026-05-05T16:29:03.373Z" }, + { url = "https://files.pythonhosted.org/packages/35/ad/34a5141178e8b18a4cfa45d1a0d523c84397e2abd5d06fea2d846da687e8/librt-0.10.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:56ed90c48c19249012dadfd79a1bc13bd5168ea60a70722d330a3a600c0b1852", size = 232073, upload-time = "2026-05-05T16:29:04.815Z" }, + { url = "https://files.pythonhosted.org/packages/97/1f/67240e910cd9f9ab1498c1470738345fc29dce5dc9719db1e0e09d1e861f/librt-0.10.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d74ca0f4b2b09c117f913d4df01f6b934dff8a271096b35167d5264a31649f0", size = 256956, upload-time = "2026-05-05T16:29:06.516Z" }, + { url = "https://files.pythonhosted.org/packages/22/50/3a2b3482c27d607f6e8216d913c6bc592b9a2141d96990309452340a78e3/librt-0.10.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8eb2daa9375f93c0e55ff5e44a4bbe98f39e5fe52e1abf9c97acb67743b61bf8", size = 250593, upload-time = "2026-05-05T16:29:08.324Z" }, + { url = "https://files.pythonhosted.org/packages/e7/1c/07dba133d79f93322fa17514062f1a2a50d6bdfb7baec4acf78193d7fad1/librt-0.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7b09b90e634e6dff57978cd358070046071e2b120501f10787aeb35425f504f6", size = 263582, upload-time = "2026-05-05T16:29:09.866Z" }, + { url = "https://files.pythonhosted.org/packages/aa/ac/033f2c6d6ab0b48f15f02e5bf065521b11a51922806017f8b6274df30d69/librt-0.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2cf22fd379d60c739b800d4295ed34045f8b04aa8df9c12bd2f8f43f7fe672b7", size = 259307, upload-time = "2026-05-05T16:29:11.675Z" }, + { url = "https://files.pythonhosted.org/packages/6e/10/679046cd75d5a52c0104c890d8f69574ef4e619c683e59c15584d03a2457/librt-0.10.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:74c798793fcf29a84d442278ebe0bb1fff79fe58ac4106eeff7019cbba861423", size = 257342, upload-time = "2026-05-05T16:29:13.14Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d5/dbaac9c0884f78a53dda22b9ec92bb788e1400e762ed7623fa96928c8da5/librt-0.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dc4f1573401e8dbe6c26511fe027620b0fb30ae9a7ab814e02e510626b8b5f9c", size = 280141, upload-time = "2026-05-05T16:29:14.922Z" }, + { url = "https://files.pythonhosted.org/packages/cc/81/71f18cf8eb340d9fda011498870910f6a8697aeb50833005d3d8107653fd/librt-0.10.0-cp310-cp310-win32.whl", hash = "sha256:e1428275f5fe3d4db6822e58d8b005a5b28ffca55e8433ebc051247fbe46429f", size = 62257, upload-time = "2026-05-05T16:29:16.226Z" }, + { url = "https://files.pythonhosted.org/packages/df/52/6bcebc2f870c4836bcb372be885fae7f17a1d25037d3a8250ef79fbe0124/librt-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:0708e9408f585b0f065081680583a577652099680ccf820c7538904322b679c3", size = 70321, upload-time = "2026-05-05T16:29:17.41Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a3/1472717d2325adacc8d335ba2e4078015c09d75b599f3cf48e967b3d306e/librt-0.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01b4500ca3a625450c032a9142a8e843923ce263fa8a92ad1b38927cabe2fe72", size = 76045, upload-time = "2026-05-05T16:29:18.731Z" }, + { url = "https://files.pythonhosted.org/packages/a6/31/bfe32355d4b369aef3d7aa442df663bb5558c2ffa2de286cb2956346bc24/librt-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b7e42d1b3e300d20bfc87e72ffd62f0a92a2cb3c35f7bf90df90c9d2a49f74c", size = 79466, upload-time = "2026-05-05T16:29:20.052Z" }, + { url = "https://files.pythonhosted.org/packages/e9/f1/83f8a2c715ba2cac9b7387a5a5cea25f717f7184320cfe48b36bed9c58e9/librt-0.10.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8ef7b8c61ce3a1b597cd3e15348ff1574325165c2e7ce09a718154cde2a7950", size = 242283, upload-time = "2026-05-05T16:29:21.596Z" }, + { url = "https://files.pythonhosted.org/packages/cc/94/c3a4ce94857f0004a542f86662806383611858f522722db58efaec0a1472/librt-0.10.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:e73c84f72d1fa0d6eaa7a1930b436ba8d2c90c58d77bfabb09995a69ad35f6c0", size = 230735, upload-time = "2026-05-05T16:29:23.335Z" }, + { url = "https://files.pythonhosted.org/packages/d1/41/e962bb26c7728eb7b3a69e490d0c800fd9968a6970e390c1f18ddb56093d/librt-0.10.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9728cb98713bd862fb8f4fd6a642d1896c86058a41d77c70f3d5cee75e725275", size = 256606, upload-time = "2026-05-05T16:29:24.91Z" }, + { url = "https://files.pythonhosted.org/packages/66/3a/4e46a707b1ecc993fd691071623b9beab89703a63bd21cc7807e06c28209/librt-0.10.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:648b7e941d20acd72f9652115e0e53facd98156d61f9ebf7a812bdef8bdccea9", size = 249739, upload-time = "2026-05-05T16:29:26.648Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f5/dc5b7eb294656ad23d4ff4cf8514208d54fe1026b909d726a0dc026689c9/librt-0.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c3e33747c068e86a9007c20fdb777eb5ba8d3d19136d7812f88e69a713041b6f", size = 261414, upload-time = "2026-05-05T16:29:28.702Z" }, + { url = "https://files.pythonhosted.org/packages/58/e4/990ed8d12c7f114ac8f8ccd47f7d9bd9704ef61acfcb1df4a05047da7710/librt-0.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d509c745bf7e77d1107cf05e6abb249dc03fad13eb39f2286a49deedaeb2bcd7", size = 256614, upload-time = "2026-05-05T16:29:30.357Z" }, + { url = "https://files.pythonhosted.org/packages/60/eb/52d2726c7fb22818507dc3cc166c8f36dd4a4b68a7be67f12006ac8777c1/librt-0.10.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:786ad5a15e99d0e0e74f3adbeecc198a5ac58f340be07e984723d1e0074838de", size = 255144, upload-time = "2026-05-05T16:29:32.106Z" }, + { url = "https://files.pythonhosted.org/packages/bc/df/bd5591a78f7531fce4b6eb9962aadc6adc9560a01570442a884b6e554abe/librt-0.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:075582d877a97ee3d8e77bda3689dbe617b14f6469224a2d80b4b6c38e3951aa", size = 279121, upload-time = "2026-05-05T16:29:33.688Z" }, + { url = "https://files.pythonhosted.org/packages/fd/df/7c2b838dfc89a1762dd156d8b0c39848a7a2845d725a50be5a6e021fb8ba/librt-0.10.0-cp311-cp311-win32.whl", hash = "sha256:75ecdc3f5a90065aa2af2e574706c5495adc392520762dcf10b1aa716f0b8090", size = 62593, upload-time = "2026-05-05T16:29:35.152Z" }, + { url = "https://files.pythonhosted.org/packages/91/19/22ff572981049a9d436a083dbea1572d0f5dc068b7353637d2dd9977c8f1/librt-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:b6f6084884131d8a52cb9d7095ff2aa52c1e786d9fdaefab1fb4515415e9e083", size = 70914, upload-time = "2026-05-05T16:29:36.407Z" }, + { url = "https://files.pythonhosted.org/packages/12/22/1697cc64f4a5c7e9bce55e99c6d234a346beaedaefcd1e2ca90dd285f98c/librt-0.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:0140bd62151160047e89b2730cb6f8506cdac5127baa1afb9231e4dd3fe7f681", size = 61176, upload-time = "2026-05-05T16:29:37.62Z" }, + { url = "https://files.pythonhosted.org/packages/12/8e/cbb5b6f6e45e65c10a42449a69eaccc44d73e6a081ea752fbc5221c6dc1c/librt-0.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b4b58a44b407e91f633dafee008de9ddea6aa2a555ed94929c099260910bd0ba", size = 77327, upload-time = "2026-05-05T16:29:38.919Z" }, + { url = "https://files.pythonhosted.org/packages/e9/3d/8233cbee8e99e6a8992f02bfc2dec8d787509566a511d1fde2574ee7473f/librt-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:950b79b11762531bdf45a9df909d2f9a2a8445c70c88665c01d14c8511a27dc5", size = 79971, upload-time = "2026-05-05T16:29:40.96Z" }, + { url = "https://files.pythonhosted.org/packages/87/6f/5264b298cef2b72fc97d2dde56c66181eda35204bf5dcd1ed0c3d0a0a782/librt-0.10.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4538453f51be197633b425912c150e25b0667252d3741c53e8368176d98d9d37", size = 246559, upload-time = "2026-05-05T16:29:42.701Z" }, + { url = "https://files.pythonhosted.org/packages/07/7b/19b1b859cc60d5f99276cc2b3144d91556c6d1b1e4ebb50359696bebf7a8/librt-0.10.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:70b955f091beac93e994a0b7ec616934f63b3ea5c3d6d7af847562f935aceca7", size = 235216, upload-time = "2026-05-05T16:29:44.193Z" }, + { url = "https://files.pythonhosted.org/packages/6e/56/a2f40717142a8af46289f57874ef914353d8faccd5e4f8e594ab1e16e8c7/librt-0.10.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:483e685e06b6163728ba6c85d74315176be7190f432ec2a41226e5e14355d5f0", size = 263108, upload-time = "2026-05-05T16:29:46.365Z" }, + { url = "https://files.pythonhosted.org/packages/67/ca/15c625c3bdc0167c01e04ef8878317e9713f3bfa788438342f7a94c7b22c/librt-0.10.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ac53d946a009d1a38c44a60812708c9458fb2a239a5f630d8e625571386650f", size = 255280, upload-time = "2026-05-05T16:29:48.087Z" }, + { url = "https://files.pythonhosted.org/packages/ed/c5/ba301d571d9e05844e2435b73aba30bee77bb75ce155c9affcfd2173dd03/librt-0.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc8771c9fcf0ea894ca41fdc2abd83572c2fbda221f232d86e718614e57ff513", size = 268829, upload-time = "2026-05-05T16:29:49.628Z" }, + { url = "https://files.pythonhosted.org/packages/8b/60/af70e135bc1f1fe15dd3894b1e4bbefc7ecdf911749a925a39eb86ceb2a1/librt-0.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:70805dbc5257892ac572f86290a61e3c8d90224ecce1a8b2d1f7ed51965417f4", size = 262051, upload-time = "2026-05-05T16:29:51.244Z" }, + { url = "https://files.pythonhosted.org/packages/83/c2/c8236eb8b421bac5a172ba208f965abaa89805da2a3fa112bdf1764caf8f/librt-0.10.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d3b4f300f7bcba6e2ff73fb8bef1898479e9772bfa2682998c636391633ec826", size = 264347, upload-time = "2026-05-05T16:29:53.013Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f5/15b6d32bc25dacd4a60886a683d8128d6219910c122202b995a40dd4f8d2/librt-0.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:943bc943f92f4fb3408fae62485c6a3ad68ce4f2ee205643a39641525c19a276", size = 286482, upload-time = "2026-05-05T16:29:54.675Z" }, + { url = "https://files.pythonhosted.org/packages/fb/8e/b1b959bacd323eb4360579db992513e1406d1c6ef7edb57b5511fd0666fd/librt-0.10.0-cp312-cp312-win32.whl", hash = "sha256:6065c1a758fba1010b41401013903d3d5d2750eab425ddedd584abac31d0630e", size = 62955, upload-time = "2026-05-05T16:29:56.39Z" }, + { url = "https://files.pythonhosted.org/packages/9e/4c/d4cd6e4b9fc24098e63cc85537d1b6689682aee96809c38f08072067cc2b/librt-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:d788ecbe208ab352dab0e105cc06057bf9a2fc7e58cabb0d751ad9e30062b9e2", size = 71191, upload-time = "2026-05-05T16:29:57.682Z" }, + { url = "https://files.pythonhosted.org/packages/2b/19/8641da1f63d24b92354a492f893c022d6b3a0df44e70c8eff49364613983/librt-0.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:6003d1f295bdba02656dc81308208fc060d0a51d8c0d0a6db70f7f3c57b9ba0a", size = 61432, upload-time = "2026-05-05T16:29:58.971Z" }, + { url = "https://files.pythonhosted.org/packages/e5/29/681a75c82f4cc90d29e4b257a3299b79fe13fe927a04c57b8109d70b6957/librt-0.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f0ede79d682e73f91c1b599a76d78b7464b9b5d213754cedb13372d9df36e596", size = 77299, upload-time = "2026-05-05T16:30:00.209Z" }, + { url = "https://files.pythonhosted.org/packages/62/24/0c7ca445a55d04be79cac19819437fd094782347fa116f6681844fa6143e/librt-0.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e0ba0b131fdb336c8b9c948e397f4a7e649d0f783b529f07b647bf4961df392e", size = 79930, upload-time = "2026-05-05T16:30:01.555Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1f/1e2b8f6443ef9e9a81e89486ca70e22f3684f93db003ce6eaefc3d0839b9/librt-0.10.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2728117da2afb96fb957768725ee43dc9a2d73b031e02da424b818a3cdd3a275", size = 246195, upload-time = "2026-05-05T16:30:03.261Z" }, + { url = "https://files.pythonhosted.org/packages/74/61/9dc9e03de0439ad84c1c240aac8b747f12c90cb797ea6042f7bdb8d3410f/librt-0.10.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:723ba80594c49cdf0584196fc430752262605dc9449902fc9bd3d9b79976cb77", size = 234951, upload-time = "2026-05-05T16:30:04.881Z" }, + { url = "https://files.pythonhosted.org/packages/55/f4/635223117d7590875bca441275065a3bf491203ad4208bd1cc3ffd90c5a1/librt-0.10.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7292edaaca294a61a978c53a3c7d6130d099b0dfbc8f0a65916cdc6b891b9852", size = 262768, upload-time = "2026-05-05T16:30:06.638Z" }, + { url = "https://files.pythonhosted.org/packages/e5/66/b04152d0cd8b6ca2b428a8bd3230343230c35ed304a932f35b5375f2f828/librt-0.10.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:89fe9d539f2c10a1666633eeeac507ce95dd06d9ecc58de3c6390dba156a3d3a", size = 255075, upload-time = "2026-05-05T16:30:08.216Z" }, + { url = "https://files.pythonhosted.org/packages/35/1e/25bac4c7f2ca36f0e612cade186970683cf79153d96beccc3a11a9e19b97/librt-0.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4efa7b9587503fa5b67f40593302b9c8836d211d222ff9f7cafe67be5f8f0b10", size = 268559, upload-time = "2026-05-05T16:30:10.1Z" }, + { url = "https://files.pythonhosted.org/packages/18/54/4601faab35b6632a13200faa146ca62bfd111ffbe2568be430d65c89493a/librt-0.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:22dc982ef59df0136df36092ccbdbb570ced8aafb33e49585739b2f1de1c13b6", size = 261753, upload-time = "2026-05-05T16:30:11.912Z" }, + { url = "https://files.pythonhosted.org/packages/1b/cf/39f4023509e94fade8b074666fa3292db9cb6b34ea5dcbe7af53df9fca1d/librt-0.10.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:6f2e5f3606253a84cea719c94a3bb1c54487b5d617d0254d46e0920d8a06be3f", size = 264055, upload-time = "2026-05-05T16:30:13.465Z" }, + { url = "https://files.pythonhosted.org/packages/8e/00/40247209fc46a8e308a91412d5206aedf8efb667ee89eb625820106a5c2f/librt-0.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:40884bfaa1e29f6b6a9be255007d8f359bfc9e61d68bdef8ed3158bfcbc95df9", size = 286190, upload-time = "2026-05-05T16:30:15.073Z" }, + { url = "https://files.pythonhosted.org/packages/d8/6e/5566beb94431a985abe1787af5ef86e087750172ff9d0bbf20f93e88132d/librt-0.10.0-cp313-cp313-win32.whl", hash = "sha256:3cd34cd8254eba756660bff6c2da91278248184301054fe3e4feb073bdd49b14", size = 62949, upload-time = "2026-05-05T16:30:16.503Z" }, + { url = "https://files.pythonhosted.org/packages/d0/c2/3ea3301d6c8dff51d39dbe8ed75db3dc92896947d4afb5eeadf821c1e67f/librt-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:7baac5313e2d8dce1386f97777a8d03ab28f5fe1e780b3b9ac2ee7544551fedc", size = 71152, upload-time = "2026-05-05T16:30:17.766Z" }, + { url = "https://files.pythonhosted.org/packages/3c/de/5d49cb92cadcbc77d3abc27b93fd6030ed8437487dde2eae38cab5e6704d/librt-0.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:afc5b4406c8e2515698d922a5c7823a009312835ea58196671fff40e35cb8166", size = 61336, upload-time = "2026-05-05T16:30:19.021Z" }, + { url = "https://files.pythonhosted.org/packages/6a/64/7165e08108cc185a13a9c069f0685e6ef92e70e07fddf7edf5e7348c6316/librt-0.10.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f09588a30e6a22ec624090d72a3ab1a6d4d5485c3ed739603e76aa3c16efa688", size = 76794, upload-time = "2026-05-05T16:30:20.392Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ef/bf8613febf651b90c5222ee79dea5ae58d4cc2b544df69d3033424448934/librt-0.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:131ade118d12bd7a0adc4e655474a553f1b76cf78385868885944d21d51e45e0", size = 79662, upload-time = "2026-05-05T16:30:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/b6/67/9eddd165c1d8397bdf99b38bf12b5a55b3def5035b49eedb49f2775d1430/librt-0.10.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8b9ab28e40d011c373a189eae900c916e66d6fbecf7983e9e4883089ee085ef", size = 242390, upload-time = "2026-05-05T16:30:23.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/d1/d95da80334501866cd37004ab5d7483220d05862fab4b5405394f0264f0d/librt-0.10.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:67c39bb30da73bae1f293d1ed8bc2f8f6642649dd0928d3600aeff3041ac23d6", size = 232603, upload-time = "2026-05-05T16:30:25.198Z" }, + { url = "https://files.pythonhosted.org/packages/0c/fa/e6d64d28718bc1be4e1736fcb037ca1c4dfca927e7167df75a7d5215665e/librt-0.10.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8c3273c6b774614f093c8927c2bf1b077d0fefde988fe98f46a333734e5597ab", size = 259187, upload-time = "2026-05-05T16:30:26.772Z" }, + { url = "https://files.pythonhosted.org/packages/72/3f/3fdb77e7f937dad59cfd76b720be7e7643400ec76b2da35befab8d66ba30/librt-0.10.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9dd7c1b86a4baa583ab5db977484b93a2c474e69e96ef3e9538387ea54229cb9", size = 251846, upload-time = "2026-05-05T16:30:28.56Z" }, + { url = "https://files.pythonhosted.org/packages/18/ca/f4d49133dd86a6f55d79eca30bf412fa722f511a9abe67f62f57aa64e66a/librt-0.10.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a77385c5a202e831149f7ad03be9e67cf80e957e52c614e83dcb822c95222eb8", size = 264936, upload-time = "2026-05-05T16:30:30.491Z" }, + { url = "https://files.pythonhosted.org/packages/de/66/a8df2fbadc1f6c1827a096d11c40175bd526133480bd3bc88ec64a03d257/librt-0.10.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c6a5eafa74b5655bad59886138ed68426f098a6beb8cb95a71f2cc3cd8bb33fe", size = 258699, upload-time = "2026-05-05T16:30:32.002Z" }, + { url = "https://files.pythonhosted.org/packages/bb/73/1e3c83613fe05451bb969e27b68a573d177f08d5f63533cc29fec0989658/librt-0.10.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1fc93d0439204c50ab4d1512611ce2c206f1b369b419f69c7c27c761561e3291", size = 259825, upload-time = "2026-05-05T16:30:35.077Z" }, + { url = "https://files.pythonhosted.org/packages/09/24/5e2f926ee9d3ef348d9339526d7062abb5c44d8419e3179528c01d78c102/librt-0.10.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:79e713c178bc7a744adfbee6b4619a288eecc0c914da2a9313a20255abe2f0cf", size = 282548, upload-time = "2026-05-05T16:30:36.639Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7d/3e89ed6ad0162561fa8bef9df3195e24263104c955713cd0237d3711fad2/librt-0.10.0-cp314-cp314-win32.whl", hash = "sha256:2eba9d955a68c41d9f326be3da42f163ec3518b7ab20f1c826224e7bed71e0bf", size = 58970, upload-time = "2026-05-05T16:30:38.183Z" }, + { url = "https://files.pythonhosted.org/packages/76/25/579e731c94a7086a268bfa3e7a4945cd47836bebd3cbf3faeafd2e7eaef9/librt-0.10.0-cp314-cp314-win_amd64.whl", hash = "sha256:cbfaf7f5145e9917f5d18bffa298eff6a19d74e7b8b11dabdca95785befe8dbf", size = 67260, upload-time = "2026-05-05T16:30:39.804Z" }, + { url = "https://files.pythonhosted.org/packages/6e/f8/235822b7ae0b2334f12ee18bcf2476d07924077a5efeea57dbe927704be2/librt-0.10.0-cp314-cp314-win_arm64.whl", hash = "sha256:8d6d385d1969849a6b1397114df22714b6ded917bada98668e3e974dc663477e", size = 57156, upload-time = "2026-05-05T16:30:41.412Z" }, + { url = "https://files.pythonhosted.org/packages/9f/e3/9b919cbf1e8eb770bf91bb7df28125e0f1daf4587169afefd95402636e9a/librt-0.10.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:6c3a82d3bd32631ef5c79922dfc028520c9ad840255979ab4d908271818039ee", size = 79150, upload-time = "2026-05-05T16:30:42.761Z" }, + { url = "https://files.pythonhosted.org/packages/6a/f5/72a944aa3bc3498169a168087eff58ca48b58bf1b704e59d091fd30739f3/librt-0.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d64cc66005dc324c9bb1fa3fc2841f529002f6eb15966d55e46d430f56955a6a", size = 82304, upload-time = "2026-05-05T16:30:44.082Z" }, + { url = "https://files.pythonhosted.org/packages/9c/e3/fcc290a33e295019759472dfa794d204e43504b276ac65eab7fd9da20ea3/librt-0.10.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9bb562cd28c88cd2c6a9a6c78f99dc39348d6b16c94adc25de0e574acf1176e9", size = 272556, upload-time = "2026-05-05T16:30:45.497Z" }, + { url = "https://files.pythonhosted.org/packages/fd/54/546975e4c997573885e7f040a05012f8838e06fb12b0c3c1fbb76254e9d7/librt-0.10.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b809aa2854d019c28773b03605df22adc675ee4f3f4402d673581313e8906119", size = 256941, upload-time = "2026-05-05T16:30:47.059Z" }, + { url = "https://files.pythonhosted.org/packages/70/8c/f1d03401571b331653acddbd4e8cd955c06d945241dd08b25192fac0d04b/librt-0.10.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc15acabdd519bd4176fdadc2119e5e3093485d86f89138daf47e5b4cedb983a", size = 285855, upload-time = "2026-05-05T16:30:48.86Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/62cf80ff046c339faf56718b3a940244d4beb70f1c6407289b5830ec11e9/librt-0.10.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b1b2d835307d08ddadd94568e2369648ec9173bd3eea6d7f52a1abe717c81f98", size = 275321, upload-time = "2026-05-05T16:30:50.63Z" }, + { url = "https://files.pythonhosted.org/packages/d9/ea/da5918d4070362e9a4d2ee9cd34f9dc84902daad8fd4275f8504a727ff4e/librt-0.10.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d261c6a2f93335a5167887fb0223e8b98ffce20ee3fde242e8e58a37ece6d0e5", size = 293993, upload-time = "2026-05-05T16:30:52.577Z" }, + { url = "https://files.pythonhosted.org/packages/c9/8d/68b6086bed1fcdc314c640ea04e31e52d18052e08059fa595409d66a51a9/librt-0.10.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e2ffd44963f8e7f68995504d90f9881d64e94dc1d8e310039b9526108fc0c0f7", size = 284254, upload-time = "2026-05-05T16:30:55.086Z" }, + { url = "https://files.pythonhosted.org/packages/06/c8/b810f1d84ec34a5a7ed93d7b510ab04164d75fbdf23088d5c3fbe6b08357/librt-0.10.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5f285f6455ed495791c4d8630e5af732960adea93cac4c893d15619f2eae53e8", size = 284925, upload-time = "2026-05-05T16:30:56.728Z" }, + { url = "https://files.pythonhosted.org/packages/5a/00/3c82d4158c5a2c62528b8fccce65a8c9ad700e480e86f9389387435089a5/librt-0.10.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f6034ff52e663d34c7b82ef2aa2f94ad7c1d939e2368e63b06844bc4d127d2e1", size = 307830, upload-time = "2026-05-05T16:30:58.377Z" }, + { url = "https://files.pythonhosted.org/packages/99/3a/9c635ac3e8a00383ff689161d3eac8a30b3b2ddc711b40471e6b8983ea29/librt-0.10.0-cp314-cp314t-win32.whl", hash = "sha256:657860fd877fba6a241ea088ef99f63ca819945d3c715265da670bad56c37ebe", size = 60147, upload-time = "2026-05-05T16:31:00.293Z" }, + { url = "https://files.pythonhosted.org/packages/dc/e8/6f65f3e565d4ac212cddddd552eacc8035ffdf941ca0ad6fe945a211d41f/librt-0.10.0-cp314-cp314t-win_amd64.whl", hash = "sha256:56ded2d66010203a0cb5af063b609e3f079531a0e5e576d618dece859fd2e1af", size = 68649, upload-time = "2026-05-05T16:31:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/51/78/a0705a67cacd81e5fa01a5035b3adbdfbb43a7b8d4bd27e2b282ae61baf2/librt-0.10.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1ee63f30abf18ed4830fdbaf87b2b6f4bba1e198d46085c314edde4045e56715", size = 58247, upload-time = "2026-05-05T16:31:03.191Z" }, ] [[package]] @@ -1138,7 +1176,7 @@ linkify = [ [[package]] name = "markdown-it-py" -version = "4.0.0" +version = "4.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15'", @@ -1148,9 +1186,9 @@ resolution-markers = [ dependencies = [ { name = "mdurl", marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/5c/f3aedc83549aae71cd52b9e9687fe896e3dc6e966ba20eba04718605d198/markdown_it_py-4.1.0.tar.gz", hash = "sha256:760e3f87b2787c044c5138a5ba107b7c2be26c03b13cc7f8fe42756b65b1df6c", size = 81613, upload-time = "2026-05-06T16:32:13.649Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, + { url = "https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl", hash = "sha256:d4939a62a2dd0cd9cb80a191a711ba1d39bac8ed5ef9e9966895b0171c01c46d", size = 90955, upload-time = "2026-05-06T16:32:12.184Z" }, ] [package.optional-dependencies] @@ -1249,7 +1287,7 @@ version = "0.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655, upload-time = "2025-08-11T07:25:49.083Z" } wheels = [ @@ -1466,60 +1504,61 @@ wheels = [ [[package]] name = "mypy" -version = "1.20.2" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "ast-serialize" }, { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, { name = "mypy-extensions" }, { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/04/af/e3d4b3e9ec91a0ff9aabfdb38692952acf49bbb899c2e4c29acb3a6da3ae/mypy-1.20.2.tar.gz", hash = "sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665", size = 3817349, upload-time = "2026-04-21T17:12:28.473Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/97/ce2502df2cecf2ef997b6c6527c4a223b92feb9e7b790cdc8dcd683f3a8a/mypy-1.20.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4", size = 14457059, upload-time = "2026-04-21T17:06:14.935Z" }, - { url = "https://files.pythonhosted.org/packages/c9/34/417ee60b822cc80c0f3dc9f495ad7fd8dbb8d8b2cf4baf22d4046d25d01d/mypy-1.20.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997", size = 13346816, upload-time = "2026-04-21T17:10:41.433Z" }, - { url = "https://files.pythonhosted.org/packages/4a/85/e20951978702df58379d0bcc2e8f7ccdca4e78cd7dc66dd3ddbf9b29d517/mypy-1.20.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14", size = 13772593, upload-time = "2026-04-21T17:08:11.24Z" }, - { url = "https://files.pythonhosted.org/packages/63/a5/5441a13259ec516c56fd5de0fd96a69a9590ae6c5e5d3e5174aa84b97973/mypy-1.20.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99", size = 14656635, upload-time = "2026-04-21T17:09:54.042Z" }, - { url = "https://files.pythonhosted.org/packages/3b/51/b89c69157c5e1f19fd125a65d991166a26906e7902f026f00feebbcfa2b9/mypy-1.20.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c", size = 14943278, upload-time = "2026-04-21T17:09:15.599Z" }, - { url = "https://files.pythonhosted.org/packages/e9/44/6b0eeecfe96d7cce1d71c66b8e03cb304aa70ec11f1955dc1d6b46aca3c3/mypy-1.20.2-cp310-cp310-win_amd64.whl", hash = "sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd", size = 10851915, upload-time = "2026-04-21T17:06:03.5Z" }, - { url = "https://files.pythonhosted.org/packages/3c/36/6593dc88545d75fb96416184be5392da5e2a8e8c2802a8597913e16ae25c/mypy-1.20.2-cp310-cp310-win_arm64.whl", hash = "sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2", size = 9786676, upload-time = "2026-04-21T17:07:02.035Z" }, - { url = "https://files.pythonhosted.org/packages/1f/4d/9ebeae211caccbdaddde7ed5e31dfcf57faac66be9b11deb1dc6526c8078/mypy-1.20.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c", size = 14371307, upload-time = "2026-04-21T17:08:56.442Z" }, - { url = "https://files.pythonhosted.org/packages/95/d7/93473d34b61f04fac1aecc01368485c89c5c4af7a4b9a0cab5d77d04b63f/mypy-1.20.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3", size = 13258917, upload-time = "2026-04-21T17:05:50.978Z" }, - { url = "https://files.pythonhosted.org/packages/e2/30/3dd903e8bafb7b5f7bf87fcd58f8382086dea2aa19f0a7b357f21f63071b/mypy-1.20.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254", size = 13700516, upload-time = "2026-04-21T17:11:33.161Z" }, - { url = "https://files.pythonhosted.org/packages/07/05/c61a140aba4c729ac7bc99ae26fc627c78a6e08f5b9dd319244ea71a3d7e/mypy-1.20.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98", size = 14562889, upload-time = "2026-04-21T17:05:27.674Z" }, - { url = "https://files.pythonhosted.org/packages/fd/87/da78243742ffa8a36d98c3010f0d829f93d5da4e6786f1a1a6f2ad616502/mypy-1.20.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac", size = 14803844, upload-time = "2026-04-21T17:10:06.2Z" }, - { url = "https://files.pythonhosted.org/packages/37/52/10a1ddf91b40f843943a3c6db51e2df59c9e237f29d355e95eaab427461f/mypy-1.20.2-cp311-cp311-win_amd64.whl", hash = "sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67", size = 10846300, upload-time = "2026-04-21T17:12:23.886Z" }, - { url = "https://files.pythonhosted.org/packages/20/02/f9a4415b664c53bd34d6709be59da303abcae986dc4ac847b402edb6fa1e/mypy-1.20.2-cp311-cp311-win_arm64.whl", hash = "sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100", size = 9779498, upload-time = "2026-04-21T17:09:23.695Z" }, - { url = "https://files.pythonhosted.org/packages/71/4e/7560e4528db9e9b147e4c0f22660466bf30a0a1fe3d63d1b9d3b0fd354ee/mypy-1.20.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b", size = 14539393, upload-time = "2026-04-21T17:07:12.52Z" }, - { url = "https://files.pythonhosted.org/packages/32/d9/34a5efed8124f5a9234f55ac6a4ced4201e2c5b81e1109c49ad23190ec8c/mypy-1.20.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4", size = 13361642, upload-time = "2026-04-21T17:06:53.742Z" }, - { url = "https://files.pythonhosted.org/packages/d1/14/eb377acf78c03c92d566a1510cda8137348215b5335085ef662ab82ecd3a/mypy-1.20.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6", size = 13740347, upload-time = "2026-04-21T17:12:04.73Z" }, - { url = "https://files.pythonhosted.org/packages/b9/94/7e4634a32b641aa1c112422eed1bbece61ee16205f674190e8b536f884de/mypy-1.20.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066", size = 14734042, upload-time = "2026-04-21T17:07:43.16Z" }, - { url = "https://files.pythonhosted.org/packages/7a/f3/f7e62395cb7f434541b4491a01149a4439e28ace4c0c632bbf5431e92d1f/mypy-1.20.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102", size = 14964958, upload-time = "2026-04-21T17:11:00.665Z" }, - { url = "https://files.pythonhosted.org/packages/3e/0d/47e3c3a0ec2a876e35aeac365df3cac7776c36bbd4ed18cc521e1b9d255b/mypy-1.20.2-cp312-cp312-win_amd64.whl", hash = "sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9", size = 10911340, upload-time = "2026-04-21T17:10:49.179Z" }, - { url = "https://files.pythonhosted.org/packages/d6/b2/6c852d72e0ea8b01f49da817fb52539993cde327e7d010e0103dc12d0dac/mypy-1.20.2-cp312-cp312-win_arm64.whl", hash = "sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58", size = 9833947, upload-time = "2026-04-21T17:09:05.267Z" }, - { url = "https://files.pythonhosted.org/packages/5b/c4/b93812d3a192c9bcf5df405bd2f30277cd0e48106a14d1023c7f6ed6e39b/mypy-1.20.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026", size = 14524670, upload-time = "2026-04-21T17:10:30.737Z" }, - { url = "https://files.pythonhosted.org/packages/f3/47/42c122501bff18eaf1e8f457f5c017933452d8acdc52918a9f59f6812955/mypy-1.20.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943", size = 13336218, upload-time = "2026-04-21T17:08:44.069Z" }, - { url = "https://files.pythonhosted.org/packages/92/8f/75bbc92f41725fbd585fb17b440b1119b576105df1013622983e18640a93/mypy-1.20.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517", size = 13724906, upload-time = "2026-04-21T17:08:01.02Z" }, - { url = "https://files.pythonhosted.org/packages/a1/32/4c49da27a606167391ff0c39aa955707a00edc500572e562f7c36c08a71f/mypy-1.20.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15", size = 14726046, upload-time = "2026-04-21T17:11:22.354Z" }, - { url = "https://files.pythonhosted.org/packages/7f/fc/4e354a1bd70216359deb0c9c54847ee6b32ef78dfb09f5131ff99b494078/mypy-1.20.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee", size = 14955587, upload-time = "2026-04-21T17:12:16.033Z" }, - { url = "https://files.pythonhosted.org/packages/62/b2/c0f2056e9eb8f08c62cafd9715e4584b89132bdc832fcf85d27d07b5f3e5/mypy-1.20.2-cp313-cp313-win_amd64.whl", hash = "sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f", size = 10922681, upload-time = "2026-04-21T17:06:35.842Z" }, - { url = "https://files.pythonhosted.org/packages/e5/14/065e333721f05de8ef683d0aa804c23026bcc287446b61cac657b902ccac/mypy-1.20.2-cp313-cp313-win_arm64.whl", hash = "sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330", size = 9830560, upload-time = "2026-04-21T17:07:51.023Z" }, - { url = "https://files.pythonhosted.org/packages/ae/d1/b4ec96b0ecc620a4443570c6e95c867903428cfcde4206518eafdd5880c3/mypy-1.20.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30", size = 14524561, upload-time = "2026-04-21T17:06:27.325Z" }, - { url = "https://files.pythonhosted.org/packages/3a/63/d2c2ff4fa66bc49477d32dfa26e8a167ba803ea6a69c5efb416036909d30/mypy-1.20.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924", size = 13363883, upload-time = "2026-04-21T17:11:11.239Z" }, - { url = "https://files.pythonhosted.org/packages/2a/56/983916806bf4eddeaaa2c9230903c3669c6718552a921154e1c5182c701f/mypy-1.20.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb", size = 13742945, upload-time = "2026-04-21T17:08:34.181Z" }, - { url = "https://files.pythonhosted.org/packages/19/65/0cd9285ab010ee8214c83d67c6b49417c40d86ce46f1aa109457b5a9b8d7/mypy-1.20.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc", size = 14706163, upload-time = "2026-04-21T17:05:15.51Z" }, - { url = "https://files.pythonhosted.org/packages/94/97/48ff3b297cafcc94d185243a9190836fb1b01c1b0918fff64e941e973cc9/mypy-1.20.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558", size = 14938677, upload-time = "2026-04-21T17:05:39.562Z" }, - { url = "https://files.pythonhosted.org/packages/fd/a1/1b4233d255bdd0b38a1f284feeb1c143ca508c19184964e22f8d837ec851/mypy-1.20.2-cp314-cp314-win_amd64.whl", hash = "sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8", size = 11089322, upload-time = "2026-04-21T17:06:44.29Z" }, - { url = "https://files.pythonhosted.org/packages/78/c2/ce7ee2ba36aeb954ba50f18fa25d9c1188578654b97d02a66a15b6f09531/mypy-1.20.2-cp314-cp314-win_arm64.whl", hash = "sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3", size = 10017775, upload-time = "2026-04-21T17:07:20.732Z" }, - { url = "https://files.pythonhosted.org/packages/4e/a1/9d93a7d0b5859af0ead82b4888b46df6c8797e1bc5e1e262a08518c6d48e/mypy-1.20.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609", size = 15549002, upload-time = "2026-04-21T17:08:23.107Z" }, - { url = "https://files.pythonhosted.org/packages/00/d2/09a6a10ee1bf0008f6c144d9676f2ca6a12512151b4e0ad0ff6c4fac5337/mypy-1.20.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2", size = 14401942, upload-time = "2026-04-21T17:07:31.837Z" }, - { url = "https://files.pythonhosted.org/packages/57/da/9594b75c3c019e805250bed3583bdf4443ff9e6ef08f97e39ae308cb06f2/mypy-1.20.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c", size = 15041649, upload-time = "2026-04-21T17:09:34.653Z" }, - { url = "https://files.pythonhosted.org/packages/97/77/f75a65c278e6e8eba2071f7f5a90481891053ecc39878cc444634d892abe/mypy-1.20.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744", size = 15864588, upload-time = "2026-04-21T17:11:44.936Z" }, - { url = "https://files.pythonhosted.org/packages/d7/46/1a4e1c66e96c1a3246ddf5403d122ac9b0a8d2b7e65730b9d6533ba7a6d3/mypy-1.20.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6", size = 16093956, upload-time = "2026-04-21T17:10:17.683Z" }, - { url = "https://files.pythonhosted.org/packages/5a/2c/78a8851264dec38cd736ca5b8bc9380674df0dd0be7792f538916157716c/mypy-1.20.2-cp314-cp314t-win_amd64.whl", hash = "sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec", size = 12568661, upload-time = "2026-04-21T17:11:54.473Z" }, - { url = "https://files.pythonhosted.org/packages/83/01/cd7318aa03493322ce275a0e14f4f52b8896335e4e79d4fb8153a7ad2b77/mypy-1.20.2-cp314-cp314t-win_arm64.whl", hash = "sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382", size = 10389240, upload-time = "2026-04-21T17:09:42.719Z" }, - { url = "https://files.pythonhosted.org/packages/28/9a/f23c163e25b11074188251b0b5a0342625fc1cdb6af604757174fa9acc9b/mypy-1.20.2-py3-none-any.whl", hash = "sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563", size = 2637314, upload-time = "2026-04-21T17:05:54.5Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/cf/dc/7e6d49f04fca40b9dd5c752a51a432ffe67fb45200702bc9eee0cb4bbb26/mypy-2.0.0.tar.gz", hash = "sha256:1a9e3900ac5c40f1fe813506c7739da6e6f0eab2729067ebd94bfb0bbba53532", size = 3869036, upload-time = "2026-05-06T19:26:43.22Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/1e/9983d2d5b5d2dc3677177bcf0fa6b25185ecf750cc0559e02199625a31c5/mypy-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:65d6f22d643bccaeb182d41d2a9f0990a05a871673c4ae3f97d4931eca0d2294", size = 14663140, upload-time = "2026-05-06T19:25:59.474Z" }, + { url = "https://files.pythonhosted.org/packages/69/bc/b4009c91d3ced13c8f406acf47bbe56365025cd21bf6585cd1e87375a708/mypy-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:106650bce72114f43019bf72197296f51c2cd47adfa9d073ea2976c247a404c5", size = 13526733, upload-time = "2026-05-06T19:22:56.425Z" }, + { url = "https://files.pythonhosted.org/packages/f0/99/2403cb0ceeb1552f70e70e779e3d0713b24f84c7ca0e9e14b2b7bc684cf0/mypy-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c734b7eb89a4cc4ec347f8187ffa730e2b59693407bc93dcb878183037f80a17", size = 13951940, upload-time = "2026-05-06T19:24:43.45Z" }, + { url = "https://files.pythonhosted.org/packages/1d/f7/4848a14c2667b6eb62841c9aeb7e1f6479613b1ef9a65564fe1f5518a35b/mypy-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd9e60388944d0f1432a2419ab938a78d5658df1d143a7172cfe1a197276cf49", size = 14833983, upload-time = "2026-05-06T19:23:16.827Z" }, + { url = "https://files.pythonhosted.org/packages/ec/28/c51831f9f1c6e46cbce765bd0a18981b84696e40bd1eea14e0a08494af44/mypy-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f95e3890666c3be41af7a7179f4872341c08e90c161ba8e7a08a21f9be92c131", size = 15135591, upload-time = "2026-05-06T19:24:32.96Z" }, + { url = "https://files.pythonhosted.org/packages/40/7f/3c25e503a94f9ec18352464551bc6c506dee2bca93c6d0e0b5568eefc269/mypy-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:e8e8709ce1b1046b8aad77a506dd01491157102dd727128c0b374b5025c7d769", size = 10983019, upload-time = "2026-05-06T19:20:30.942Z" }, + { url = "https://files.pythonhosted.org/packages/75/da/5cf833fd3b53fd4b5797e55dc16fb7efab16fddbc7205d49ff65b15d554e/mypy-2.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:0165968759c99ab79dc1a9f8aaec18e93a1bedcf7c13edd70e68dd3d5faf17cb", size = 9914165, upload-time = "2026-05-06T19:21:49.165Z" }, + { url = "https://files.pythonhosted.org/packages/8b/1e/268b81393b81d64683f670680215553e70ae92c55805915b3440080e05e4/mypy-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17b7222e9fdfd352e61fb3131da117e55cc465f701ff232f1bd97a02bbad91f", size = 14580849, upload-time = "2026-05-06T19:23:06.567Z" }, + { url = "https://files.pythonhosted.org/packages/6e/32/d159a8002d9e5c44e59ece9d641a26956c89be5b6827f819d9a9dc678c65/mypy-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cc0a61adea1a5ffc2d47a4dc4bb180d8103f477fc2a90a1cdcbb168c2cc6caff", size = 13444955, upload-time = "2026-05-06T19:25:11.982Z" }, + { url = "https://files.pythonhosted.org/packages/cd/5d/3b28d5a2799591da0ee5490418e94497eaf5d701e42d8b001b5e17a9b3d6/mypy-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8578f857b519993d065e5805290b71467ebfae772407a5f57e823755e4fdb850", size = 13873124, upload-time = "2026-05-06T19:20:39.684Z" }, + { url = "https://files.pythonhosted.org/packages/60/23/f40f723955617b814d5ddc1154d8938b77aaf6926c2dbf72846e8943a0b7/mypy-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:33f668a37a650df60f7b825c1ac61e6baadd4ac3c89519e929badde58d28edf5", size = 14748822, upload-time = "2026-05-06T19:25:30.972Z" }, + { url = "https://files.pythonhosted.org/packages/d6/16/eded971224a483e422a141ffd580c00e1b919df8e529f06d03a4a987878c/mypy-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29ea6da86c8c5e9addd48fa6e624f467341b3814f54ded871b28980468686dea", size = 14992675, upload-time = "2026-05-06T19:23:34.511Z" }, + { url = "https://files.pythonhosted.org/packages/ea/6a/1cbd7290f00b4dbaa4c4502e53ac05645ea635e4d1e3dcd42687c2fc39cd/mypy-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:904baa0124ebbccf0c7ba94f722cf9186ee30478f5e5b11432ffc8929248ee55", size = 10983628, upload-time = "2026-05-06T19:26:39.48Z" }, + { url = "https://files.pythonhosted.org/packages/83/3f/8caa9bcc2636cd512642050747466b695fa2540d7040544fd7ddb721d671/mypy-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:440165501295e523bf1e5d3e411b62b367b901c65610938e75f0e56ba0462461", size = 9906041, upload-time = "2026-05-06T19:24:03.199Z" }, + { url = "https://files.pythonhosted.org/packages/f6/4b/f6cd12ef1eb63be1c342da3e8ca811d2280276177f6de4ef20cb2366d79b/mypy-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:660790551c988e69d8bf7a35c8b4149edeb22f4a339165702be843532e9dcdb5", size = 14756610, upload-time = "2026-05-06T19:26:19.221Z" }, + { url = "https://files.pythonhosted.org/packages/32/73/67d09ca28bee21feaca264b2a680cf2d300bcc2071136ad064928324c843/mypy-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7a15bf92cd8781f8e72f69ffa7e30d1f434402d065ee1ecd5223ef2ef100f914", size = 13554270, upload-time = "2026-05-06T19:26:08.977Z" }, + { url = "https://files.pythonhosted.org/packages/61/b3/44718b5c6b1b5a27440ff2effe6a1be0fa2a190c0f4e2e21a83728416f95/mypy-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ff370b43d7def05bbcd2f5267f0bcda72dd6a552ef2ea9375b02d6fe06da270", size = 13924663, upload-time = "2026-05-06T19:21:24.932Z" }, + { url = "https://files.pythonhosted.org/packages/6a/2b/bbb9cc5773f946846a7c340097e59bcf84095437dda0d56bb4f6cf1f6541/mypy-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37bd246590a018e5a11703b7b09c39d47ede3df5ba3fa863c5b8590b465beb01", size = 14946862, upload-time = "2026-05-06T19:24:23.023Z" }, + { url = "https://files.pythonhosted.org/packages/43/25/e9318566f443a5130b4ff0ad3367ee6c4c4c49ff083fe5214a7318c18282/mypy-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cce87e92214fac8bf8feb8a680d0c1b6fb748d50e9b57fbb13e4b1d83a3ed19b", size = 15175090, upload-time = "2026-05-06T19:26:28.794Z" }, + { url = "https://files.pythonhosted.org/packages/67/65/2ec28c834f21e164c33bc296a7db538ad50c74f83e517c7a0be95ff6de86/mypy-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:e19e9cb69b66a4141009d24898259914fa2b71d026de0b46edf9fafdbf4fd46e", size = 11052899, upload-time = "2026-05-06T19:25:39.084Z" }, + { url = "https://files.pythonhosted.org/packages/9e/72/d1ec625cfc9bd101c07a6834ef1f94e820296f8fdbad2eb03f50e0983f8c/mypy-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:b021614cb08d44785b025982163ec3c39c94bff766ead071fa9e82b4ef6f62cd", size = 9972935, upload-time = "2026-05-06T19:23:24.204Z" }, + { url = "https://files.pythonhosted.org/packages/e5/c6/996a1e535e5d0d597c3b1460fc962733091f885f312e749350eb2ac10965/mypy-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ef5f581b61240d1cc629b12f8df6565ed6ffac0d82ed745eef7833222ab50b9", size = 14737259, upload-time = "2026-05-06T19:20:23.081Z" }, + { url = "https://files.pythonhosted.org/packages/94/c5/0f9460e26b77f434bd53f47d1ce32a3cd4580c92a5331fa5dfc059f9421a/mypy-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:20e3470a165dbc249bdfbe8d1c5172727ef22688cffc279f8c3aa264ab9d4d9a", size = 13538377, upload-time = "2026-05-06T19:21:08.804Z" }, + { url = "https://files.pythonhosted.org/packages/b2/3e/8ea2f8dd1e5c9c279fb3c28193bdb850adf4d3d8172880abad829eced609/mypy-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:224ba142eee8b4d65d4db657cb1fc22abec30b135ded6ab297302ba1f62e505d", size = 13914264, upload-time = "2026-05-06T19:24:12.875Z" }, + { url = "https://files.pythonhosted.org/packages/be/ce/78bd3b8520f676acee9dab48ea71473e68f6d5cf14b59fbd800bea50a92b/mypy-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e879ad8a03908ff74d15e8a9b42bf049918e6798d52c011011f1873d0b5877e", size = 14926761, upload-time = "2026-05-06T19:20:12.846Z" }, + { url = "https://files.pythonhosted.org/packages/61/ef/b52fa340522da3d22e669117c3b83155c2660f7cdc035856958fbfffb224/mypy-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:65c5c15bcbd18d6fe927cc55c459597a3517d69cc3123f067be3b020010e115e", size = 15157014, upload-time = "2026-05-06T19:25:49.78Z" }, + { url = "https://files.pythonhosted.org/packages/7a/0c/dde7614250c6d017936c7aa3bb63b9b52c7cfd298d3f1be9be45f307870b/mypy-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:d1a068acd7c9fb77e9f8923f1556f2f49d6d7895821121b8d97fa5642b9c52f5", size = 11067049, upload-time = "2026-05-06T19:21:16.116Z" }, + { url = "https://files.pythonhosted.org/packages/27/ec/1d6af4830a94a285442db19caa02f160cc1a255e4f324eec5458e6c2bafb/mypy-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:ef9d96da1ddffbc21f27d3939319b6846d12393baa17c4d2f3e81e040e73ce2c", size = 9967903, upload-time = "2026-05-06T19:22:15.52Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2c/6fefe954207860aed6eeb91776795e64a257d3ce0360862288984ce121f5/mypy-2.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c918c64e8ce36557851b0347f84eb12f1965d3a06813c36df253eb0c0afd1d82", size = 14729633, upload-time = "2026-05-06T19:24:53.383Z" }, + { url = "https://files.pythonhosted.org/packages/23/d6/d336f5b820af189eb0390cce21de62d264c0a4e64713dfbe81bfc4fc7739/mypy-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:301f1a8ccc7d79b542ee218b28bb49443a83e194eb3d10da63ff1649e5aa5d34", size = 13559524, upload-time = "2026-05-06T19:22:24.906Z" }, + { url = "https://files.pythonhosted.org/packages/af/a6/d7bb54fde1770f0484e5fbdbdce37a41e95ed0a1cd493ec60ead111e356c/mypy-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf4ef489d44ce350bac3fd699907834e551d4c934e9cc862ef201215ab1558d", size = 13936018, upload-time = "2026-05-06T19:25:02.992Z" }, + { url = "https://files.pythonhosted.org/packages/7d/ba/5be51316b91e6a6bf6e3a8adb3de500e7e1fb5bf9491743b8cbc81a34a2c/mypy-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9cde2d0989f912fc850890f727d0d76495e7a6c5bdd9912a1efdb64952b4398d", size = 14910712, upload-time = "2026-05-06T19:25:21.83Z" }, + { url = "https://files.pythonhosted.org/packages/b7/37/e2c8c3b373e20ebfb66e6c83a99027fd67df4ec43b08879f74e822d2dc4c/mypy-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cdf05693c231a14fe37dbfce192a3a1372c26a833af4a80f550547742952e719", size = 15141499, upload-time = "2026-05-06T19:20:50.924Z" }, + { url = "https://files.pythonhosted.org/packages/12/36/07756f933e00416d912e35878cfcf89a593a3350a885691c0bb85ae0226a/mypy-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:73aee2da33a2237e66cbe84a94780e53599847e86bb3aa7b93e405e8cd9905f2", size = 11240511, upload-time = "2026-05-06T19:21:32.39Z" }, + { url = "https://files.pythonhosted.org/packages/70/05/79ac1f20f2397353f3845f7b8bb5d8006cda7c8ef9092f04f9de3c6135f2/mypy-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:1f6dcd8f39971f41edab2728c877c4ac8b50ad3c387ff2770423b79a05d23910", size = 10149336, upload-time = "2026-05-06T19:22:08.383Z" }, + { url = "https://files.pythonhosted.org/packages/53/e0/0db84e0ebbad6e99e566c68e4b465784f2a2294f7719e8db9d509ef23087/mypy-2.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a04e980b9275c76159da66c6e1723c7798306f9802b31bdaf9358d0c84030ce8", size = 15797362, upload-time = "2026-05-06T19:22:00.835Z" }, + { url = "https://files.pythonhosted.org/packages/0a/a4/14cc0768164dd53bec48aa41a20270b18df9bf72aa5054278bf133608315/mypy-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:33f9cf4825469b2bc73c53ba55f6d9a9b4cdb60f9e6e228745581520f29b8771", size = 14635914, upload-time = "2026-05-06T19:23:43.675Z" }, + { url = "https://files.pythonhosted.org/packages/08/48/d866a3e23b4dc5974c77d9cf65a435bf22de01a84dd4620917950e233960/mypy-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:191675c3c7dc2a5c7722a035a6909c277f14046c5e4e02aa5fbf65f8524f08ad", size = 15270866, upload-time = "2026-05-06T19:22:34.756Z" }, + { url = "https://files.pythonhosted.org/packages/71/eb/de9ef94958eb2078a6b908ceb247757dc384d3a238d3bd6ed7d81de5eaf8/mypy-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3d26c4321a3b06fc9f04c741e0733af693f82d823f8e64e47b2e63b7f19fa84", size = 16093131, upload-time = "2026-05-06T19:23:56.541Z" }, + { url = "https://files.pythonhosted.org/packages/ad/07/0ab2c1a9d26e90942612724cbd5788f16b7810c5dd39bfcf79286c6c4524/mypy-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bbcbc4d5917ca6ce12de70e051de7f533e3bf92d548b41a38a2232a6fe356525", size = 16330685, upload-time = "2026-05-06T19:21:42.037Z" }, + { url = "https://files.pythonhosted.org/packages/a6/8f/46f85d1371a5be642dad263828118ae1efd536d91d8bd2000c68acff3920/mypy-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:dbc6ba6d40572ae49268531565793a8f07eac7fc65ad76d482c9b4c8765b6043", size = 12752017, upload-time = "2026-05-06T19:22:44.002Z" }, + { url = "https://files.pythonhosted.org/packages/7a/e6/94ca48800cac19eb28a58188a768aaec0d16cac0f373915f073058ab0855/mypy-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:77926029dfcb7e1a3ecb0acb2ddbb24ca36be03f7d623e1759ad5376be8f6c01", size = 10527097, upload-time = "2026-05-06T19:20:58.973Z" }, + { url = "https://files.pythonhosted.org/packages/5c/14/fd0694aa594d6e9f9fd16ce821be2eff295197a273262ef56ddcc1388d68/mypy-2.0.0-py3-none-any.whl", hash = "sha256:8a92b2be3146b4fa1f062af7eb05574cbf3e6eb8e1f14704af1075423144e4e5", size = 2673434, upload-time = "2026-05-06T19:26:32.856Z" }, ] [[package]] @@ -1563,7 +1602,7 @@ resolution-markers = [ dependencies = [ { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "jinja2", marker = "python_full_version >= '3.11'" }, - { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "mdit-py-plugins", marker = "python_full_version >= '3.11'" }, { name = "pyyaml", marker = "python_full_version >= '3.11'" }, { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, @@ -1643,7 +1682,7 @@ requires-dist = [ { name = "jinja2" }, { name = "jsonschema", specifier = ">=4.0" }, { name = "markdown", specifier = ">=3.3" }, - { name = "mypy", marker = "extra == 'dev'" }, + { name = "mypy", marker = "extra == 'dev'", specifier = ">=2.0.0" }, { name = "myst-parser", marker = "extra == 'dev'" }, { name = "packaging" }, { name = "pdiff" }, @@ -2116,26 +2155,26 @@ wheels = [ [[package]] name = "prek" -version = "0.3.11" +version = "0.3.13" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/60/5b980c70525ca5f0d17942d8eae13b399051aa384413366fe5df229712ea/prek-0.3.11.tar.gz", hash = "sha256:c4cf77848009503c58d80ff216e32af45b63ea49652bb5546748c1ebfd4d9847", size = 433440, upload-time = "2026-04-27T04:22:59.923Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3c/59/0a279983f96bd5d538b4975f0a23121082aa3b8560b6649fdf61f8011b07/prek-0.3.13.tar.gz", hash = "sha256:c48586ee3708bfbf3df80121f55583e9a7d0fa166b08172c091fe5971e92a0ac", size = 444848, upload-time = "2026-05-05T18:07:09.076Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/2a/3392fa7d1fd1ce538915baa7597e7203bbe888367a8b15bfd51ca74d4714/prek-0.3.11-py3-none-linux_armv6l.whl", hash = "sha256:787e605716cfdc86ec01e7c5cf62799f39c28d49de5e37d75595c8e6248cb0f3", size = 5423112, upload-time = "2026-04-27T04:22:52.659Z" }, - { url = "https://files.pythonhosted.org/packages/a9/b0/3fc653b30b70d6c2714fc56bcfe1c2439437fc38f60b72bc300603ace4cd/prek-0.3.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ef1f37187ca52d75ba9c46b53007476c4eab2c3f11bd23defd57a81c62d90442", size = 5801382, upload-time = "2026-04-27T04:23:04.464Z" }, - { url = "https://files.pythonhosted.org/packages/2e/46/39aedc7843c3703f1f43b686622e4f8cd123e03b87a163e5c8f2fbd56cda/prek-0.3.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e0d0828a1b50447502ea1be3f5a84da474fdca558cd5d76a1a5205169bb808c7", size = 5370817, upload-time = "2026-04-27T04:22:49.277Z" }, - { url = "https://files.pythonhosted.org/packages/15/83/df5f3aeacbdea96a88c4f06c98d3932469711fed4e3bf5b703dd6507abe7/prek-0.3.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:bf49464b526ee36d2130baf60ab9580560bfaa60efd2997328e6d6671e209014", size = 5621405, upload-time = "2026-04-27T04:23:10.58Z" }, - { url = "https://files.pythonhosted.org/packages/8f/f2/e32c9720747a327669863a4f92d05b9e6fadb851e903b0d7310a97c956a4/prek-0.3.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac344529f0d34757c7c95f65e66b9f6440a691f826eaf43f503247bd22023558", size = 5339780, upload-time = "2026-04-27T04:22:47.614Z" }, - { url = "https://files.pythonhosted.org/packages/29/2e/0e2f71b63bc2e5372575d5c1574b0666d2f90d30da51ed706a32cbf465a0/prek-0.3.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83672d963f249e2f246d3bec97f8fd2e8032e70da0a7d9acb2fa38af76dd82d2", size = 5735277, upload-time = "2026-04-27T04:23:12.437Z" }, - { url = "https://files.pythonhosted.org/packages/09/46/88abf51ac88eeff1ad2fe7d1797ca1fea43eb1ac1ddb8331463ac5b27ed2/prek-0.3.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef70957195d2896a30dd849e64f88344df7bb51af9c950cf16bd11519e7424b0", size = 6622420, upload-time = "2026-04-27T04:23:05.982Z" }, - { url = "https://files.pythonhosted.org/packages/5d/b6/592028a45b084a68b76c7edef909c789d1c96b26761388f63659beef7166/prek-0.3.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f0cc07d2cdb5fe2882015d5fdafc9af98b4c560d4caa1ae948caeab4341b79", size = 6020038, upload-time = "2026-04-27T04:22:54.367Z" }, - { url = "https://files.pythonhosted.org/packages/ca/f7/e97f55a1645a2e9becffeee28892ad8bb66cd144dabfa4392ea8e2674bbe/prek-0.3.11-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:d7554b436dae2ec97f4351a46817e3561657244307d1c0915f355b859f4fab71", size = 5622539, upload-time = "2026-04-27T04:23:01.314Z" }, - { url = "https://files.pythonhosted.org/packages/41/e2/f3119eef6b621782ad216a86d449609858ea34c57cf4a40fc6dc80556d7e/prek-0.3.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:caba5d635a5b64b7ac64d903f29b043ca5b0d9d9693543a0ef331ade89e6ad3f", size = 5440681, upload-time = "2026-04-27T04:23:07.422Z" }, - { url = "https://files.pythonhosted.org/packages/04/62/22dd4f59a47654faeebe74651182ecc48d436542646cc92723052dfd9a45/prek-0.3.11-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:c95a63f19dde48e84b70bd63a235670834af15fa4df8b85d8b7894dd5bc419a9", size = 5314773, upload-time = "2026-04-27T04:22:57.912Z" }, - { url = "https://files.pythonhosted.org/packages/bb/94/a8361462acb8d8f5b8505255b95ffbfc2ee0872a79b4e066eb330692f7be/prek-0.3.11-py3-none-musllinux_1_1_i686.whl", hash = "sha256:7353b45f44a386c676fe96ba72a5ee326b676f789339f405cf6f1d69a1707194", size = 5596208, upload-time = "2026-04-27T04:23:09.08Z" }, - { url = "https://files.pythonhosted.org/packages/04/0c/5f065b86bbeb9977074a055d8a05e90c7201f6c4c7032dada61739b5f8cb/prek-0.3.11-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:39f4e86176ccbb70c098df6abbc8e36c1d86cb81281abe92fb79dcd572418214", size = 6132833, upload-time = "2026-04-27T04:22:56.054Z" }, - { url = "https://files.pythonhosted.org/packages/19/0c/8ab0ae140201dcee505f58b60abbe56bd05ac96b821a6866f6f90c4d971f/prek-0.3.11-py3-none-win32.whl", hash = "sha256:35d2361049653a3dcf27227b7f1b340c5c42a12c0e0361c4b785921bfd125839", size = 5120856, upload-time = "2026-04-27T04:23:02.752Z" }, - { url = "https://files.pythonhosted.org/packages/57/05/9844c1125d3714f6f6c7b475884128a4b0c6c3ee0cd208ead44ca8174687/prek-0.3.11-py3-none-win_amd64.whl", hash = "sha256:a387689cd2e182f92dbb681151ee5a04f494fe97e95d6d783875da90b950e6d5", size = 5510916, upload-time = "2026-04-27T04:22:45.704Z" }, - { url = "https://files.pythonhosted.org/packages/ff/13/24b0288c553dc8d61f44c4d0746fe9bb1e1bd29d1e70571658536e4c0f72/prek-0.3.11-py3-none-win_arm64.whl", hash = "sha256:e4a8f900378a6657c7eb2fc4b12fa5c934edf209d0a24544539842479ec16e0b", size = 5345988, upload-time = "2026-04-27T04:22:50.918Z" }, + { url = "https://files.pythonhosted.org/packages/bc/6a/9baa2bda21dccc2927e952416f6cc23a75eb99c9ed18837164ac2e4a5640/prek-0.3.13-py3-none-linux_armv6l.whl", hash = "sha256:b00d38f01235073c35aa5f48df57fefef45a6cec2ae0884d750345a2c7220370", size = 5506622, upload-time = "2026-05-05T18:06:53.091Z" }, + { url = "https://files.pythonhosted.org/packages/56/77/d44b5d9bdca0879b865f8e47bf84cf5dc9e8b358d029e6d9b83d8809c116/prek-0.3.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0d89ac712c60e34d1550a606ad5fdfb8ad71d44ced8afa2fa5cbc106be4abd9e", size = 5878743, upload-time = "2026-05-05T18:07:23.164Z" }, + { url = "https://files.pythonhosted.org/packages/08/cf/19e8525cde8b3aa12858aca434d1fa653ef3b152da5af11eafc857634dc2/prek-0.3.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f9b5265863d18b5be4ea094fdce4fd6ca61a8c89a70ee3d8ee153b3e0ed6b272", size = 5434909, upload-time = "2026-05-05T18:07:25.276Z" }, + { url = "https://files.pythonhosted.org/packages/7a/9a/e5f97194782de4dab622ce09dafb3ebdd2ee4d354a83ac4def7ebeee236c/prek-0.3.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:64b59a1550780af2bba37297c704b17f81d8e9df6288af1fab4017938e33b1db", size = 5697536, upload-time = "2026-05-05T18:07:05.475Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8c/e1f548ffc4b227e4c2b5a9b30f5978a7e0e6dad51305b97a2ba5b2a923e7/prek-0.3.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ce6cd8f114ba9bbdbe97422103fd886101949b1c42e588a7543c4436ead2020", size = 5428160, upload-time = "2026-05-05T18:07:01.489Z" }, + { url = "https://files.pythonhosted.org/packages/8a/44/abd919b00905a32d21dca2cec32c707860cf217da2431b62dd52684b310e/prek-0.3.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc03e924a24d8d961f56195853c8b206cb196be6db4ad8312125dae847d718ac", size = 5827275, upload-time = "2026-05-05T18:07:17.437Z" }, + { url = "https://files.pythonhosted.org/packages/af/ed/cafd2b80d58a83faf8371c6543bd1475a2224242a3294da7f8582f6aa551/prek-0.3.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ca8c526a23873177fb3b92013500b08ef5f8bedc7263f9f3a44dd2f49645a26", size = 6710293, upload-time = "2026-05-05T18:07:10.663Z" }, + { url = "https://files.pythonhosted.org/packages/35/09/52a4a27596b764173a34d74db09356b30faaacb4a1075b75adbc036a0008/prek-0.3.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5bbb175478438a871e3281d2c3c3f067288af73ad81707a9bdebfd769766c7d", size = 6096556, upload-time = "2026-05-05T18:07:19.46Z" }, + { url = "https://files.pythonhosted.org/packages/63/60/80f61729ce6498815d46d5580cf76da2c157c9b6494046183682441a0ea3/prek-0.3.13-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a65327a014d838341af757dfc05a706d10e8e33f039bc32bb3dbe2fa21c440c0", size = 5693267, upload-time = "2026-05-05T18:07:03.66Z" }, + { url = "https://files.pythonhosted.org/packages/36/9d/c7a663fe70676ffab2e0c6c9a71997a3ccd002ed5bc60b7422a937911af0/prek-0.3.13-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:b6a200843a36a5b0c41764ce7639ccb3471d48b097f1c5e3fc8f034219b42626", size = 5532865, upload-time = "2026-05-05T18:07:15.237Z" }, + { url = "https://files.pythonhosted.org/packages/32/68/506ef5a235536030e16f61e7210474554f6e05f845f27df5877d2dbb1a06/prek-0.3.13-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:bdacaad8f35f343e063d251211fe34db1de9e5cc591795361ad69a6485202258", size = 5395951, upload-time = "2026-05-05T18:06:55.183Z" }, + { url = "https://files.pythonhosted.org/packages/3e/00/22d7c6db7f43b58f7d015913c12660c9bbc82751cff6cfd8c31993cf30eb/prek-0.3.13-py3-none-musllinux_1_1_i686.whl", hash = "sha256:f00328f1c520d8fefb910ab0d3c6764ee330d227952baa19b7e3de7242bd8b3b", size = 5681195, upload-time = "2026-05-05T18:07:12.804Z" }, + { url = "https://files.pythonhosted.org/packages/10/e3/fdf9882238796914ddaf11381a9083b374980156200a953324f6c795f34d/prek-0.3.13-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:e5530a867bcf5b172b7513a64e71b06a337d1d184696227ae953845867376b8d", size = 6212085, upload-time = "2026-05-05T18:07:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/ca/1d/528759931344b5c7103085798f5fa2e86d27d9410b753a6bcbe7726aa8ba/prek-0.3.13-py3-none-win32.whl", hash = "sha256:326fac2bdce00074ce6c5046b861d310638aee2b9de1ed241ba7eb32bdc83898", size = 5199566, upload-time = "2026-05-05T18:07:21.416Z" }, + { url = "https://files.pythonhosted.org/packages/6b/d0/8715ee837c73314a02767d20652cc312d1b6ff6733fa00f52de2b648bc3a/prek-0.3.13-py3-none-win_amd64.whl", hash = "sha256:841049f89f5ec9f4035299283d11e566ac5a068e3742ead1055ea04f886831fc", size = 5589599, upload-time = "2026-05-05T18:06:57.28Z" }, + { url = "https://files.pythonhosted.org/packages/ff/cf/0af0b15be0ebd82f7e50adee149b05a73533d78cb1b97cb889f0647ebffe/prek-0.3.13-py3-none-win_arm64.whl", hash = "sha256:a9fd74e0aec550c6b8d41076fdcdd6ff121cd7d94d743c1338bd794784e3c775", size = 5419029, upload-time = "2026-05-05T18:06:59.645Z" }, ] [[package]] @@ -2303,7 +2342,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.13.3" +version = "2.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -2311,125 +2350,125 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d9/e4/40d09941a2cebcb20609b86a559817d5b9291c49dd6f8c87e5feffbe703a/pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d", size = 844068, upload-time = "2026-04-20T14:46:43.632Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/0a/fd7d723f8f8153418fb40cf9c940e82004fce7e987026b08a68a36dd3fe7/pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927", size = 471981, upload-time = "2026-04-20T14:46:41.402Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, ] [[package]] name = "pydantic-core" -version = "2.46.3" +version = "2.46.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2a/ef/f7abb56c49382a246fd2ce9c799691e3c3e7175ec74b14d99e798bcddb1a/pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c", size = 471412, upload-time = "2026-04-20T14:40:56.672Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/98/b50eb9a411e87483b5c65dba4fa430a06bac4234d3403a40e5a9905ebcd0/pydantic_core-2.46.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1", size = 2108971, upload-time = "2026-04-20T14:43:51.945Z" }, - { url = "https://files.pythonhosted.org/packages/08/4b/f364b9d161718ff2217160a4b5d41ce38de60aed91c3689ebffa1c939d23/pydantic_core-2.46.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f", size = 1949588, upload-time = "2026-04-20T14:44:10.386Z" }, - { url = "https://files.pythonhosted.org/packages/8f/8b/30bd03ee83b2f5e29f5ba8e647ab3c456bf56f2ec72fdbcc0215484a0854/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3", size = 1975986, upload-time = "2026-04-20T14:43:57.106Z" }, - { url = "https://files.pythonhosted.org/packages/3c/54/13ccf954d84ec275d5d023d5786e4aa48840bc9f161f2838dc98e1153518/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a", size = 2055830, upload-time = "2026-04-20T14:44:15.499Z" }, - { url = "https://files.pythonhosted.org/packages/be/0e/65f38125e660fdbd72aa858e7dfae893645cfa0e7b13d333e174a367cd23/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807", size = 2222340, upload-time = "2026-04-20T14:41:51.353Z" }, - { url = "https://files.pythonhosted.org/packages/d1/88/f3ab7739efe0e7e80777dbb84c59eb98518e3f57ea433206194c2e425272/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda", size = 2280727, upload-time = "2026-04-20T14:41:30.461Z" }, - { url = "https://files.pythonhosted.org/packages/2a/6d/c228219080817bec4982f9531cadb18da6aaa770fdeb114f49c237ac2c9f/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57", size = 2092158, upload-time = "2026-04-20T14:44:07.305Z" }, - { url = "https://files.pythonhosted.org/packages/0f/b1/525a16711e7c6d61635fac3b0bd54600b5c5d9f60c6fc5aaab26b64a2297/pydantic_core-2.46.3-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045", size = 2116626, upload-time = "2026-04-20T14:42:34.118Z" }, - { url = "https://files.pythonhosted.org/packages/ef/7c/17d30673351439a6951bf54f564cf2443ab00ae264ec9df00e2efd710eb5/pydantic_core-2.46.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943", size = 2160691, upload-time = "2026-04-20T14:41:14.023Z" }, - { url = "https://files.pythonhosted.org/packages/86/66/af8adbcbc0886ead7f1a116606a534d75a307e71e6e08226000d51b880d2/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f", size = 2182543, upload-time = "2026-04-20T14:40:48.886Z" }, - { url = "https://files.pythonhosted.org/packages/b0/37/6de71e0f54c54a4190010f57deb749e1ddf75c568ada3b1320b70067f121/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4", size = 2324513, upload-time = "2026-04-20T14:42:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/51/b1/9fc74ce94f603d5ef59ff258ca9c2c8fb902fb548d340a96f77f4d1c3b7f/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a", size = 2361853, upload-time = "2026-04-20T14:43:24.886Z" }, - { url = "https://files.pythonhosted.org/packages/40/d0/4c652fc592db35f100279ee751d5a145aca1b9a7984b9684ba7c1b5b0535/pydantic_core-2.46.3-cp310-cp310-win32.whl", hash = "sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7", size = 1980465, upload-time = "2026-04-20T14:44:46.239Z" }, - { url = "https://files.pythonhosted.org/packages/27/b8/a920453c38afbe1f355e1ea0b0d94a0a3e0b0879d32d793108755fa171d5/pydantic_core-2.46.3-cp310-cp310-win_amd64.whl", hash = "sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6", size = 2073884, upload-time = "2026-04-20T14:43:01.201Z" }, - { url = "https://files.pythonhosted.org/packages/22/a2/1ba90a83e85a3f94c796b184f3efde9c72f2830dcda493eea8d59ba78e6d/pydantic_core-2.46.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5", size = 2106740, upload-time = "2026-04-20T14:41:20.932Z" }, - { url = "https://files.pythonhosted.org/packages/b6/f6/99ae893c89a0b9d3daec9f95487aa676709aa83f67643b3f0abaf4ab628a/pydantic_core-2.46.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c", size = 1948293, upload-time = "2026-04-20T14:43:42.115Z" }, - { url = "https://files.pythonhosted.org/packages/3e/b8/2e8e636dc9e3f16c2e16bf0849e24be82c5ee82c603c65fc0326666328fc/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e", size = 1973222, upload-time = "2026-04-20T14:41:57.841Z" }, - { url = "https://files.pythonhosted.org/packages/34/36/0e730beec4d83c5306f417afbd82ff237d9a21e83c5edf675f31ed84c1fe/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287", size = 2053852, upload-time = "2026-04-20T14:40:43.077Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f0/3071131f47e39136a17814576e0fada9168569f7f8c0e6ac4d1ede6a4958/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe", size = 2221134, upload-time = "2026-04-20T14:43:03.349Z" }, - { url = "https://files.pythonhosted.org/packages/2f/a9/a2dc023eec5aa4b02a467874bad32e2446957d2adcab14e107eab502e978/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050", size = 2279785, upload-time = "2026-04-20T14:41:19.285Z" }, - { url = "https://files.pythonhosted.org/packages/0a/44/93f489d16fb63fbd41c670441536541f6e8cfa1e5a69f40bc9c5d30d8c90/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2", size = 2089404, upload-time = "2026-04-20T14:43:10.108Z" }, - { url = "https://files.pythonhosted.org/packages/2a/78/8692e3aa72b2d004f7a5d937f1dfdc8552ba26caf0bec75f342c40f00dec/pydantic_core-2.46.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa", size = 2114898, upload-time = "2026-04-20T14:44:51.475Z" }, - { url = "https://files.pythonhosted.org/packages/6a/62/e83133f2e7832532060175cebf1f13748f4c7e7e7165cdd1f611f174494b/pydantic_core-2.46.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c", size = 2157856, upload-time = "2026-04-20T14:43:46.64Z" }, - { url = "https://files.pythonhosted.org/packages/6d/ec/6a500e3ad7718ee50583fae79c8651f5d37e3abce1fa9ae177ae65842c53/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf", size = 2180168, upload-time = "2026-04-20T14:42:00.302Z" }, - { url = "https://files.pythonhosted.org/packages/d8/53/8267811054b1aa7fc1dc7ded93812372ef79a839f5e23558136a6afbfde1/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b", size = 2322885, upload-time = "2026-04-20T14:41:05.253Z" }, - { url = "https://files.pythonhosted.org/packages/c8/c1/1c0acdb3aa0856ddc4ecc55214578f896f2de16f400cf51627eb3c26c1c4/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e", size = 2360328, upload-time = "2026-04-20T14:41:43.991Z" }, - { url = "https://files.pythonhosted.org/packages/f0/d0/ef39cd0f4a926814f360e71c1adeab48ad214d9727e4deb48eedfb5bce1a/pydantic_core-2.46.3-cp311-cp311-win32.whl", hash = "sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb", size = 1979464, upload-time = "2026-04-20T14:43:12.215Z" }, - { url = "https://files.pythonhosted.org/packages/18/9c/f41951b0d858e343f1cf09398b2a7b3014013799744f2c4a8ad6a3eec4f2/pydantic_core-2.46.3-cp311-cp311-win_amd64.whl", hash = "sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346", size = 2070837, upload-time = "2026-04-20T14:41:47.707Z" }, - { url = "https://files.pythonhosted.org/packages/9f/1e/264a17cd582f6ed50950d4d03dd5fefd84e570e238afe1cb3e25cf238769/pydantic_core-2.46.3-cp311-cp311-win_arm64.whl", hash = "sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6", size = 2053647, upload-time = "2026-04-20T14:42:27.535Z" }, - { url = "https://files.pythonhosted.org/packages/4b/cb/5b47425556ecc1f3fe18ed2a0083188aa46e1dd812b06e406475b3a5d536/pydantic_core-2.46.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67", size = 2101946, upload-time = "2026-04-20T14:40:52.581Z" }, - { url = "https://files.pythonhosted.org/packages/a1/4f/2fb62c2267cae99b815bbf4a7b9283812c88ca3153ef29f7707200f1d4e5/pydantic_core-2.46.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089", size = 1951612, upload-time = "2026-04-20T14:42:42.996Z" }, - { url = "https://files.pythonhosted.org/packages/50/6e/b7348fd30d6556d132cddd5bd79f37f96f2601fe0608afac4f5fb01ec0b3/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0", size = 1977027, upload-time = "2026-04-20T14:42:02.001Z" }, - { url = "https://files.pythonhosted.org/packages/82/11/31d60ee2b45540d3fb0b29302a393dbc01cd771c473f5b5147bcd353e593/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789", size = 2063008, upload-time = "2026-04-20T14:44:17.952Z" }, - { url = "https://files.pythonhosted.org/packages/8a/db/3a9d1957181b59258f44a2300ab0f0be9d1e12d662a4f57bb31250455c52/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d", size = 2233082, upload-time = "2026-04-20T14:40:57.934Z" }, - { url = "https://files.pythonhosted.org/packages/9c/e1/3277c38792aeb5cfb18c2f0c5785a221d9ff4e149abbe1184d53d5f72273/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c", size = 2304615, upload-time = "2026-04-20T14:42:12.584Z" }, - { url = "https://files.pythonhosted.org/packages/5e/d5/e3d9717c9eba10855325650afd2a9cba8e607321697f18953af9d562da2f/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395", size = 2094380, upload-time = "2026-04-20T14:43:05.522Z" }, - { url = "https://files.pythonhosted.org/packages/a1/20/abac35dedcbfd66c6f0b03e4e3564511771d6c9b7ede10a362d03e110d9b/pydantic_core-2.46.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396", size = 2135429, upload-time = "2026-04-20T14:41:55.549Z" }, - { url = "https://files.pythonhosted.org/packages/6c/a5/41bfd1df69afad71b5cf0535055bccc73022715ad362edbc124bc1e021d7/pydantic_core-2.46.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d", size = 2174582, upload-time = "2026-04-20T14:41:45.96Z" }, - { url = "https://files.pythonhosted.org/packages/79/65/38d86ea056b29b2b10734eb23329b7a7672ca604df4f2b6e9c02d4ee22fe/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca", size = 2187533, upload-time = "2026-04-20T14:40:55.367Z" }, - { url = "https://files.pythonhosted.org/packages/b6/55/a1129141678a2026badc539ad1dee0a71d06f54c2f06a4bd68c030ac781b/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976", size = 2332985, upload-time = "2026-04-20T14:44:13.05Z" }, - { url = "https://files.pythonhosted.org/packages/d7/60/cb26f4077719f709e54819f4e8e1d43f4091f94e285eb6bd21e1190a7b7c/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b", size = 2373670, upload-time = "2026-04-20T14:41:53.421Z" }, - { url = "https://files.pythonhosted.org/packages/6b/7e/c3f21882bdf1d8d086876f81b5e296206c69c6082551d776895de7801fa0/pydantic_core-2.46.3-cp312-cp312-win32.whl", hash = "sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4", size = 1966722, upload-time = "2026-04-20T14:44:30.588Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/6b5e757b859013ebfbd7adba02f23b428f37c86dcbf78b5bb0b4ffd36e99/pydantic_core-2.46.3-cp312-cp312-win_amd64.whl", hash = "sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1", size = 2072970, upload-time = "2026-04-20T14:42:54.248Z" }, - { url = "https://files.pythonhosted.org/packages/bf/f8/a989b21cc75e9a32d24192ef700eea606521221a89faa40c919ce884f2b1/pydantic_core-2.46.3-cp312-cp312-win_arm64.whl", hash = "sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72", size = 2035963, upload-time = "2026-04-20T14:44:20.4Z" }, - { url = "https://files.pythonhosted.org/packages/9b/3c/9b5e8eb9821936d065439c3b0fb1490ffa64163bfe7e1595985a47896073/pydantic_core-2.46.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37", size = 2102109, upload-time = "2026-04-20T14:41:24.219Z" }, - { url = "https://files.pythonhosted.org/packages/91/97/1c41d1f5a19f241d8069f1e249853bcce378cdb76eec8ab636d7bc426280/pydantic_core-2.46.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f", size = 1951820, upload-time = "2026-04-20T14:42:14.236Z" }, - { url = "https://files.pythonhosted.org/packages/30/b4/d03a7ae14571bc2b6b3c7b122441154720619afe9a336fa3a95434df5e2f/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8", size = 1977785, upload-time = "2026-04-20T14:42:31.648Z" }, - { url = "https://files.pythonhosted.org/packages/ae/0c/4086f808834b59e3c8f1aa26df8f4b6d998cdcf354a143d18ef41529d1fe/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad", size = 2062761, upload-time = "2026-04-20T14:40:37.093Z" }, - { url = "https://files.pythonhosted.org/packages/fa/71/a649be5a5064c2df0db06e0a512c2281134ed2fcc981f52a657936a7527c/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c", size = 2232989, upload-time = "2026-04-20T14:42:59.254Z" }, - { url = "https://files.pythonhosted.org/packages/a2/84/7756e75763e810b3a710f4724441d1ecc5883b94aacb07ca71c5fb5cfb69/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f", size = 2303975, upload-time = "2026-04-20T14:41:32.287Z" }, - { url = "https://files.pythonhosted.org/packages/6c/35/68a762e0c1e31f35fa0dac733cbd9f5b118042853698de9509c8e5bf128b/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35", size = 2095325, upload-time = "2026-04-20T14:42:47.685Z" }, - { url = "https://files.pythonhosted.org/packages/77/bf/1bf8c9a8e91836c926eae5e3e51dce009bf495a60ca56060689d3df3f340/pydantic_core-2.46.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687", size = 2133368, upload-time = "2026-04-20T14:41:22.766Z" }, - { url = "https://files.pythonhosted.org/packages/e5/50/87d818d6bab915984995157ceb2380f5aac4e563dddbed6b56f0ed057aba/pydantic_core-2.46.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3", size = 2173908, upload-time = "2026-04-20T14:42:52.044Z" }, - { url = "https://files.pythonhosted.org/packages/91/88/a311fb306d0bd6185db41fa14ae888fb81d0baf648a761ae760d30819d33/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022", size = 2186422, upload-time = "2026-04-20T14:43:29.55Z" }, - { url = "https://files.pythonhosted.org/packages/8f/79/28fd0d81508525ab2054fef7c77a638c8b5b0afcbbaeee493cf7c3fef7e1/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23", size = 2332709, upload-time = "2026-04-20T14:42:16.134Z" }, - { url = "https://files.pythonhosted.org/packages/b3/21/795bf5fe5c0f379308b8ef19c50dedab2e7711dbc8d0c2acf08f1c7daa05/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7", size = 2372428, upload-time = "2026-04-20T14:41:10.974Z" }, - { url = "https://files.pythonhosted.org/packages/45/b3/ed14c659cbe7605e3ef063077680a64680aec81eb1a04763a05190d49b7f/pydantic_core-2.46.3-cp313-cp313-win32.whl", hash = "sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13", size = 1965601, upload-time = "2026-04-20T14:41:42.128Z" }, - { url = "https://files.pythonhosted.org/packages/ef/bb/adb70d9a762ddd002d723fbf1bd492244d37da41e3af7b74ad212609027e/pydantic_core-2.46.3-cp313-cp313-win_amd64.whl", hash = "sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0", size = 2071517, upload-time = "2026-04-20T14:43:36.096Z" }, - { url = "https://files.pythonhosted.org/packages/52/eb/66faefabebfe68bd7788339c9c9127231e680b11906368c67ce112fdb47f/pydantic_core-2.46.3-cp313-cp313-win_arm64.whl", hash = "sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec", size = 2035802, upload-time = "2026-04-20T14:43:38.507Z" }, - { url = "https://files.pythonhosted.org/packages/7f/db/a7bcb4940183fda36022cd18ba8dd12f2dff40740ec7b58ce7457befa416/pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b", size = 2097614, upload-time = "2026-04-20T14:44:38.374Z" }, - { url = "https://files.pythonhosted.org/packages/24/35/e4066358a22e3e99519db370494c7528f5a2aa1367370e80e27e20283543/pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018", size = 1951896, upload-time = "2026-04-20T14:40:53.996Z" }, - { url = "https://files.pythonhosted.org/packages/87/92/37cf4049d1636996e4b888c05a501f40a43ff218983a551d57f9d5e14f0d/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34", size = 1979314, upload-time = "2026-04-20T14:41:49.446Z" }, - { url = "https://files.pythonhosted.org/packages/d8/36/9ff4d676dfbdfb2d591cf43f3d90ded01e15b1404fd101180ed2d62a2fd3/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7", size = 2056133, upload-time = "2026-04-20T14:42:23.574Z" }, - { url = "https://files.pythonhosted.org/packages/bc/f0/405b442a4d7ba855b06eec8b2bf9c617d43b8432d099dfdc7bf999293495/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2", size = 2228726, upload-time = "2026-04-20T14:44:22.816Z" }, - { url = "https://files.pythonhosted.org/packages/e7/f8/65cd92dd5a0bd89ba277a98ecbfaf6fc36bbd3300973c7a4b826d6ab1391/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba", size = 2301214, upload-time = "2026-04-20T14:44:48.792Z" }, - { url = "https://files.pythonhosted.org/packages/fd/86/ef96a4c6e79e7a2d0410826a68fbc0eccc0fd44aa733be199d5fcac3bb87/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f", size = 2099927, upload-time = "2026-04-20T14:41:40.196Z" }, - { url = "https://files.pythonhosted.org/packages/6d/53/269caf30e0096e0a8a8f929d1982a27b3879872cca2d917d17c2f9fdf4fe/pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22", size = 2128789, upload-time = "2026-04-20T14:41:15.868Z" }, - { url = "https://files.pythonhosted.org/packages/00/b0/1a6d9b6a587e118482910c244a1c5acf4d192604174132efd12bf0ac486f/pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f", size = 2173815, upload-time = "2026-04-20T14:44:25.152Z" }, - { url = "https://files.pythonhosted.org/packages/87/56/e7e00d4041a7e62b5a40815590114db3b535bf3ca0bf4dca9f16cef25246/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127", size = 2181608, upload-time = "2026-04-20T14:41:28.933Z" }, - { url = "https://files.pythonhosted.org/packages/e8/22/4bd23c3d41f7c185d60808a1de83c76cf5aeabf792f6c636a55c3b1ec7f9/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c", size = 2326968, upload-time = "2026-04-20T14:42:03.962Z" }, - { url = "https://files.pythonhosted.org/packages/24/ac/66cd45129e3915e5ade3b292cb3bc7fd537f58f8f8dbdaba6170f7cabb74/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1", size = 2369842, upload-time = "2026-04-20T14:41:35.52Z" }, - { url = "https://files.pythonhosted.org/packages/a2/51/dd4248abb84113615473aa20d5545b7c4cd73c8644003b5259686f93996c/pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505", size = 1959661, upload-time = "2026-04-20T14:41:00.042Z" }, - { url = "https://files.pythonhosted.org/packages/20/eb/59980e5f1ae54a3b86372bd9f0fa373ea2d402e8cdcd3459334430f91e91/pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e", size = 2071686, upload-time = "2026-04-20T14:43:16.471Z" }, - { url = "https://files.pythonhosted.org/packages/8c/db/1cf77e5247047dfee34bc01fa9bca134854f528c8eb053e144298893d370/pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df", size = 2026907, upload-time = "2026-04-20T14:43:31.732Z" }, - { url = "https://files.pythonhosted.org/packages/57/c0/b3df9f6a543276eadba0a48487b082ca1f201745329d97dbfa287034a230/pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf", size = 2095047, upload-time = "2026-04-20T14:42:37.982Z" }, - { url = "https://files.pythonhosted.org/packages/66/57/886a938073b97556c168fd99e1a7305bb363cd30a6d2c76086bf0587b32a/pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee", size = 1934329, upload-time = "2026-04-20T14:43:49.655Z" }, - { url = "https://files.pythonhosted.org/packages/0b/7c/b42eaa5c34b13b07ecb51da21761297a9b8eb43044c864a035999998f328/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a", size = 1974847, upload-time = "2026-04-20T14:42:10.737Z" }, - { url = "https://files.pythonhosted.org/packages/e6/9b/92b42db6543e7de4f99ae977101a2967b63122d4b6cf7773812da2d7d5b5/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c", size = 2041742, upload-time = "2026-04-20T14:40:44.262Z" }, - { url = "https://files.pythonhosted.org/packages/0f/19/46fbe1efabb5aa2834b43b9454e70f9a83ad9c338c1291e48bdc4fecf167/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1", size = 2236235, upload-time = "2026-04-20T14:41:27.307Z" }, - { url = "https://files.pythonhosted.org/packages/77/da/b3f95bc009ad60ec53120f5d16c6faa8cabdbe8a20d83849a1f2b8728148/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64", size = 2282633, upload-time = "2026-04-20T14:44:33.271Z" }, - { url = "https://files.pythonhosted.org/packages/cc/6e/401336117722e28f32fb8220df676769d28ebdf08f2f4469646d404c43a3/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb", size = 2109679, upload-time = "2026-04-20T14:44:41.065Z" }, - { url = "https://files.pythonhosted.org/packages/fc/53/b289f9bc8756a32fe718c46f55afaeaf8d489ee18d1a1e7be1db73f42cc4/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6", size = 2108342, upload-time = "2026-04-20T14:42:50.144Z" }, - { url = "https://files.pythonhosted.org/packages/10/5b/8292fc7c1f9111f1b2b7c1b0dcf1179edcd014fc3ea4517499f50b829d71/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c", size = 2157208, upload-time = "2026-04-20T14:42:08.133Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9e/f80044e9ec07580f057a89fc131f78dda7a58751ddf52bbe05eaf31db50f/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47", size = 2167237, upload-time = "2026-04-20T14:42:25.412Z" }, - { url = "https://files.pythonhosted.org/packages/f8/84/6781a1b037f3b96be9227edbd1101f6d3946746056231bf4ac48cdff1a8d/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab", size = 2312540, upload-time = "2026-04-20T14:40:40.313Z" }, - { url = "https://files.pythonhosted.org/packages/3e/db/19c0839feeb728e7df03255581f198dfdf1c2aeb1e174a8420b63c5252e5/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba", size = 2369556, upload-time = "2026-04-20T14:41:09.427Z" }, - { url = "https://files.pythonhosted.org/packages/e0/15/3228774cb7cd45f5f721ddf1b2242747f4eb834d0c491f0c02d606f09fed/pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56", size = 1949756, upload-time = "2026-04-20T14:41:25.717Z" }, - { url = "https://files.pythonhosted.org/packages/b8/2a/c79cf53fd91e5a87e30d481809f52f9a60dd221e39de66455cf04deaad37/pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8", size = 2051305, upload-time = "2026-04-20T14:43:18.627Z" }, - { url = "https://files.pythonhosted.org/packages/0b/db/d8182a7f1d9343a032265aae186eb063fe26ca4c40f256b21e8da4498e89/pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374", size = 2026310, upload-time = "2026-04-20T14:41:01.778Z" }, - { url = "https://files.pythonhosted.org/packages/66/7f/03dbad45cd3aa9083fbc93c210ae8b005af67e4136a14186950a747c6874/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46", size = 2105683, upload-time = "2026-04-20T14:42:19.779Z" }, - { url = "https://files.pythonhosted.org/packages/26/22/4dc186ac8ea6b257e9855031f51b62a9637beac4d68ac06bee02f046f836/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874", size = 1940052, upload-time = "2026-04-20T14:43:59.274Z" }, - { url = "https://files.pythonhosted.org/packages/0d/ca/d376391a5aff1f2e8188960d7873543608130a870961c2b6b5236627c116/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76", size = 1988172, upload-time = "2026-04-20T14:41:17.469Z" }, - { url = "https://files.pythonhosted.org/packages/0e/6b/523b9f85c23788755d6ab949329de692a2e3a584bc6beb67fef5e035aa9d/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531", size = 2128596, upload-time = "2026-04-20T14:40:41.707Z" }, - { url = "https://files.pythonhosted.org/packages/34/42/f426db557e8ab2791bc7562052299944a118655496fbff99914e564c0a94/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803", size = 2091877, upload-time = "2026-04-20T14:43:27.091Z" }, - { url = "https://files.pythonhosted.org/packages/5c/4f/86a832a9d14df58e663bfdf4627dc00d3317c2bd583c4fb23390b0f04b8e/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3", size = 1932428, upload-time = "2026-04-20T14:40:45.781Z" }, - { url = "https://files.pythonhosted.org/packages/11/1a/fe857968954d93fb78e0d4b6df5c988c74c4aaa67181c60be7cfe327c0ca/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5", size = 1997550, upload-time = "2026-04-20T14:44:02.425Z" }, - { url = "https://files.pythonhosted.org/packages/17/eb/9d89ad2d9b0ba8cd65393d434471621b98912abb10fbe1df08e480ba57b5/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4", size = 2137657, upload-time = "2026-04-20T14:42:45.149Z" }, - { url = "https://files.pythonhosted.org/packages/1f/da/99d40830684f81dec901cac521b5b91c095394cc1084b9433393cde1c2df/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25", size = 2107973, upload-time = "2026-04-20T14:42:06.175Z" }, - { url = "https://files.pythonhosted.org/packages/99/a5/87024121818d75bbb2a98ddbaf638e40e7a18b5e0f5492c9ca4b1b316107/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3", size = 1947191, upload-time = "2026-04-20T14:43:14.319Z" }, - { url = "https://files.pythonhosted.org/packages/60/62/0c1acfe10945b83a6a59d19fbaa92f48825381509e5701b855c08f13db76/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536", size = 2123791, upload-time = "2026-04-20T14:43:22.766Z" }, - { url = "https://files.pythonhosted.org/packages/75/3e/3b2393b4c8f44285561dc30b00cf307a56a2eff7c483a824db3b8221ca51/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1", size = 2153197, upload-time = "2026-04-20T14:44:27.932Z" }, - { url = "https://files.pythonhosted.org/packages/ba/75/5af02fb35505051eee727c061f2881c555ab4f8ddb2d42da715a42c9731b/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c", size = 2181073, upload-time = "2026-04-20T14:43:20.729Z" }, - { url = "https://files.pythonhosted.org/packages/10/92/7e0e1bd9ca3c68305db037560ca2876f89b2647deb2f8b6319005de37505/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85", size = 2315886, upload-time = "2026-04-20T14:44:04.826Z" }, - { url = "https://files.pythonhosted.org/packages/b8/d8/101655f27eaf3e44558ead736b2795d12500598beed4683f279396fa186e/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8", size = 2360528, upload-time = "2026-04-20T14:40:47.431Z" }, - { url = "https://files.pythonhosted.org/packages/07/0f/1c34a74c8d07136f0d729ffe5e1fdab04fbdaa7684f61a92f92511a84a15/pydantic_core-2.46.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff", size = 2184144, upload-time = "2026-04-20T14:42:57Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/08/f1ba952f1c8ae5581c70fa9c6da89f247b83e3dd8c09c035d5d7931fc23d/pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4", size = 2113146, upload-time = "2026-05-06T13:37:36.537Z" }, + { url = "https://files.pythonhosted.org/packages/56/c6/65f646c7ff09bd257f660434adb45c4dfcbbcebcc030562fecf6f5bf887d/pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5", size = 1949769, upload-time = "2026-05-06T13:37:46.365Z" }, + { url = "https://files.pythonhosted.org/packages/64/ba/bfb1d928fd5b49e1258935ff104ae356e9fd89384a55bf9f847e9193ad40/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba", size = 1974958, upload-time = "2026-05-06T13:37:28.611Z" }, + { url = "https://files.pythonhosted.org/packages/4e/74/76223bfb117b64af743c9b6670d1364516f5c0604f96b48f3272f6af6cc6/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b", size = 2042118, upload-time = "2026-05-06T13:36:55.216Z" }, + { url = "https://files.pythonhosted.org/packages/cb/7b/848732968bc8f48f3187542f08358b9d842db564147b256669426ebb1652/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c", size = 2222876, upload-time = "2026-05-06T13:38:25.455Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/e90b63ee2e14bd8d3db8f705a6d75d64e6ee1b7c2c8833747ce706e1e0ce/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50", size = 2286703, upload-time = "2026-05-06T13:37:53.304Z" }, + { url = "https://files.pythonhosted.org/packages/ba/1e/acc4d70f88a0a277e4a1fa77ebb985ceabaf900430f875bf9338e11c9420/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd", size = 2092042, upload-time = "2026-05-06T13:38:46.981Z" }, + { url = "https://files.pythonhosted.org/packages/a9/da/0a422b57bf8504102bf3c4ccea9c41bab5a5cee6a54650acf8faf67f5a24/pydantic_core-2.46.4-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01", size = 2117231, upload-time = "2026-05-06T13:39:23.146Z" }, + { url = "https://files.pythonhosted.org/packages/bd/2a/2ac13c3af305843e23c5078c53d135656b3f05a2fd78cb7bbbb12e97b473/pydantic_core-2.46.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d", size = 2168388, upload-time = "2026-05-06T13:40:08.06Z" }, + { url = "https://files.pythonhosted.org/packages/72/04/2beacf7e1607e93eefe4aed1b4709f079b905fb77530179d4f7c71745f22/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4", size = 2184769, upload-time = "2026-05-06T13:38:13.901Z" }, + { url = "https://files.pythonhosted.org/packages/9e/29/d2b9fd9f539133548eaf622c06a4ce176cb46ac59f32d0359c4abc0de047/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f", size = 2319312, upload-time = "2026-05-06T13:39:08.24Z" }, + { url = "https://files.pythonhosted.org/packages/7c/af/0f7a5b85fec6075bea96e3ef9187de38fccced0de92c1e7feda8d5cc7bb9/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39", size = 2361817, upload-time = "2026-05-06T13:38:43.2Z" }, + { url = "https://files.pythonhosted.org/packages/25/a4/73363fec545fd3ec025490bdda2743c56d0dd5b6266b1a53bbe9e4265375/pydantic_core-2.46.4-cp310-cp310-win32.whl", hash = "sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d", size = 1987085, upload-time = "2026-05-06T13:39:25.497Z" }, + { url = "https://files.pythonhosted.org/packages/01/aa/62f082da2c91fac1c234bc9ee0066257ce83f0604abd72e4c9d5991f2d84/pydantic_core-2.46.4-cp310-cp310-win_amd64.whl", hash = "sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf", size = 2074311, upload-time = "2026-05-06T13:39:59.922Z" }, + { url = "https://files.pythonhosted.org/packages/5c/fa/6d7708d2cfc1a832acb6aeb0cd16e801902df8a0f583bb3b4b527fde022e/pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594", size = 2111872, upload-time = "2026-05-06T13:40:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6f/aa064a3e74b5745afbdf250594f38e7ead05e2d651bcb35994b9417a0d4d/pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c", size = 1948255, upload-time = "2026-05-06T13:39:12.574Z" }, + { url = "https://files.pythonhosted.org/packages/43/3a/41114a9f7569b84b4d84e7a018c57c56347dac30c0d4a872946ec4e36c46/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826", size = 1972827, upload-time = "2026-05-06T13:38:19.841Z" }, + { url = "https://files.pythonhosted.org/packages/ef/25/1ab42e8048fe551934d9884e8d64daa7e990ad386f310a15981aeb6a5b08/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04", size = 2041051, upload-time = "2026-05-06T13:38:10.447Z" }, + { url = "https://files.pythonhosted.org/packages/94/c2/1a934597ddf08da410385b3b7aae91956a5a76c635effef456074fad7e88/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e", size = 2221314, upload-time = "2026-05-06T13:40:13.089Z" }, + { url = "https://files.pythonhosted.org/packages/02/6d/9e8ad178c9c4df27ad3c8f25d1fe2a7ab0d2ba0559fad4aee5d3d1f16771/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3", size = 2285146, upload-time = "2026-05-06T13:38:59.224Z" }, + { url = "https://files.pythonhosted.org/packages/80/50/540cd3aeefc041beb111125c4bff779831a2111fc6b15a9138cda277d32c/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4", size = 2089685, upload-time = "2026-05-06T13:38:17.762Z" }, + { url = "https://files.pythonhosted.org/packages/6b/a4/b440ad35f05f6a38f89fa0f149accb3f0e02be94ca5e15f3c449a61b4bc9/pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398", size = 2115420, upload-time = "2026-05-06T13:37:58.195Z" }, + { url = "https://files.pythonhosted.org/packages/99/61/de4f55db8dfd57bfdfa9a12ec90fe1b57c4f41062f7ca86f08586b3e0ac0/pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3", size = 2165122, upload-time = "2026-05-06T13:37:01.167Z" }, + { url = "https://files.pythonhosted.org/packages/f7/52/7c529d7bdb2d1068bd52f51fe32572c8301f9a4febf1948f10639f1436f5/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848", size = 2182573, upload-time = "2026-05-06T13:38:45.04Z" }, + { url = "https://files.pythonhosted.org/packages/37/b3/7c40325848ba78247f2812dcf9c7274e38cd801820ca6dd9fe63bcfb0eb4/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3", size = 2317139, upload-time = "2026-05-06T13:37:15.539Z" }, + { url = "https://files.pythonhosted.org/packages/d9/37/f913f81a657c865b75da6c0dbed79876073c2a43b5bd9edbe8da785e4d49/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109", size = 2360433, upload-time = "2026-05-06T13:37:30.099Z" }, + { url = "https://files.pythonhosted.org/packages/c4/67/6acaa1be2567f9256b056d8477158cac7240813956ce86e49deae8e173b4/pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda", size = 1985513, upload-time = "2026-05-06T13:38:15.669Z" }, + { url = "https://files.pythonhosted.org/packages/aa/e6/c505f83dfeda9a2e5c995cfd872949e4d05e12f7feb3dca72f633daefa94/pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33", size = 2071114, upload-time = "2026-05-06T13:40:35.416Z" }, + { url = "https://files.pythonhosted.org/packages/0f/da/7a263a96d965d9d0df5e8de8a475f33495451117035b09acb110288c381f/pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d", size = 2044298, upload-time = "2026-05-06T13:38:29.754Z" }, + { url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" }, + { url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" }, + { url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" }, + { url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" }, + { url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" }, + { url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" }, + { url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" }, + { url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" }, + { url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" }, + { url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" }, + { url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" }, + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, + { url = "https://files.pythonhosted.org/packages/ee/a4/73995fd4ebbb46ba0ee51e6fa049b8f02c40daebb762208feda8a6b7894d/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c", size = 2111589, upload-time = "2026-05-06T13:37:10.817Z" }, + { url = "https://files.pythonhosted.org/packages/fb/7f/f37d3a5e8bfcc2e403f5c57a730f2d815693fb42119e8ea48b3789335af1/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b", size = 1944552, upload-time = "2026-05-06T13:36:56.717Z" }, + { url = "https://files.pythonhosted.org/packages/15/3c/d7eb777b3ff43e8433a4efb39a17aa8fd98a4ee8561a24a67ef5db07b2d6/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b", size = 1982984, upload-time = "2026-05-06T13:39:06.207Z" }, + { url = "https://files.pythonhosted.org/packages/63/87/70b9f40170a81afd55ca26c9b2acb25c20d64bcfbf888fafecb3ba077d4c/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea", size = 2138417, upload-time = "2026-05-06T13:39:45.476Z" }, + { url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" }, + { url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" }, + { url = "https://files.pythonhosted.org/packages/11/cb/428de0385b6c8d44b716feba566abfacfbd23ee3c4439faa789a1456242f/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0", size = 2112782, upload-time = "2026-05-06T13:37:04.016Z" }, + { url = "https://files.pythonhosted.org/packages/0b/b5/6a17bdadd0fc1f170adfd05a20d37c832f52b117b4d9131da1f41bb097ce/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7", size = 1952146, upload-time = "2026-05-06T13:39:43.092Z" }, + { url = "https://files.pythonhosted.org/packages/2a/dc/03734d80e362cd43ef65428e9de77c730ce7f2f11c60d2b1e1b39f0fbf99/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2", size = 2134492, upload-time = "2026-05-06T13:36:58.124Z" }, + { url = "https://files.pythonhosted.org/packages/de/df/5e5ffc085ed07cc22d298134d3d911c63e91f6a0eb91fe646750a3209910/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9", size = 2156604, upload-time = "2026-05-06T13:37:49.88Z" }, + { url = "https://files.pythonhosted.org/packages/81/44/6e112a4253e56f5705467cbab7ab5e91ee7398ba3d56d358635958893d3e/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf", size = 2183828, upload-time = "2026-05-06T13:37:43.053Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ad/5565071e937d8e752842ac241463944c9eb14c87e2d269f2658a5bd05e98/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30", size = 2310000, upload-time = "2026-05-06T13:37:56.694Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c3/66883a5cec183e7fba4d024b4cbbe61851a63750ef606b0afecc46d1f2bf/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc", size = 2361286, upload-time = "2026-05-06T13:40:05.667Z" }, + { url = "https://files.pythonhosted.org/packages/4b/2d/69abac8f838090bbecd5df894befb2c2619e7996a98ddb949db9f3b93225/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983", size = 2193071, upload-time = "2026-05-06T13:38:08.682Z" }, ] [[package]] @@ -2647,11 +2686,11 @@ wheels = [ [[package]] name = "pytz" -version = "2026.1.post1" +version = "2026.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/56/db/b8721d71d945e6a8ac63c0fc900b2067181dbb50805958d4d4661cf7d277/pytz-2026.1.post1.tar.gz", hash = "sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1", size = 321088, upload-time = "2026-03-03T07:47:50.683Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a", size = 320861, upload-time = "2026-05-04T01:35:29.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl", hash = "sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a", size = 510489, upload-time = "2026-03-03T07:47:49.167Z" }, + { url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141, upload-time = "2026-05-04T01:35:27.408Z" }, ] [[package]] @@ -2846,7 +2885,7 @@ version = "15.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } @@ -3301,7 +3340,7 @@ version = "8.2.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version >= '3.11'" }, { name = "mdit-py-plugins" }, { name = "platformdirs" }, { name = "pygments" }, @@ -3427,7 +3466,7 @@ wheels = [ [[package]] name = "typer" -version = "0.25.0" +version = "0.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, @@ -3435,9 +3474,9 @@ dependencies = [ { name = "rich" }, { name = "shellingham" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7b/27/ede8cec7596e0041ba7e7b80b47d132562f56ff454313a16f6084e555c9f/typer-0.25.0.tar.gz", hash = "sha256:123eaf9f19bb40fd268310e12a542c0c6b4fab9c98d9d23342a01ff95e3ce930", size = 120150, upload-time = "2026-04-26T08:46:14.767Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/51/9aed62104cea109b820bbd6c14245af756112017d309da813ef107d42e7e/typer-0.25.1.tar.gz", hash = "sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc", size = 122276, upload-time = "2026-04-30T19:32:16.964Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/72/193d4e586ec5a4db834a36bbeb47641a62f951f114ffd0fe5b1b46e8d56f/typer-0.25.0-py3-none-any.whl", hash = "sha256:ac01b48823d3db9a83c9e164338057eadbb1c9957a2a6b4eeb486669c560b5dc", size = 55993, upload-time = "2026-04-26T08:46:15.889Z" }, + { url = "https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl", hash = "sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89", size = 58409, upload-time = "2026-04-30T19:32:18.271Z" }, ] [[package]] @@ -3472,14 +3511,14 @@ wheels = [ [[package]] name = "types-requests" -version = "2.33.0.20260408" +version = "2.33.0.20260503" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/69/6a/749dc53a54a3f35842c1f8197b3ca6b54af6d7458a1bfc75f6629b6da666/types_requests-2.33.0.20260408.tar.gz", hash = "sha256:95b9a86376807a216b2fb412b47617b202091c3ea7c078f47cc358d5528ccb7b", size = 23882, upload-time = "2026-04-08T04:34:49.33Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/b8/57e94268c0d82ac3eaa2fc35aa8ca7bbc2542f726b67dcf90b0b00a3b14d/types_requests-2.33.0.20260503.tar.gz", hash = "sha256:9721b2d9dbee7131f2fb39f20f0ebb1999c18cef4b512c9a7932f3722de7c5f4", size = 23931, upload-time = "2026-05-03T05:20:08.882Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/b8/78fd6c037de4788c040fdd323b3369804400351b7827473920f6c1d03c10/types_requests-2.33.0.20260408-py3-none-any.whl", hash = "sha256:81f31d5ea4acb39f03be7bc8bed569ba6d5a9c5d97e89f45ac43d819b68ca50f", size = 20739, upload-time = "2026-04-08T04:34:48.325Z" }, + { url = "https://files.pythonhosted.org/packages/c3/82/959113a6351f3ca046cd0a8cd2cee071d7ea47473560557a01eeae9a6fe2/types_requests-2.33.0.20260503-py3-none-any.whl", hash = "sha256:02aaa7e3577a13471715bb1bddb693cc985ea514f754b503bf033e6a09a3e528", size = 20736, upload-time = "2026-05-03T05:20:07.858Z" }, ] [[package]] @@ -3562,11 +3601,11 @@ wheels = [ [[package]] name = "wcwidth" -version = "0.6.0" +version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684, upload-time = "2026-02-06T19:19:40.919Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/ee/afaf0f85a9a18fe47a67f1e4422ed6cf1fe642f0ae0a2f81166231303c52/wcwidth-0.7.0.tar.gz", hash = "sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0", size = 182132, upload-time = "2026-05-02T16:04:12.653Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189, upload-time = "2026-02-06T19:19:39.646Z" }, + { url = "https://files.pythonhosted.org/packages/41/52/e465037f5375f43533d1a80b6923955201596a99142ed524d77b571a1418/wcwidth-0.7.0-py3-none-any.whl", hash = "sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2", size = 110825, upload-time = "2026-05-02T16:04:11.033Z" }, ] [[package]] From b6af91ab271c5e16d2d93724bf5ebfb1387576ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Fri, 8 May 2026 16:32:25 +0200 Subject: [PATCH 030/135] container configs: use correct key for conda configs (#4269) Co-authored-by: nf-core-bot --- CHANGELOG.md | 1 + nf_core/pipelines/containers_utils.py | 3 ++- tests/pipelines/test_container_configs.py | 6 ++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a49056c70..56398753fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### General - Update pre-commit hook pre-commit/mirrors-mypy to v2 ([#4270](https://github.com/nf-core/tools/pull/4270)) +- container configs: use correct key for conda configs ([#4269](https://github.com/nf-core/tools/pull/4269)) ### Linting diff --git a/nf_core/pipelines/containers_utils.py b/nf_core/pipelines/containers_utils.py index 2ab297b091..a3a5751ef3 100644 --- a/nf_core/pipelines/containers_utils.py +++ b/nf_core/pipelines/containers_utils.py @@ -184,8 +184,9 @@ def generate_container_configs( for platform, module_containers in containers.items(): if not module_containers: continue + container_key = "conda" if platform.startswith("conda_lock_") else "container" lines = [ - f"process {{ withName: '{module_name}' {{ container = '{container}' }} }}\n" + f"process {{ withName: '{module_name}' {{ {container_key} = '{container}' }} }}\n" for module_name, container in sorted(module_containers.items()) ] config_path = self.workflow_directory / "conf" / f"containers_{platform}.config" diff --git a/tests/pipelines/test_container_configs.py b/tests/pipelines/test_container_configs.py index e90b39a021..c7f5067afa 100644 --- a/tests/pipelines/test_container_configs.py +++ b/tests/pipelines/test_container_configs.py @@ -67,7 +67,8 @@ def test_generate_all_container_configs(self) -> None: with cfg_path.open("r") as fh: content = fh.readlines() value = fastqc_meta_yml["containers"][runtime][arch][protocol] - assert f"process {{ withName: 'FASTQC' {{ container = '{value}' }} }}\n" in content + key = "conda" if p_name.startswith("conda_lock_") else "container" + assert f"process {{ withName: 'FASTQC' {{ {key} = '{value}' }} }}\n" in content def test_generate_container_configs_new_module_injected(self) -> None: """new_module_name/path are used when nextflow inspect doesn't yet know about the module.""" @@ -96,7 +97,8 @@ def test_generate_container_configs_new_module_injected(self) -> None: cfg_path = conf_dir / f"containers_{p_name}.config" assert cfg_path.exists() value = fastqc_meta_yml["containers"][runtime][arch][protocol] - assert f"process {{ withName: 'FASTQC' {{ container = '{value}' }} }}\n" in cfg_path.read_text() + key = "conda" if p_name.startswith("conda_lock_") else "container" + assert f"process {{ withName: 'FASTQC' {{ {key} = '{value}' }} }}\n" in cfg_path.read_text() def test_generate_container_configs_removes_stale_entries(self) -> None: """Stale config files are deleted when all their modules have been removed.""" From 2bead682d7434117e3cba88d2fd7faf208e53808 Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Mon, 11 May 2026 12:57:52 +0100 Subject: [PATCH 031/135] feat(install/update): add --only flag for single-target operations Today there is no working invocation of `nf-core modules/subworkflows install` or `update` that touches only the named component. - `install --force ` always walks the include graph and re-pins every reachable component at the cached-repo HEAD, producing a wide modules.json diff for what the user asked to be a focused change. - `update ` (no flags) cascades silently when run non-interactively (`no_prompts` flips `recursive_update=True`), and prompts per-component interactively. The only way to get single-target behaviour is to answer "no" to each prompt by hand. This makes it hard to ship a focused, reviewable dep bump as a standalone PR: maintainers who want to update one subworkflow currently have to hand-edit modules.json or accept a sprawling unrelated diff. Add `--only` to `install` and `update` for both modules and subworkflows. When set: - `install`: skip `install_included_components` so transitive deps are not re-fetched or pinned. - `update`: force `recursive_update=False`, regardless of `--update-deps` or `no_prompts`. Mutually exclusive with `--update-deps`; raises a clear UserWarning if both are set. Measured against nf-core/rnaseq pr-1680 (`subworkflows install --force bam_dedup_umi`): Default: 22 files modified, 25 git_sha lines in modules.json diff. --only: 10 files modified, 2 git_sha lines (single SHA bump). The remaining ~9 untracked files under `--only` are container-config side effects (`conf/containers_*.config` plus `nextflow inspect`'s conda-lock cache), not module/subworkflow content. Tests: - subworkflows install --only: named subworkflow installed, transitive module dep (samtools/index) is *not* on disk. - subworkflows update --only: named subworkflow's SHA changes, transitive dep (samtools/flagstat) SHA stays pinned. - --only with --update-deps: UserWarning ("mutually exclusive"). Co-Authored-By: Claude Opus 4.7 (1M context) --- nf_core/__main__.py | 51 ++++++++++++++++++++++++++---- nf_core/commands_modules.py | 5 ++- nf_core/commands_subworkflows.py | 5 ++- nf_core/components/install.py | 4 ++- nf_core/components/update.py | 10 +++++- nf_core/modules/install.py | 2 ++ nf_core/modules/update.py | 2 ++ nf_core/subworkflows/install.py | 2 ++ nf_core/subworkflows/update.py | 2 ++ tests/subworkflows/test_install.py | 9 ++++++ tests/subworkflows/test_update.py | 33 +++++++++++++++++++ 11 files changed, 115 insertions(+), 10 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index f115bf2bfa..9abf103de7 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -993,11 +993,17 @@ def command_modules_list_local(ctx, keywords, json, directory): # pylint: disab help="Force reinstallation of module if it already exists", ) @click.option("-s", "--sha", type=str, metavar="", help="Install module at commit SHA") -def command_modules_install(ctx, tool, directory, prompt, force, sha): +@click.option( + "--only", + is_flag=True, + default=False, + help="Restrict the install to the named component; do not recurse into included modules/subworkflows.", +) +def command_modules_install(ctx, tool, directory, prompt, force, sha, only): """ Install DSL2 modules within a pipeline. """ - modules_install(ctx, tool, directory, prompt, force, sha) + modules_install(ctx, tool, directory, prompt, force, sha, only) # nf-core modules update @@ -1065,6 +1071,12 @@ def command_modules_install(ctx, tool, directory, prompt, force, sha): default=False, help="Automatically update all linked modules and subworkflows without asking for confirmation", ) +@click.option( + "--only", + is_flag=True, + default=False, + help="Restrict the update to the named module; do not touch transitively linked components. Mutually exclusive with --update-deps.", +) def command_modules_update( ctx, tool, @@ -1077,11 +1089,14 @@ def command_modules_update( save_diff, update_deps, limit_output, + only, ): """ Update DSL2 modules within a pipeline. """ - modules_update(ctx, tool, directory, force, prompt, sha, install_all, preview, save_diff, update_deps, limit_output) + modules_update( + ctx, tool, directory, force, prompt, sha, install_all, preview, save_diff, update_deps, limit_output, only + ) # nf-core modules patch @@ -1725,11 +1740,17 @@ def command_subworkflows_info(ctx, subworkflow, directory): metavar="", help="Install subworkflow at commit SHA", ) -def command_subworkflows_install(ctx, subworkflow, directory, prompt, force, sha): +@click.option( + "--only", + is_flag=True, + default=False, + help="Restrict the install to the named subworkflow; do not recurse into included modules/subworkflows.", +) +def command_subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, only): """ Install DSL2 subworkflow within a pipeline. """ - subworkflows_install(ctx, subworkflow, directory, prompt, force, sha) + subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, only) # nf-core subworkflows patch @@ -1882,6 +1903,12 @@ def command_subworkflows_remove(ctx, directory, subworkflow, force): default=False, help="Automatically update all linked modules and subworkflows without asking for confirmation", ) +@click.option( + "--only", + is_flag=True, + default=False, + help="Restrict the update to the named subworkflow; do not touch transitively linked components. Mutually exclusive with --update-deps.", +) def command_subworkflows_update( ctx, subworkflow, @@ -1894,12 +1921,24 @@ def command_subworkflows_update( save_diff, update_deps, limit_output, + only, ): """ Update DSL2 subworkflow within a pipeline. """ subworkflows_update( - ctx, subworkflow, directory, force, prompt, sha, install_all, preview, save_diff, update_deps, limit_output + ctx, + subworkflow, + directory, + force, + prompt, + sha, + install_all, + preview, + save_diff, + update_deps, + limit_output, + only, ) diff --git a/nf_core/commands_modules.py b/nf_core/commands_modules.py index 7f5b991745..f3c9630c80 100644 --- a/nf_core/commands_modules.py +++ b/nf_core/commands_modules.py @@ -49,7 +49,7 @@ def modules_list_local(ctx, keywords, json, directory): # pylint: disable=redef sys.exit(1) -def modules_install(ctx, tool, directory, prompt, force, sha): +def modules_install(ctx, tool, directory, prompt, force, sha, only=False): """ Install DSL2 modules within a pipeline. @@ -66,6 +66,7 @@ def modules_install(ctx, tool, directory, prompt, force, sha): ctx.obj["modules_repo_url"], ctx.obj["modules_repo_branch"], ctx.obj["modules_repo_no_pull"], + only=only, ) exit_status = module_install.install(tool) if not exit_status: @@ -87,6 +88,7 @@ def modules_update( save_diff, update_deps, limit_output, + only, ): """ Update DSL2 modules within a pipeline. @@ -109,6 +111,7 @@ def modules_update( ctx.obj["modules_repo_branch"], ctx.obj["modules_repo_no_pull"], limit_output, + only, ) exit_status = module_install.update(tool) if not exit_status and install_all: diff --git a/nf_core/commands_subworkflows.py b/nf_core/commands_subworkflows.py index 193e976401..0cf441458e 100644 --- a/nf_core/commands_subworkflows.py +++ b/nf_core/commands_subworkflows.py @@ -177,7 +177,7 @@ def subworkflows_info(ctx, subworkflow, directory): sys.exit(1) -def subworkflows_install(ctx, subworkflow, directory, prompt, force, sha): +def subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, only=False): """ Install DSL2 subworkflow within a pipeline. @@ -194,6 +194,7 @@ def subworkflows_install(ctx, subworkflow, directory, prompt, force, sha): ctx.obj["modules_repo_url"], ctx.obj["modules_repo_branch"], ctx.obj["modules_repo_no_pull"], + only=only, ) exit_status = subworkflow_install.install(subworkflow) if not exit_status: @@ -234,6 +235,7 @@ def subworkflows_update( save_diff, update_deps, limit_output, + only, ): """ Update DSL2 subworkflow within a pipeline. @@ -256,6 +258,7 @@ def subworkflows_update( ctx.obj["modules_repo_branch"], ctx.obj["modules_repo_no_pull"], limit_output, + only, ) exit_status = subworkflow_install.update(subworkflow) if not exit_status and install_all: diff --git a/nf_core/components/install.py b/nf_core/components/install.py index 8350159320..dec5bf10ae 100644 --- a/nf_core/components/install.py +++ b/nf_core/components/install.py @@ -37,6 +37,7 @@ def __init__( branch: str | None = None, no_pull: bool = False, installed_by: list[str] | None = None, + only: bool = False, ): super().__init__(component_type, pipeline_dir, remote_url, branch, no_pull) self.current_remote = ModulesRepo(remote_url, branch) @@ -45,6 +46,7 @@ def __init__( self.prompt = prompt self.sha = sha self.current_sha = sha + self.only = only if installed_by is not None: self.installed_by = installed_by else: @@ -165,7 +167,7 @@ def install(self, component: str | dict[str, str], silent: bool = False) -> bool self.component_type, self.modules_repo, component, version, self.installed_by, install_track ) - if self.component_type == "subworkflows": + if self.component_type == "subworkflows" and not self.only: # Install included modules and subworkflows self.install_included_components(component_dir) diff --git a/nf_core/components/update.py b/nf_core/components/update.py index e679643735..7ffd81f76b 100644 --- a/nf_core/components/update.py +++ b/nf_core/components/update.py @@ -38,6 +38,7 @@ def __init__( branch=None, no_pull=False, limit_output=False, + only=False, ): super().__init__(component_type, pipeline_dir, remote_url, branch, no_pull) self.current_remote = ModulesRepo(remote_url, branch) @@ -50,6 +51,7 @@ def __init__( self.save_diff_fn = save_diff_fn self.limit_output = limit_output self.update_deps = update_deps + self.only = only self.component = None self.update_config = None self.modules_json = ModulesJson(self.directory) @@ -68,6 +70,9 @@ def _parameter_checks(self): if self.update_all and self.component: raise UserWarning(f"Either a {self.component_type[:-1]} or the '--all' flag can be specified, not both.") + if self.only and self.update_deps: + raise UserWarning("`--only` and `--update-deps` are mutually exclusive: pick single-target or cascade.") + if self.repo_type == "modules": raise UserWarning( f"{self.component_type.title()} can not be updated in clones of the nf-core/modules repository." @@ -314,7 +319,10 @@ def update(self, component=None, silent=False, updated=None, check_diff_exist=Tr try_generate_container_configs(self.directory) recursive_update = True modules_to_update, subworkflows_to_update = self.get_components_to_update(component) - if not silent and len(modules_to_update + subworkflows_to_update) > 0 and not self.update_all: + if self.only: + # Caller asked for single-target update; skip linked components entirely. + recursive_update = False + elif not silent and len(modules_to_update + subworkflows_to_update) > 0 and not self.update_all: log.warning( f"All modules and subworkflows linked to the updated {self.component_type[:-1]} will be {'asked for update' if self.show_diff else 'automatically updated'}.\n" "It is advised to keep all your modules and subworkflows up to date.\n" diff --git a/nf_core/modules/install.py b/nf_core/modules/install.py index 7055abe49a..46a1a504a0 100644 --- a/nf_core/modules/install.py +++ b/nf_core/modules/install.py @@ -12,6 +12,7 @@ def __init__( branch=None, no_pull=False, installed_by=None, + only=False, ): super().__init__( pipeline_dir, @@ -23,4 +24,5 @@ def __init__( branch=branch, no_pull=no_pull, installed_by=installed_by, + only=only, ) diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index f6cf5235a4..332ed1ca13 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -16,6 +16,7 @@ def __init__( branch=None, no_pull=False, limit_output=False, + only=False, ): super().__init__( pipeline_dir, @@ -31,4 +32,5 @@ def __init__( branch, no_pull, limit_output, + only, ) diff --git a/nf_core/subworkflows/install.py b/nf_core/subworkflows/install.py index 70a6b0afa5..5a9ce9ab14 100644 --- a/nf_core/subworkflows/install.py +++ b/nf_core/subworkflows/install.py @@ -12,6 +12,7 @@ def __init__( branch=None, no_pull=False, installed_by=None, + only=False, ): super().__init__( pipeline_dir, @@ -23,4 +24,5 @@ def __init__( branch=branch, no_pull=no_pull, installed_by=installed_by, + only=only, ) diff --git a/nf_core/subworkflows/update.py b/nf_core/subworkflows/update.py index 9b6bf16928..cfe65b9e88 100644 --- a/nf_core/subworkflows/update.py +++ b/nf_core/subworkflows/update.py @@ -16,6 +16,7 @@ def __init__( branch=None, no_pull=False, limit_output=False, + only=False, ): super().__init__( pipeline_dir, @@ -31,4 +32,5 @@ def __init__( branch, no_pull, limit_output, + only, ) diff --git a/tests/subworkflows/test_install.py b/tests/subworkflows/test_install.py index 91263d2847..4e21ca6c23 100644 --- a/tests/subworkflows/test_install.py +++ b/tests/subworkflows/test_install.py @@ -18,6 +18,15 @@ class TestSubworkflowsInstall(TestSubworkflows): + def test_subworkflow_install_only_skips_included_components(self): + """`--only` installs the named subworkflow but does not pull in transitive modules.""" + install_obj = SubworkflowInstall(self.pipeline_dir, prompt=False, force=False, only=True) + assert install_obj.install("bam_sort_stats_samtools") is not False + subworkflow_path = Path(self.pipeline_dir, "subworkflows", "nf-core", "bam_sort_stats_samtools") + samtools_index_path = Path(self.pipeline_dir, "modules", "nf-core", "samtools", "index") + assert subworkflow_path.exists(), "Named subworkflow should be installed" + assert not samtools_index_path.exists(), "Transitive module dep must not be installed under --only" + def test_subworkflows_install_bam_sort_stats_samtools(self): """Test installing a subworkflow - bam_sort_stats_samtools""" assert self.subworkflow_install.install("bam_sort_stats_samtools") is not False diff --git a/tests/subworkflows/test_update.py b/tests/subworkflows/test_update.py index 936b61c782..bf03940c60 100644 --- a/tests/subworkflows/test_update.py +++ b/tests/subworkflows/test_update.py @@ -4,6 +4,7 @@ from pathlib import Path from unittest import mock +import pytest import questionary import yaml @@ -32,6 +33,38 @@ def test_install_and_update(self): assert update_obj.update("bam_stats_samtools") is True assert cmp_component(tmpdir, sw_path) is True + def test_subworkflow_update_only_skips_linked_components(self): + """`--only` updates the named subworkflow's SHA but leaves transitive deps untouched.""" + assert self.subworkflow_install_old.install("fastq_align_bowtie2") + old_mod_json = ModulesJson(self.pipeline_dir).get_modules_json() + old_dep_sha = old_mod_json["repos"][NF_CORE_MODULES_REMOTE]["modules"][NF_CORE_MODULES_NAME][ + "samtools/flagstat" + ]["git_sha"] + + update_obj = SubworkflowUpdate(self.pipeline_dir, show_diff=False, only=True) + assert update_obj.update("fastq_align_bowtie2") is True + + mod_json = ModulesJson(self.pipeline_dir).get_modules_json() + # The named subworkflow's SHA moved. + assert ( + mod_json["repos"][NF_CORE_MODULES_REMOTE]["subworkflows"][NF_CORE_MODULES_NAME]["fastq_align_bowtie2"][ + "git_sha" + ] + != old_mod_json["repos"][NF_CORE_MODULES_REMOTE]["subworkflows"][NF_CORE_MODULES_NAME][ + "fastq_align_bowtie2" + ]["git_sha"] + ) + # A transitively-linked module's SHA did not. + assert ( + mod_json["repos"][NF_CORE_MODULES_REMOTE]["modules"][NF_CORE_MODULES_NAME]["samtools/flagstat"]["git_sha"] + == old_dep_sha + ) + + def test_subworkflow_update_only_with_update_deps_errors(self): + """`--only` and `--update-deps` are mutually exclusive.""" + with pytest.raises(UserWarning, match="mutually exclusive"): + SubworkflowUpdate(self.pipeline_dir, only=True, update_deps=True, show_diff=False)._parameter_checks() + def test_install_at_hash_and_update(self): """Installs an old version of a subworkflow in the pipeline and updates it""" assert self.subworkflow_install_old.install("fastq_align_bowtie2") From f63939100554eda9f68622d5b7236e91659648ca Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Mon, 11 May 2026 13:47:05 +0100 Subject: [PATCH 032/135] fix(install --only): preserve installed_by tracking on transitive deps Mashehu's review (PR #4279, comment r3218829796): skipping install_included_components under --only dropped the installed_by tracking update for already-installed transitive deps. If a module was recorded as used by subworkflow A and then subworkflow B was installed with --only, B was not added to the module's installed_by list, and a later uninstall of A would orphan the module. Keep install_included_components in the call path under --only, and instead suppress --force propagation to transitive deps. The recursive call still hits the install.py "already installed" branch (install.py:130-139) for installed deps, which refreshes installed_by without touching files or pinned SHAs. Co-Authored-By: Claude Opus 4.7 (1M context) --- nf_core/components/install.py | 16 +++++++++++++--- tests/subworkflows/test_install.py | 21 ++++++++++++++------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/nf_core/components/install.py b/nf_core/components/install.py index dec5bf10ae..01a8fb58ac 100644 --- a/nf_core/components/install.py +++ b/nf_core/components/install.py @@ -167,9 +167,19 @@ def install(self, component: str | dict[str, str], silent: bool = False) -> bool self.component_type, self.modules_repo, component, version, self.installed_by, install_track ) - if self.component_type == "subworkflows" and not self.only: - # Install included modules and subworkflows - self.install_included_components(component_dir) + if self.component_type == "subworkflows": + # Under --only, don't propagate --force to transitive deps so + # already-installed ones keep their pinned SHAs and just have + # installed_by tracking refreshed. + if self.only: + original_force = self.force + self.force = False + try: + self.install_included_components(component_dir) + finally: + self.force = original_force + else: + self.install_included_components(component_dir) # Regenerate container configuration files for the pipeline when modules are installed if self.component_type == "modules": diff --git a/tests/subworkflows/test_install.py b/tests/subworkflows/test_install.py index 4e21ca6c23..310b62f977 100644 --- a/tests/subworkflows/test_install.py +++ b/tests/subworkflows/test_install.py @@ -18,14 +18,21 @@ class TestSubworkflowsInstall(TestSubworkflows): - def test_subworkflow_install_only_skips_included_components(self): - """`--only` installs the named subworkflow but does not pull in transitive modules.""" - install_obj = SubworkflowInstall(self.pipeline_dir, prompt=False, force=False, only=True) - assert install_obj.install("bam_sort_stats_samtools") is not False - subworkflow_path = Path(self.pipeline_dir, "subworkflows", "nf-core", "bam_sort_stats_samtools") + def test_subworkflow_install_force_only_does_not_reinstall_deps(self): + """`install --force --only` leaves transitive deps' SHAs pinned.""" + assert self.subworkflow_install.install("bam_sort_stats_samtools") is not False samtools_index_path = Path(self.pipeline_dir, "modules", "nf-core", "samtools", "index") - assert subworkflow_path.exists(), "Named subworkflow should be installed" - assert not samtools_index_path.exists(), "Transitive module dep must not be installed under --only" + assert samtools_index_path.exists() + before_sha = ModulesJson(self.pipeline_dir).get_modules_json()["repos"][ + "https://github.com/nf-core/modules.git" + ]["modules"]["nf-core"]["samtools/index"]["git_sha"] + + force_only = SubworkflowInstall(self.pipeline_dir, prompt=False, force=True, only=True) + assert force_only.install("bam_sort_stats_samtools") is not False + after_sha = ModulesJson(self.pipeline_dir).get_modules_json()["repos"][ + "https://github.com/nf-core/modules.git" + ]["modules"]["nf-core"]["samtools/index"]["git_sha"] + assert before_sha == after_sha def test_subworkflows_install_bam_sort_stats_samtools(self): """Test installing a subworkflow - bam_sort_stats_samtools""" From 6867880d1cead14a2114a6ec00a09f1b3aaf705e Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Mon, 11 May 2026 14:09:20 +0100 Subject: [PATCH 033/135] review: drop --only from modules install, block --only with --all, add tests Self-review on PR #4279 found a few rough edges: - --only is a no-op on `nf-core modules install` because install never recurses for modules. Removed the CLI flag and the corresponding parameter from ModuleInstall. - --only and --all on update are semantically contradictory. Added the mutual-exclusion check alongside the existing --only/--update-deps one. - Help text on subworkflows install was inaccurate after the recursion is now kept (force is suppressed instead). Tightened the wording. - Added two tests: installed_by tracking is updated when --only-installing a parent of an already-installed sub-subworkflow (mashehu's scenario), and `module update --only` doesn't invoke update_linked_components even when get_components_to_update reports linked subworkflows. - Added the missing test for --only + --all error. Co-Authored-By: Claude Opus 4.7 (1M context) --- nf_core/__main__.py | 16 +++++----------- nf_core/commands_modules.py | 3 +-- nf_core/components/update.py | 3 +++ nf_core/modules/install.py | 2 -- tests/modules/test_update.py | 14 ++++++++++++++ tests/subworkflows/test_install.py | 11 +++++++++++ tests/subworkflows/test_update.py | 5 +++++ 7 files changed, 39 insertions(+), 15 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 9abf103de7..214b01a0d0 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -993,17 +993,11 @@ def command_modules_list_local(ctx, keywords, json, directory): # pylint: disab help="Force reinstallation of module if it already exists", ) @click.option("-s", "--sha", type=str, metavar="", help="Install module at commit SHA") -@click.option( - "--only", - is_flag=True, - default=False, - help="Restrict the install to the named component; do not recurse into included modules/subworkflows.", -) -def command_modules_install(ctx, tool, directory, prompt, force, sha, only): +def command_modules_install(ctx, tool, directory, prompt, force, sha): """ Install DSL2 modules within a pipeline. """ - modules_install(ctx, tool, directory, prompt, force, sha, only) + modules_install(ctx, tool, directory, prompt, force, sha) # nf-core modules update @@ -1075,7 +1069,7 @@ def command_modules_install(ctx, tool, directory, prompt, force, sha, only): "--only", is_flag=True, default=False, - help="Restrict the update to the named module; do not touch transitively linked components. Mutually exclusive with --update-deps.", + help="Single-target update: don't cascade to linked components. Conflicts with --update-deps and --all.", ) def command_modules_update( ctx, @@ -1744,7 +1738,7 @@ def command_subworkflows_info(ctx, subworkflow, directory): "--only", is_flag=True, default=False, - help="Restrict the install to the named subworkflow; do not recurse into included modules/subworkflows.", + help="With --force, refresh only the named subworkflow; leave transitive deps' files and SHAs pinned.", ) def command_subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, only): """ @@ -1907,7 +1901,7 @@ def command_subworkflows_remove(ctx, directory, subworkflow, force): "--only", is_flag=True, default=False, - help="Restrict the update to the named subworkflow; do not touch transitively linked components. Mutually exclusive with --update-deps.", + help="Single-target update: don't cascade to linked components. Conflicts with --update-deps and --all.", ) def command_subworkflows_update( ctx, diff --git a/nf_core/commands_modules.py b/nf_core/commands_modules.py index f3c9630c80..70d2e147a8 100644 --- a/nf_core/commands_modules.py +++ b/nf_core/commands_modules.py @@ -49,7 +49,7 @@ def modules_list_local(ctx, keywords, json, directory): # pylint: disable=redef sys.exit(1) -def modules_install(ctx, tool, directory, prompt, force, sha, only=False): +def modules_install(ctx, tool, directory, prompt, force, sha): """ Install DSL2 modules within a pipeline. @@ -66,7 +66,6 @@ def modules_install(ctx, tool, directory, prompt, force, sha, only=False): ctx.obj["modules_repo_url"], ctx.obj["modules_repo_branch"], ctx.obj["modules_repo_no_pull"], - only=only, ) exit_status = module_install.install(tool) if not exit_status: diff --git a/nf_core/components/update.py b/nf_core/components/update.py index 7ffd81f76b..159e016186 100644 --- a/nf_core/components/update.py +++ b/nf_core/components/update.py @@ -73,6 +73,9 @@ def _parameter_checks(self): if self.only and self.update_deps: raise UserWarning("`--only` and `--update-deps` are mutually exclusive: pick single-target or cascade.") + if self.only and self.update_all: + raise UserWarning("`--only` and `--all` are mutually exclusive.") + if self.repo_type == "modules": raise UserWarning( f"{self.component_type.title()} can not be updated in clones of the nf-core/modules repository." diff --git a/nf_core/modules/install.py b/nf_core/modules/install.py index 46a1a504a0..7055abe49a 100644 --- a/nf_core/modules/install.py +++ b/nf_core/modules/install.py @@ -12,7 +12,6 @@ def __init__( branch=None, no_pull=False, installed_by=None, - only=False, ): super().__init__( pipeline_dir, @@ -24,5 +23,4 @@ def __init__( branch=branch, no_pull=no_pull, installed_by=installed_by, - only=only, ) diff --git a/tests/modules/test_update.py b/tests/modules/test_update.py index be3df24256..a8008992af 100644 --- a/tests/modules/test_update.py +++ b/tests/modules/test_update.py @@ -43,6 +43,20 @@ def test_install_and_update(self): assert update_obj.update("trimgalore") is True assert cmp_component(trimgalore_tmpdir, trimgalore_path) is True + @mock.patch("nf_core.components.update.ComponentUpdate.update_linked_components") + @mock.patch( + "nf_core.components.update.ComponentUpdate.get_components_to_update", + return_value=([], [{"name": "fake_sw", "git_remote": "x"}]), + ) + def test_module_update_only_does_not_cascade(self, mock_get_linked, mock_cascade): + """`module update --only` skips cascade even when linked subworkflows exist.""" + assert self.mods_install_old.install("trimgalore") + update_obj = ModuleUpdate( + self.pipeline_dir, show_diff=False, only=True, remote_url=GITLAB_URL, branch=OLD_TRIMGALORE_BRANCH + ) + assert update_obj.update("trimgalore") is True + assert not mock_cascade.called + def test_install_at_hash_and_update(self): """Installs an old version of a module in the pipeline and updates it""" assert self.mods_install_old.install("trimgalore") diff --git a/tests/subworkflows/test_install.py b/tests/subworkflows/test_install.py index 310b62f977..86536d6f72 100644 --- a/tests/subworkflows/test_install.py +++ b/tests/subworkflows/test_install.py @@ -34,6 +34,17 @@ def test_subworkflow_install_force_only_does_not_reinstall_deps(self): ]["modules"]["nf-core"]["samtools/index"]["git_sha"] assert before_sha == after_sha + def test_subworkflow_install_only_preserves_installed_by_tracking(self): + """`install --only` of a parent records the new dependent in shared subcomponents' installed_by.""" + # Install the sub-subworkflow first so it's already on disk before we --only the parent. + assert self.subworkflow_install.install("bam_stats_samtools") is not False + only_install = SubworkflowInstall(self.pipeline_dir, prompt=False, force=False, only=True) + assert only_install.install("bam_sort_stats_samtools") is not False + installed_by = ModulesJson(self.pipeline_dir).get_modules_json()["repos"][ + "https://github.com/nf-core/modules.git" + ]["subworkflows"]["nf-core"]["bam_stats_samtools"]["installed_by"] + assert sorted(installed_by) == sorted(["subworkflows", "bam_sort_stats_samtools"]) + def test_subworkflows_install_bam_sort_stats_samtools(self): """Test installing a subworkflow - bam_sort_stats_samtools""" assert self.subworkflow_install.install("bam_sort_stats_samtools") is not False diff --git a/tests/subworkflows/test_update.py b/tests/subworkflows/test_update.py index bf03940c60..f0dd11c486 100644 --- a/tests/subworkflows/test_update.py +++ b/tests/subworkflows/test_update.py @@ -65,6 +65,11 @@ def test_subworkflow_update_only_with_update_deps_errors(self): with pytest.raises(UserWarning, match="mutually exclusive"): SubworkflowUpdate(self.pipeline_dir, only=True, update_deps=True, show_diff=False)._parameter_checks() + def test_subworkflow_update_only_with_all_errors(self): + """`--only` and `--all` are mutually exclusive.""" + with pytest.raises(UserWarning, match="mutually exclusive"): + SubworkflowUpdate(self.pipeline_dir, only=True, update_all=True, show_diff=False)._parameter_checks() + def test_install_at_hash_and_update(self): """Installs an old version of a subworkflow in the pipeline and updates it""" assert self.subworkflow_install_old.install("fastq_align_bowtie2") From 058c6cc58e85e6090c989e68d3fa5d050a7124dc Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Mon, 11 May 2026 15:58:35 +0100 Subject: [PATCH 034/135] review: rename --only to --skip-deps Per mashehu's review (#4279). Reads more naturally next to the existing --update-deps flag. Rename is mechanical: CLI option, attribute (self.only -> self.skip_deps), keyword arg, and tests. Co-Authored-By: Claude Opus 4.7 (1M context) --- nf_core/__main__.py | 22 +++++++++++----------- nf_core/commands_modules.py | 4 ++-- nf_core/commands_subworkflows.py | 8 ++++---- nf_core/components/install.py | 8 ++++---- nf_core/components/update.py | 14 +++++++------- nf_core/modules/update.py | 4 ++-- nf_core/subworkflows/install.py | 4 ++-- nf_core/subworkflows/update.py | 4 ++-- tests/modules/test_update.py | 6 +++--- tests/subworkflows/test_install.py | 18 +++++++++--------- tests/subworkflows/test_update.py | 18 +++++++++--------- 11 files changed, 55 insertions(+), 55 deletions(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 214b01a0d0..4cbe98b603 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -1066,10 +1066,10 @@ def command_modules_install(ctx, tool, directory, prompt, force, sha): help="Automatically update all linked modules and subworkflows without asking for confirmation", ) @click.option( - "--only", + "--skip-deps", is_flag=True, default=False, - help="Single-target update: don't cascade to linked components. Conflicts with --update-deps and --all.", + help="Skip the cascade to linked components. Conflicts with --update-deps and --all.", ) def command_modules_update( ctx, @@ -1083,13 +1083,13 @@ def command_modules_update( save_diff, update_deps, limit_output, - only, + skip_deps, ): """ Update DSL2 modules within a pipeline. """ modules_update( - ctx, tool, directory, force, prompt, sha, install_all, preview, save_diff, update_deps, limit_output, only + ctx, tool, directory, force, prompt, sha, install_all, preview, save_diff, update_deps, limit_output, skip_deps ) @@ -1735,16 +1735,16 @@ def command_subworkflows_info(ctx, subworkflow, directory): help="Install subworkflow at commit SHA", ) @click.option( - "--only", + "--skip-deps", is_flag=True, default=False, help="With --force, refresh only the named subworkflow; leave transitive deps' files and SHAs pinned.", ) -def command_subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, only): +def command_subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, skip_deps): """ Install DSL2 subworkflow within a pipeline. """ - subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, only) + subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, skip_deps) # nf-core subworkflows patch @@ -1898,10 +1898,10 @@ def command_subworkflows_remove(ctx, directory, subworkflow, force): help="Automatically update all linked modules and subworkflows without asking for confirmation", ) @click.option( - "--only", + "--skip-deps", is_flag=True, default=False, - help="Single-target update: don't cascade to linked components. Conflicts with --update-deps and --all.", + help="Skip the cascade to linked components. Conflicts with --update-deps and --all.", ) def command_subworkflows_update( ctx, @@ -1915,7 +1915,7 @@ def command_subworkflows_update( save_diff, update_deps, limit_output, - only, + skip_deps, ): """ Update DSL2 subworkflow within a pipeline. @@ -1932,7 +1932,7 @@ def command_subworkflows_update( save_diff, update_deps, limit_output, - only, + skip_deps, ) diff --git a/nf_core/commands_modules.py b/nf_core/commands_modules.py index 70d2e147a8..525121726b 100644 --- a/nf_core/commands_modules.py +++ b/nf_core/commands_modules.py @@ -87,7 +87,7 @@ def modules_update( save_diff, update_deps, limit_output, - only, + skip_deps, ): """ Update DSL2 modules within a pipeline. @@ -110,7 +110,7 @@ def modules_update( ctx.obj["modules_repo_branch"], ctx.obj["modules_repo_no_pull"], limit_output, - only, + skip_deps, ) exit_status = module_install.update(tool) if not exit_status and install_all: diff --git a/nf_core/commands_subworkflows.py b/nf_core/commands_subworkflows.py index 0cf441458e..4ac3c321a9 100644 --- a/nf_core/commands_subworkflows.py +++ b/nf_core/commands_subworkflows.py @@ -177,7 +177,7 @@ def subworkflows_info(ctx, subworkflow, directory): sys.exit(1) -def subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, only=False): +def subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, skip_deps=False): """ Install DSL2 subworkflow within a pipeline. @@ -194,7 +194,7 @@ def subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, only=F ctx.obj["modules_repo_url"], ctx.obj["modules_repo_branch"], ctx.obj["modules_repo_no_pull"], - only=only, + skip_deps=skip_deps, ) exit_status = subworkflow_install.install(subworkflow) if not exit_status: @@ -235,7 +235,7 @@ def subworkflows_update( save_diff, update_deps, limit_output, - only, + skip_deps, ): """ Update DSL2 subworkflow within a pipeline. @@ -258,7 +258,7 @@ def subworkflows_update( ctx.obj["modules_repo_branch"], ctx.obj["modules_repo_no_pull"], limit_output, - only, + skip_deps, ) exit_status = subworkflow_install.update(subworkflow) if not exit_status and install_all: diff --git a/nf_core/components/install.py b/nf_core/components/install.py index 01a8fb58ac..f71cf4feef 100644 --- a/nf_core/components/install.py +++ b/nf_core/components/install.py @@ -37,7 +37,7 @@ def __init__( branch: str | None = None, no_pull: bool = False, installed_by: list[str] | None = None, - only: bool = False, + skip_deps: bool = False, ): super().__init__(component_type, pipeline_dir, remote_url, branch, no_pull) self.current_remote = ModulesRepo(remote_url, branch) @@ -46,7 +46,7 @@ def __init__( self.prompt = prompt self.sha = sha self.current_sha = sha - self.only = only + self.skip_deps = skip_deps if installed_by is not None: self.installed_by = installed_by else: @@ -168,10 +168,10 @@ def install(self, component: str | dict[str, str], silent: bool = False) -> bool ) if self.component_type == "subworkflows": - # Under --only, don't propagate --force to transitive deps so + # Under --skip-deps, don't propagate --force to transitive deps so # already-installed ones keep their pinned SHAs and just have # installed_by tracking refreshed. - if self.only: + if self.skip_deps: original_force = self.force self.force = False try: diff --git a/nf_core/components/update.py b/nf_core/components/update.py index 159e016186..9a14b732b7 100644 --- a/nf_core/components/update.py +++ b/nf_core/components/update.py @@ -38,7 +38,7 @@ def __init__( branch=None, no_pull=False, limit_output=False, - only=False, + skip_deps=False, ): super().__init__(component_type, pipeline_dir, remote_url, branch, no_pull) self.current_remote = ModulesRepo(remote_url, branch) @@ -51,7 +51,7 @@ def __init__( self.save_diff_fn = save_diff_fn self.limit_output = limit_output self.update_deps = update_deps - self.only = only + self.skip_deps = skip_deps self.component = None self.update_config = None self.modules_json = ModulesJson(self.directory) @@ -70,11 +70,11 @@ def _parameter_checks(self): if self.update_all and self.component: raise UserWarning(f"Either a {self.component_type[:-1]} or the '--all' flag can be specified, not both.") - if self.only and self.update_deps: - raise UserWarning("`--only` and `--update-deps` are mutually exclusive: pick single-target or cascade.") + if self.skip_deps and self.update_deps: + raise UserWarning("`--skip-deps` and `--update-deps` are mutually exclusive.") - if self.only and self.update_all: - raise UserWarning("`--only` and `--all` are mutually exclusive.") + if self.skip_deps and self.update_all: + raise UserWarning("`--skip-deps` and `--all` are mutually exclusive.") if self.repo_type == "modules": raise UserWarning( @@ -322,7 +322,7 @@ def update(self, component=None, silent=False, updated=None, check_diff_exist=Tr try_generate_container_configs(self.directory) recursive_update = True modules_to_update, subworkflows_to_update = self.get_components_to_update(component) - if self.only: + if self.skip_deps: # Caller asked for single-target update; skip linked components entirely. recursive_update = False elif not silent and len(modules_to_update + subworkflows_to_update) > 0 and not self.update_all: diff --git a/nf_core/modules/update.py b/nf_core/modules/update.py index 332ed1ca13..ed34b3e41c 100644 --- a/nf_core/modules/update.py +++ b/nf_core/modules/update.py @@ -16,7 +16,7 @@ def __init__( branch=None, no_pull=False, limit_output=False, - only=False, + skip_deps=False, ): super().__init__( pipeline_dir, @@ -32,5 +32,5 @@ def __init__( branch, no_pull, limit_output, - only, + skip_deps, ) diff --git a/nf_core/subworkflows/install.py b/nf_core/subworkflows/install.py index 5a9ce9ab14..90bb504b80 100644 --- a/nf_core/subworkflows/install.py +++ b/nf_core/subworkflows/install.py @@ -12,7 +12,7 @@ def __init__( branch=None, no_pull=False, installed_by=None, - only=False, + skip_deps=False, ): super().__init__( pipeline_dir, @@ -24,5 +24,5 @@ def __init__( branch=branch, no_pull=no_pull, installed_by=installed_by, - only=only, + skip_deps=skip_deps, ) diff --git a/nf_core/subworkflows/update.py b/nf_core/subworkflows/update.py index cfe65b9e88..29c4dbcc02 100644 --- a/nf_core/subworkflows/update.py +++ b/nf_core/subworkflows/update.py @@ -16,7 +16,7 @@ def __init__( branch=None, no_pull=False, limit_output=False, - only=False, + skip_deps=False, ): super().__init__( pipeline_dir, @@ -32,5 +32,5 @@ def __init__( branch, no_pull, limit_output, - only, + skip_deps, ) diff --git a/tests/modules/test_update.py b/tests/modules/test_update.py index a8008992af..b061fe185a 100644 --- a/tests/modules/test_update.py +++ b/tests/modules/test_update.py @@ -48,11 +48,11 @@ def test_install_and_update(self): "nf_core.components.update.ComponentUpdate.get_components_to_update", return_value=([], [{"name": "fake_sw", "git_remote": "x"}]), ) - def test_module_update_only_does_not_cascade(self, mock_get_linked, mock_cascade): - """`module update --only` skips cascade even when linked subworkflows exist.""" + def test_module_update_skip_deps_does_not_cascade(self, mock_get_linked, mock_cascade): + """`module update --skip-deps` skips cascade even when linked subworkflows exist.""" assert self.mods_install_old.install("trimgalore") update_obj = ModuleUpdate( - self.pipeline_dir, show_diff=False, only=True, remote_url=GITLAB_URL, branch=OLD_TRIMGALORE_BRANCH + self.pipeline_dir, show_diff=False, skip_deps=True, remote_url=GITLAB_URL, branch=OLD_TRIMGALORE_BRANCH ) assert update_obj.update("trimgalore") is True assert not mock_cascade.called diff --git a/tests/subworkflows/test_install.py b/tests/subworkflows/test_install.py index 86536d6f72..67b007f9d9 100644 --- a/tests/subworkflows/test_install.py +++ b/tests/subworkflows/test_install.py @@ -18,8 +18,8 @@ class TestSubworkflowsInstall(TestSubworkflows): - def test_subworkflow_install_force_only_does_not_reinstall_deps(self): - """`install --force --only` leaves transitive deps' SHAs pinned.""" + def test_subworkflow_install_force_skip_deps_does_not_reinstall_deps(self): + """`install --force --skip-deps` leaves transitive deps' SHAs pinned.""" assert self.subworkflow_install.install("bam_sort_stats_samtools") is not False samtools_index_path = Path(self.pipeline_dir, "modules", "nf-core", "samtools", "index") assert samtools_index_path.exists() @@ -27,19 +27,19 @@ def test_subworkflow_install_force_only_does_not_reinstall_deps(self): "https://github.com/nf-core/modules.git" ]["modules"]["nf-core"]["samtools/index"]["git_sha"] - force_only = SubworkflowInstall(self.pipeline_dir, prompt=False, force=True, only=True) - assert force_only.install("bam_sort_stats_samtools") is not False + force_skip = SubworkflowInstall(self.pipeline_dir, prompt=False, force=True, skip_deps=True) + assert force_skip.install("bam_sort_stats_samtools") is not False after_sha = ModulesJson(self.pipeline_dir).get_modules_json()["repos"][ "https://github.com/nf-core/modules.git" ]["modules"]["nf-core"]["samtools/index"]["git_sha"] assert before_sha == after_sha - def test_subworkflow_install_only_preserves_installed_by_tracking(self): - """`install --only` of a parent records the new dependent in shared subcomponents' installed_by.""" - # Install the sub-subworkflow first so it's already on disk before we --only the parent. + def test_subworkflow_install_skip_deps_preserves_installed_by_tracking(self): + """`install --skip-deps` of a parent records the new dependent in shared subcomponents' installed_by.""" + # Install the sub-subworkflow first so it's already on disk before we --skip-deps the parent. assert self.subworkflow_install.install("bam_stats_samtools") is not False - only_install = SubworkflowInstall(self.pipeline_dir, prompt=False, force=False, only=True) - assert only_install.install("bam_sort_stats_samtools") is not False + skip_install = SubworkflowInstall(self.pipeline_dir, prompt=False, force=False, skip_deps=True) + assert skip_install.install("bam_sort_stats_samtools") is not False installed_by = ModulesJson(self.pipeline_dir).get_modules_json()["repos"][ "https://github.com/nf-core/modules.git" ]["subworkflows"]["nf-core"]["bam_stats_samtools"]["installed_by"] diff --git a/tests/subworkflows/test_update.py b/tests/subworkflows/test_update.py index f0dd11c486..6c9567ae40 100644 --- a/tests/subworkflows/test_update.py +++ b/tests/subworkflows/test_update.py @@ -33,15 +33,15 @@ def test_install_and_update(self): assert update_obj.update("bam_stats_samtools") is True assert cmp_component(tmpdir, sw_path) is True - def test_subworkflow_update_only_skips_linked_components(self): - """`--only` updates the named subworkflow's SHA but leaves transitive deps untouched.""" + def test_subworkflow_update_skip_deps_skips_linked_components(self): + """`--skip-deps` updates the named subworkflow's SHA but leaves transitive deps untouched.""" assert self.subworkflow_install_old.install("fastq_align_bowtie2") old_mod_json = ModulesJson(self.pipeline_dir).get_modules_json() old_dep_sha = old_mod_json["repos"][NF_CORE_MODULES_REMOTE]["modules"][NF_CORE_MODULES_NAME][ "samtools/flagstat" ]["git_sha"] - update_obj = SubworkflowUpdate(self.pipeline_dir, show_diff=False, only=True) + update_obj = SubworkflowUpdate(self.pipeline_dir, show_diff=False, skip_deps=True) assert update_obj.update("fastq_align_bowtie2") is True mod_json = ModulesJson(self.pipeline_dir).get_modules_json() @@ -60,15 +60,15 @@ def test_subworkflow_update_only_skips_linked_components(self): == old_dep_sha ) - def test_subworkflow_update_only_with_update_deps_errors(self): - """`--only` and `--update-deps` are mutually exclusive.""" + def test_subworkflow_update_skip_deps_with_update_deps_errors(self): + """`--skip-deps` and `--update-deps` are mutually exclusive.""" with pytest.raises(UserWarning, match="mutually exclusive"): - SubworkflowUpdate(self.pipeline_dir, only=True, update_deps=True, show_diff=False)._parameter_checks() + SubworkflowUpdate(self.pipeline_dir, skip_deps=True, update_deps=True, show_diff=False)._parameter_checks() - def test_subworkflow_update_only_with_all_errors(self): - """`--only` and `--all` are mutually exclusive.""" + def test_subworkflow_update_skip_deps_with_all_errors(self): + """`--skip-deps` and `--all` are mutually exclusive.""" with pytest.raises(UserWarning, match="mutually exclusive"): - SubworkflowUpdate(self.pipeline_dir, only=True, update_all=True, show_diff=False)._parameter_checks() + SubworkflowUpdate(self.pipeline_dir, skip_deps=True, update_all=True, show_diff=False)._parameter_checks() def test_install_at_hash_and_update(self): """Installs an old version of a subworkflow in the pipeline and updates it""" From 8060ecec68e9de99b424da52033048a3dd0facd7 Mon Sep 17 00:00:00 2001 From: Jonathan Manning Date: Mon, 11 May 2026 17:30:08 +0100 Subject: [PATCH 035/135] fix(update --skip-deps): also short-circuit the cascade in --save-diff The non-dry-run path of `ComponentUpdate.update` honoured `self.skip_deps`, but the dry-run `--save-diff` branch still walked `get_components_to_update` and called `update_linked_components`, so the generated diff contained every transitively-linked component instead of just the named one. Add the same `if self.skip_deps: recursive_update = False` guard to the save-diff path and a regression test that asserts the resulting diff references only the named subworkflow. Co-Authored-By: Claude Opus 4.7 (1M context) --- nf_core/components/update.py | 4 +++- tests/subworkflows/test_update.py | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/nf_core/components/update.py b/nf_core/components/update.py index 9a14b732b7..1017643549 100644 --- a/nf_core/components/update.py +++ b/nf_core/components/update.py @@ -266,7 +266,9 @@ def update(self, component=None, silent=False, updated=None, check_diff_exist=Tr updated.append(component) recursive_update = True modules_to_update, subworkflows_to_update = self.get_components_to_update(component) - if not silent and len(modules_to_update + subworkflows_to_update) > 0: + if self.skip_deps: + recursive_update = False + elif not silent and len(modules_to_update + subworkflows_to_update) > 0: log.warning( f"All modules and subworkflows linked to the updated {self.component_type[:-1]} will be added to the same diff file.\n" "It is advised to keep all your modules and subworkflows up to date.\n" diff --git a/tests/subworkflows/test_update.py b/tests/subworkflows/test_update.py index 6c9567ae40..25a41a1e42 100644 --- a/tests/subworkflows/test_update.py +++ b/tests/subworkflows/test_update.py @@ -60,6 +60,29 @@ def test_subworkflow_update_skip_deps_skips_linked_components(self): == old_dep_sha ) + def test_subworkflow_update_skip_deps_save_diff_only_named_component(self): + """`--skip-deps --save-diff` writes a diff for only the named subworkflow, no linked components.""" + assert self.subworkflow_install_old.install("fastq_align_bowtie2") + diff_path = Path(tempfile.mkdtemp()) / "skipdeps.diff" + update_obj = SubworkflowUpdate( + self.pipeline_dir, + show_diff=False, + save_diff_fn=diff_path, + skip_deps=True, + ) + assert update_obj.update("fastq_align_bowtie2") is True + + diff_text = diff_path.read_text() + # The named subworkflow's main.nf should be in the diff + assert "subworkflows/nf-core/fastq_align_bowtie2/main.nf" in diff_text + # Transitively-linked module files (e.g. samtools/*) must not be in the diff + for linked in ( + "modules/nf-core/samtools/flagstat/main.nf", + "modules/nf-core/samtools/index/main.nf", + "modules/nf-core/samtools/sort/main.nf", + ): + assert linked not in diff_text, f"unexpected linked component in --skip-deps diff: {linked}" + def test_subworkflow_update_skip_deps_with_update_deps_errors(self): """`--skip-deps` and `--update-deps` are mutually exclusive.""" with pytest.raises(UserWarning, match="mutually exclusive"): From 2e5666d89bae010ec2c910374ab33bbbf4e9e633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 20 May 2026 16:13:21 +0200 Subject: [PATCH 036/135] modules info: handle one element channels correctly (#4268) * handle one element channels correctly * update docstring --- CHANGELOG.md | 2 ++ nf_core/components/info.py | 3 +++ tests/modules/test_info.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56398753fc..2bfd0400a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ ### Modules +- `modules info`: handle one element channels correctly ([#4268](https://github.com/nf-core/tools/pull/4268)) + ### Subworkflows ### Template diff --git a/nf_core/components/info.py b/nf_core/components/info.py index cc30f8dec9..57f0a3858e 100644 --- a/nf_core/components/info.py +++ b/nf_core/components/info.py @@ -299,9 +299,12 @@ def generate_component_info_help(self): # Inputs if self.meta.get("input"): inputs_table = self.generate_params_table("Inputs") + log.debug(f"Input channels: {self.meta['input']}") for i, input_channel in enumerate(self.meta["input"]): inputs_table.add_row(f"[italic]input[{i}][/]", "", "") if self.component_type == "modules": + if not isinstance(input_channel, list): + input_channel = [input_channel] for element in input_channel: for key, info in element.items(): inputs_table.add_row( diff --git a/tests/modules/test_info.py b/tests/modules/test_info.py index 8e60bed316..3f338d28bc 100644 --- a/tests/modules/test_info.py +++ b/tests/modules/test_info.py @@ -1,3 +1,6 @@ +from pathlib import Path + +import yaml from rich.console import Console import nf_core.modules.info @@ -60,3 +63,29 @@ def test_modules_info_in_modules_repo(self): assert "Module: fastqc" in output assert "Inputs" in output assert "Outputs" in output + + def test_modules_info_mixed_input_type(self): + """Test getting info about a module with mixed input types (list and dict)""" + self.mods_install.install("fastqc") + meta_path = Path(self.pipeline_dir, "modules", "nf-core", "fastqc", "meta.yml") + + # Load existing meta.yml + with open(meta_path) as f: + meta = yaml.safe_load(f) + + # Append a dictionary-style input (the cause of the bug) + meta["input"].append({"index_format": {"type": "string", "description": "Index format"}}) + + # Write modified meta.yml back + with open(meta_path, "w") as f: + yaml.dump(meta, f) + + mods_info = nf_core.modules.info.ModuleInfo(self.pipeline_dir, "fastqc") + mods_info_output = mods_info.get_component_info() + console = Console(record=True) + console.print(mods_info_output) + output = console.export_text() + + assert "Module: fastqc" in output + assert "index_format" in output + assert "(string)" in output From 3c0c3106c2418bc63a3320849732c242bc6f14d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 21 May 2026 10:52:26 +0200 Subject: [PATCH 037/135] fix CI: commit updated configs after modules update step (#4292) --- .github/actions/create-lint-wf/action.yml | 17 ++++++++++++++--- nf_core/utils.py | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/actions/create-lint-wf/action.yml b/.github/actions/create-lint-wf/action.yml index 0102c71dfb..97a6b95cd9 100644 --- a/.github/actions/create-lint-wf/action.yml +++ b/.github/actions/create-lint-wf/action.yml @@ -53,22 +53,33 @@ runs: run: uv run nf-core --log-file log.txt modules update --dir nf-core-testpipeline --all --no-preview working-directory: create-lint-wf + # Commit regenerated container configs so lint sees them as up to date + - name: commit updated container configs + shell: bash + run: | + cd nf-core-testpipeline + git config user.email "nf-core-bot@nf-co.re" + git config user.name "nf-core-bot" + git add conf/containers_*.config + git diff --cached --quiet || git commit -m "Update container configs after modules update" + working-directory: create-lint-wf + # Remove TODO statements - name: remove TODO shell: bash - run: find nf-core-testpipeline -type f -exec sed -i 's#TODO nf-core:##g' {} \; + run: find nf-core-testpipeline -not -path '*/.git/*' -type f -exec sed -i 's#TODO nf-core:##g' {} \; working-directory: create-lint-wf # Uncomment includeConfig statement - name: uncomment include config shell: bash - run: find nf-core-testpipeline -type f -exec sed -i 's/\/\/ includeConfig/includeConfig/' {} \; + run: find nf-core-testpipeline -not -path '*/.git/*' -type f -exec sed -i 's/\/\/ includeConfig/includeConfig/' {} \; working-directory: create-lint-wf # Replace zenodo.XXXXXX to pass readme linting - name: replace zenodo.XXXXXX shell: bash - run: find nf-core-testpipeline -type f -exec sed -i 's/zenodo.XXXXXX/zenodo.123456/g' {} \; + run: find nf-core-testpipeline -not -path '*/.git/*' -type f -exec sed -i 's/zenodo.XXXXXX/zenodo.123456/g' {} \; working-directory: create-lint-wf # Run nf-core pipelines linting diff --git a/nf_core/utils.py b/nf_core/utils.py index d376559e53..333cc75d1f 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -203,7 +203,7 @@ def __init__(self, wf_path: Path) -> None: self.files: list[Path] = [] self.git_sha: str | None = None self.minNextflowVersion: str | None = None - self.wf_path = Path(wf_path) + self.wf_path = Path(wf_path).resolve() self.pipeline_name: str | None = None self.pipeline_prefix: str | None = None self.schema_obj: PipelineSchema | None = None From dfe760d38736f22f68fcd0fdf311e30b58567c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 21 May 2026 13:01:59 +0200 Subject: [PATCH 038/135] simplify logic for parsing of container configs (#4277) --- nf_core/components/install.py | 5 +- nf_core/components/update.py | 5 +- nf_core/pipelines/containers_utils.py | 268 +++++++++----------- nf_core/pipelines/lint/container_configs.py | 14 +- nf_core/utils.py | 12 + tests/pipelines/test_container_configs.py | 82 +++--- 6 files changed, 180 insertions(+), 206 deletions(-) diff --git a/nf_core/components/install.py b/nf_core/components/install.py index f71cf4feef..fc6c790dd3 100644 --- a/nf_core/components/install.py +++ b/nf_core/components/install.py @@ -181,9 +181,10 @@ def install(self, component: str | dict[str, str], silent: bool = False) -> bool else: self.install_included_components(component_dir) - # Regenerate container configuration files for the pipeline when modules are installed + # Update container configs for the installed module. Subworkflows have no container entries of their + # own; their included modules each trigger this when installed above. if self.component_type == "modules": - try_generate_container_configs(self.directory, component_dir, component) + try_generate_container_configs(self.directory, component_dir) if not silent: modules_json.load() diff --git a/nf_core/components/update.py b/nf_core/components/update.py index 1017643549..bf2b9a64b8 100644 --- a/nf_core/components/update.py +++ b/nf_core/components/update.py @@ -318,10 +318,9 @@ def update(self, component=None, silent=False, updated=None, check_diff_exist=Tr # Update modules.json with newly installed component self.modules_json.update(self.component_type, modules_repo, component, version, installed_by=None) updated.append(component) - - # Regenerate container configuration files for the pipeline when modules are updated if self.component_type == "modules": - try_generate_container_configs(self.directory) + try_generate_container_configs(self.directory, component_dir) + recursive_update = True modules_to_update, subworkflows_to_update = self.get_components_to_update(component) if self.skip_deps: diff --git a/nf_core/pipelines/containers_utils.py b/nf_core/pipelines/containers_utils.py index a3a5751ef3..d7de4fe73c 100644 --- a/nf_core/pipelines/containers_utils.py +++ b/nf_core/pipelines/containers_utils.py @@ -1,11 +1,12 @@ -import json +import contextlib import logging import re +from concurrent.futures import ThreadPoolExecutor, as_completed from pathlib import Path import yaml -from nf_core.utils import NF_INSPECT_MIN_NF_VERSION, check_nextflow_version, pretty_nf_version, run_cmd +from nf_core.utils import read_module_name log = logging.getLogger(__name__) @@ -20,185 +21,158 @@ "conda_lock_files_arm64": ["conda", "linux/arm64", "lock_file"], } +_CONFIG_LINE_RE = re.compile(r"withName:\s*'(\w+)'\s*\{\s*(?:container|conda)\s*=\s*'([^']+)'") -class ContainerConfigs: - """Generates the container configuration files for a pipeline. - Args: - workflow_directory (Path): The directory containing the workflow files. - """ +def _container_key(platform: str) -> str: + return "conda" if platform.startswith("conda_lock_") else "container" - def __init__( - self, - workflow_directory: Path = Path(), - ): - self.workflow_directory = workflow_directory - def check_nextflow_version_sufficient(self) -> None: - """Check if the Nextflow version is sufficient to run `nextflow inspect`.""" - if not check_nextflow_version(NF_INSPECT_MIN_NF_VERSION, silent=True): - raise UserWarning( - f"To use Seqera containers Nextflow version >= {pretty_nf_version(NF_INSPECT_MIN_NF_VERSION)} is required.\n" - f"Please update your Nextflow version with [magenta]'nextflow self-update'[/]\n" - ) +def _parse_config_file(config_path: Path) -> dict[str, str]: + """Return {module_name: container} from an existing platform config file.""" + result: dict[str, str] = {} + with contextlib.suppress(OSError): + for line in config_path.read_text().splitlines(): + m = _CONFIG_LINE_RE.search(line) + if m: + result[m.group(1)] = m.group(2) + return result - def parse_module_paths(self) -> dict[str, Path]: - """Parse include statements from workflow files to extract module paths. - Only processes includes pointing to 'modules/' directories. - Extracts the path from 'modules/' onwards, ignoring any '../' prefixes. +def _write_platform_config(config_path: Path, entries: dict[str, str], key: str) -> bool: + """Write *entries* to *config_path*, or delete it when empty. - Returns: - dict: Mapping of process names to their module paths (e.g., 'modules/nf-core/fastqc') - """ - module_paths = {} + Skips the write when content is unchanged. Returns True if the file now exists. + """ + if not entries: + config_path.unlink(missing_ok=True) + return False + new_content = "".join( + f"process {{ withName: '{name}' {{ {key} = '{container}' }} }}\n" for name, container in sorted(entries.items()) + ) + if not config_path.exists() or config_path.read_text() != new_content: + config_path.write_text(new_content) + return True - # Pattern matches: include { NAME ... } from 'path' - # Captures the first name (original) and the path, ignoring any alias - include_pattern = re.compile(r"include\s*\{\s*(\w+).*?\}\s*from\s+['\"]([^'\"]+)['\"]") - # Search in root (main.nf), workflows, modules, and subworkflows directories - search_dirs = ["workflows", "modules", "subworkflows"] +def _process_meta(meta_path: Path) -> tuple[str, dict[str, str]] | None: + """Read one meta.yml + sibling main.nf and return (module_name, {platform: container}). - nf_files_to_search = list(self.workflow_directory.glob("*.nf")) - for search_dir in search_dirs: - search_path = self.workflow_directory / search_dir - if not search_path.exists(): - continue - nf_files_to_search.extend(search_path.rglob("*.nf")) + Returns None when the file should be skipped. + """ + try: + raw = meta_path.read_bytes() + except OSError as e: + log.debug(f"Could not read {meta_path}: {e}") + return None + + # TODO: remove this early-exit once containers are present in the majority of modules + if b"containers:" not in raw: + return None + + meta = yaml.safe_load(raw) - for nf_file in nf_files_to_search: - try: - content = nf_file.read_text() - for match in include_pattern.finditer(content): - process_name = match.group(1) - relative_path = match.group(2) + module_name = read_module_name(meta_path.parent / "main.nf") + if not module_name: + log.debug(f"No process definition found next to {meta_path}, skipping") + return None - # Only process paths that contain 'modules/' - if "modules/" not in relative_path: - continue + platform_containers: dict[str, str] = {} + for platform_name, (runtime, arch, protocol) in PLATFORMS.items(): + log.debug(f"Adding container for platform {platform_name}, runtime={runtime}, arch={arch}, protocol={protocol}") + with contextlib.suppress(KeyError, TypeError): + platform_containers[platform_name] = meta["containers"][runtime][arch][protocol] - # Extract everything from 'modules/' onwards, removing any '/main' suffix - module_path_str = relative_path[relative_path.find("modules/") :] - module_path_str = module_path_str.replace("/main", "") + return module_name, platform_containers + + +class ContainerConfigs: + """Generates the container configuration files for a pipeline. - module_paths[process_name] = Path(module_path_str) - log.debug(f"Found include: {process_name} -> {module_path_str}") + Args: + workflow_directory (Path): The directory containing the workflow files. + """ - except OSError as e: - log.debug(f"Error parsing {nf_file}: {e}") - continue + def __init__(self, workflow_directory: Path = Path()) -> None: + self.workflow_directory = workflow_directory - return module_paths + def update_module_container_config(self, module_path: Path) -> None: + """Targeted update for a single module. - def generate_container_configs( - self, new_module_path: Path | None = None, new_module_name: str | None = None - ) -> set[str]: + Reads the current config files, splices in (or removes) the entry for + the module at *module_path*, and writes back only what changed. """ - Generate the container configuration files for a pipeline. - Requires Nextflow >= 25.04.4 + result = _process_meta(module_path / "meta.yml") + + if result is None: + module_name = read_module_name(module_path / "main.nf") + if not module_name: + log.debug(f"Could not determine process name for {module_path}, skipping") + return + platform_containers: dict[str, str] = {} + else: + module_name, platform_containers = result + + conf_dir = self.workflow_directory / "conf" + for platform in PLATFORMS: + config_path = conf_dir / f"containers_{platform}.config" + entries = _parse_config_file(config_path) + if platform in platform_containers: + entries[module_name] = platform_containers[platform] + _write_platform_config(config_path, entries, _container_key(platform)) + + def generate_container_configs(self) -> set[str]: + """Full scan of all ``meta.yml`` files under ``modules/``. + + Used by lint and bulk operations (update, remove, patch) where multiple + modules may have changed. Returns: set[str]: Names of config files written (e.g. ``{'containers_docker_amd64.config'}``). """ - self.check_nextflow_version_sufficient() - log.debug("Generating container config file with [magenta bold]nextflow inspect[/].") - try: - # Run nextflow inspect - executable = "nextflow" - cmd_params = f"inspect -format json {self.workflow_directory}" - cmd_out = run_cmd(executable, cmd_params) - if cmd_out is None: - raise UserWarning("Failed to run `nextflow inspect`. Please check your Nextflow installation.") - - out, _ = cmd_out - out_str = out.decode("utf-8", errors="replace") - try: - # Newer Nextflow versions print [PIPELINE]/[WORKDIR] headers before and [SUCCESS] after the JSON - json_start = out_str.find("{") - out_json, _ = json.JSONDecoder().raw_decode(out_str, json_start if json_start >= 0 else 0) - except json.JSONDecodeError: - out_json = json.loads(out) - - except RuntimeError as e: - log.error("Running 'nextflow inspect' failed with the following error:") - raise UserWarning(e) from e - - module_names = {p.get("name") for p in out_json["processes"] if p.get("name")} - log.debug(f"Found {len(module_names)} modules: {', '.join(module_names)}") - - # Parse module paths from include statements - module_path_map = self.parse_module_paths() - log.debug(f"Parsed {len(module_path_map)} module paths from include statements") - - if new_module_name and new_module_path: - module_names.add(new_module_name.upper()) - module_path_map[new_module_name.upper()] = new_module_path - - # Build containers dict from module meta.yml files - # Pre-initialize all platforms to avoid repeated existence checks - has_warnings = False + modules_dir = self.workflow_directory / "modules" + if not modules_dir.is_dir(): + log.debug(f"No modules directory found at {modules_dir}, skipping") + return set() + containers: dict[str, dict[str, str]] = {platform: {} for platform in PLATFORMS} - for m_name in module_names: - # Try to get module path from include statements - if m_name in module_path_map: - module_path = module_path_map[m_name] - log.debug(f"Using parsed path for {m_name}: {module_path}") - else: - # Fallback to old heuristic method - log.debug(f"No parsed path found for {m_name}, using heuristic") - module_path = Path(*m_name.lower().split("_", 1)) - - # Look for meta.yml in the module path - meta_path = self.workflow_directory / module_path / "meta.yml" - - try: - with open(meta_path) as fh: - meta = yaml.safe_load(fh) - log.debug(f"Loaded meta.yml for {m_name} from {meta_path}") - except FileNotFoundError: - log.warning(f"Could not find meta.yml for {m_name} at {meta_path}") - continue - - # Extract containers for all platforms - for platform_name, (runtime, arch, protocol) in PLATFORMS.items(): - try: - containers[platform_name][m_name] = meta["containers"][runtime][arch][protocol] - log.debug(f"Found {platform_name} container for {m_name}") - except (KeyError, TypeError): - log.debug(f"Could not find {platform_name} container for {m_name}") - has_warnings = True + + with ThreadPoolExecutor() as pool: + futures = {pool.submit(_process_meta, p): p for p in modules_dir.rglob("meta.yml")} + for future in as_completed(futures): + result = future.result() + if result is None: continue - if has_warnings: - log.debug( - "Generated container configs for the pipeline. Not all containers were found. Run with `-v` to see detailed warning messages." - ) - else: - log.info("Generated container configs for the pipeline successfully.") + module_name, platform_containers = result + for platform_name, container in platform_containers.items(): + containers[platform_name][module_name] = container # remove all generated config files, to handle removed modules for platform in PLATFORMS: (self.workflow_directory / "conf" / f"containers_{platform}.config").unlink(missing_ok=True) - # write config files + written: set[str] = set() for platform, module_containers in containers.items(): - if not module_containers: - continue - container_key = "conda" if platform.startswith("conda_lock_") else "container" - lines = [ - f"process {{ withName: '{module_name}' {{ {container_key} = '{container}' }} }}\n" - for module_name, container in sorted(module_containers.items()) - ] config_path = self.workflow_directory / "conf" / f"containers_{platform}.config" - config_path.write_text("".join(lines)) - written.add(config_path.name) + if _write_platform_config(config_path, module_containers, _container_key(platform)): + written.add(config_path.name) + + log.info("Generated container configs for the pipeline.") return written -def try_generate_container_configs( - directory: Path, new_module_path: Path | None = None, new_module_name: str | None = None -) -> None: +def try_generate_container_configs(directory: Path, module_path: Path | None = None) -> None: + """Regenerate container configs for *directory*. + + If *module_path* is given, only that module's entries are updated (fast + path for single-module installs). Otherwise a full scan of ``modules/`` + is performed. + """ try: - ContainerConfigs(directory).generate_container_configs(new_module_path, new_module_name) + configs = ContainerConfigs(directory) + if module_path is not None: + configs.update_module_container_config(module_path) + else: + configs.generate_container_configs() except UserWarning as e: log.warning(f"Could not regenerate container configuration files: {e}") diff --git a/nf_core/pipelines/lint/container_configs.py b/nf_core/pipelines/lint/container_configs.py index b5143dba82..e6aba4bd15 100644 --- a/nf_core/pipelines/lint/container_configs.py +++ b/nf_core/pipelines/lint/container_configs.py @@ -11,9 +11,11 @@ def container_configs(self): """Check that the container configuration files in ``conf/`` are up to date. - Runs ``nextflow inspect`` to regenerate container configuration files directly - in ``conf/`` and uses ``git diff`` to detect changes. If not in ``--fix`` mode - the working tree is restored to its original state afterwards. + Scans all ``meta.yml`` files under ``modules/`` that contain a ``containers`` + key, reads the process name from the sibling ``main.nf``, and regenerates + the container configuration files in ``conf/``. Uses ``git diff`` to detect + changes. If not in ``--fix`` mode the working tree is restored to its + original state afterwards. Can be skipped by adding the following to the ``.nf-core.yml`` file: @@ -37,6 +39,8 @@ def container_configs(self): warned.append(f"Could not generate container configuration files: {e}") return {"passed": passed, "failed": failed, "warned": warned} + log.debug(f"Generated {len(generated)} container config file(s): {', '.join(sorted(generated)) or 'none'}") + # Files modified in the working tree (tracked and changed by generation) modified = { Path(d.a_path).name @@ -52,6 +56,8 @@ def container_configs(self): # Already-correct files: generated, tracked, and unchanged correct = generated - modified - new + log.debug(f"Container config status — correct: {len(correct)}, modified: {len(modified)}, new: {len(new)}") + fixing = "container_configs" in self.fix for name in sorted(correct): @@ -59,6 +65,7 @@ def container_configs(self): for name in sorted(modified | new): if fixing: + log.debug(f"Overwriting `conf/{name}` with regenerated container configuration") passed.append(f"`conf/{name}` is up to date") fixed.append(f"`conf/{name}` overwritten with regenerated container configuration.") else: @@ -70,6 +77,7 @@ def container_configs(self): if not fixing: # Restore working tree: reset modified tracked files and delete new untracked ones + log.debug(f"Restoring working tree: resetting {len(modified)} modified, removing {len(new)} new file(s)") for name in modified: repo.git.restore(str(conf_dir / name)) for name in new: diff --git a/nf_core/utils.py b/nf_core/utils.py index 333cc75d1f..483d1b799b 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -369,6 +369,18 @@ def check_nextflow_version(minimal_nf_version: tuple[int, int, int, bool], silen return nf_version >= minimal_nf_version +_NF_PROCESS_NAME_RE = re.compile(r"^\s*process\s+(\w+)\s*\{", re.MULTILINE) + + +def read_module_name(main_nf: Path) -> str | None: + """Return the process name declared in a Nextflow ``main.nf`` file, or ``None``.""" + try: + match = _NF_PROCESS_NAME_RE.search(main_nf.read_text()) + return match.group(1) if match else None + except OSError: + return None + + def fetch_wf_config(wf_path: Path, cache_config: bool = True) -> dict: """Uses Nextflow to retrieve the the configuration variables from a Nextflow workflow. diff --git a/tests/pipelines/test_container_configs.py b/tests/pipelines/test_container_configs.py index c7f5067afa..e879a5f5e1 100644 --- a/tests/pipelines/test_container_configs.py +++ b/tests/pipelines/test_container_configs.py @@ -1,14 +1,11 @@ """Tests for the ContainerConfigs helper used by pipelines.""" -from pathlib import Path -from unittest.mock import patch +import shutil -import pytest import ruamel.yaml from nf_core.modules.install import ModuleInstall from nf_core.pipelines.containers_utils import PLATFORMS, ContainerConfigs -from nf_core.utils import NF_INSPECT_MIN_NF_VERSION, pretty_nf_version from ..test_pipelines import TestPipelines @@ -22,30 +19,6 @@ def setUp(self) -> None: super().setUp() self.container_configs = ContainerConfigs(self.pipeline_dir) - def test_check_nextflow_version_sufficient_ok(self) -> None: - """check_nextflow_version should return silently when version is sufficient.""" - with patch( - "nf_core.pipelines.containers_utils.check_nextflow_version", - return_value=True, - ) as mocked_check: - self.container_configs.check_nextflow_version_sufficient() - - mocked_check.assert_called_once_with(NF_INSPECT_MIN_NF_VERSION, silent=True) - - def test_check_nextflow_version_sufficient_too_low(self) -> None: - """check_nextflow_version should raise UserWarning when version is too low.""" - with ( - patch( - "nf_core.pipelines.containers_utils.check_nextflow_version", - return_value=False, - ), - pytest.raises(UserWarning) as excinfo, - ): - self.container_configs.check_nextflow_version_sufficient() - - # Error message should mention the minimal required version - assert pretty_nf_version(NF_INSPECT_MIN_NF_VERSION) in str(excinfo.value) - def test_generate_all_container_configs(self) -> None: """Run generate_all_container_configs in a pipeline.""" # Install fastqc and multiqc @@ -70,8 +43,8 @@ def test_generate_all_container_configs(self) -> None: key = "conda" if p_name.startswith("conda_lock_") else "container" assert f"process {{ withName: 'FASTQC' {{ {key} = '{value}' }} }}\n" in content - def test_generate_container_configs_new_module_injected(self) -> None: - """new_module_name/path are used when nextflow inspect doesn't yet know about the module.""" + def test_generate_container_configs_newly_installed_module(self) -> None: + """A newly installed module is picked up from disk by the filesystem scan.""" mods_install = ModuleInstall( self.pipeline_dir, prompt=False, force=False, sha="79b36b51048048374b642289bfe9e591ef56fe05" ) @@ -80,17 +53,7 @@ def test_generate_container_configs_new_module_injected(self) -> None: with open(self.pipeline_dir / "modules" / "nf-core" / "fastqc" / "meta.yml") as fh: fastqc_meta_yml = yaml.load(fh) - with ( - patch("nf_core.pipelines.containers_utils.check_nextflow_version", return_value=True), - patch( - "nf_core.pipelines.containers_utils.run_cmd", - return_value=(b'{"processes": []}', b""), - ), - ): - self.container_configs.generate_container_configs( - new_module_path=Path("modules/nf-core/fastqc"), - new_module_name="fastqc", - ) + self.container_configs.generate_container_configs() conf_dir = self.pipeline_dir / "conf" for p_name, (runtime, arch, protocol) in PLATFORMS.items(): @@ -101,21 +64,38 @@ def test_generate_container_configs_new_module_injected(self) -> None: assert f"process {{ withName: 'FASTQC' {{ {key} = '{value}' }} }}\n" in cfg_path.read_text() def test_generate_container_configs_removes_stale_entries(self) -> None: - """Stale config files are deleted when all their modules have been removed.""" + """Stale entries are not present after regeneration.""" conf_dir = self.pipeline_dir / "conf" stale_line = "process { withName: 'REMOVED_MODULE' { container = 'stale/image:latest' } }\n" for p_name in PLATFORMS: (conf_dir / f"containers_{p_name}.config").write_text(stale_line) - with ( - patch("nf_core.pipelines.containers_utils.check_nextflow_version", return_value=True), - patch( - "nf_core.pipelines.containers_utils.run_cmd", - return_value=(b'{"processes": []}', b""), - ), - ): - self.container_configs.generate_container_configs() + self.container_configs.generate_container_configs() for p_name in PLATFORMS: cfg_path = conf_dir / f"containers_{p_name}.config" - assert not cfg_path.exists(), f"{cfg_path.name} should be deleted when all modules are removed" + if cfg_path.exists(): + assert stale_line not in cfg_path.read_text(), ( + f"{cfg_path.name} still contains stale entry after regeneration" + ) + + def test_generate_container_configs_no_modules_dir(self) -> None: + """Returns an empty set immediately when there is no modules/ directory.""" + shutil.rmtree(self.pipeline_dir / "modules", ignore_errors=True) + result = self.container_configs.generate_container_configs() + assert result == set() + + def test_generate_container_configs_skips_meta_without_containers(self) -> None: + """meta.yml files without a containers key are silently ignored.""" + module_dir = self.pipeline_dir / "modules" / "local" / "fake" + module_dir.mkdir(parents=True, exist_ok=True) + (module_dir / "meta.yml").write_text("name: fake\ndescription: no containers here\n") + (module_dir / "main.nf").write_text('process FAKE {\n script:\n """\n echo hello\n """\n}\n') + + self.container_configs.generate_container_configs() + + conf_dir = self.pipeline_dir / "conf" + for p_name in PLATFORMS: + cfg_path = conf_dir / f"containers_{p_name}.config" + if cfg_path.exists(): + assert "FAKE" not in cfg_path.read_text(), f"{cfg_path.name} contains entry for FAKE module" From 9f53ebce4a788a8a62ada8146be63613e3dac88c Mon Sep 17 00:00:00 2001 From: Beatriz Vinhas Date: Thu, 21 May 2026 15:40:48 +0200 Subject: [PATCH 039/135] Fix linting for `modules.json` to add support for only installing subworkflows from a repository (#4287) Improve linting for `modules.json`: * Add support for repositories from where only `subworkflows` have been installed since this was currently not allowed. * Add explicit linting error message for when there are either no `modules` or `subworkflows` installed for a repository. * Add explicit linting error messages for repository links that don't start with "http" - this was an existing check that only returned a general error message. --- CHANGELOG.md | 1 + nf_core/pipelines/lint/modules_json.py | 52 +++++++++--------- tests/pipelines/lint/test_modules_json.py | 64 +++++++++++++++++++++++ 3 files changed, 91 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bfd0400a4..b1f0d17153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ ### Linting - accept `process_low_memory` as a standard module label ([#4264](https://github.com/nf-core/tools/pull/4264)) +- improve linting for `modules.json` to add support for only installing subworkflows from a repository and provide more explicit error messages ([#4287](https://github.com/nf-core/tools/pull/4287)) ### Modules diff --git a/nf_core/pipelines/lint/modules_json.py b/nf_core/pipelines/lint/modules_json.py index f7f5a077e7..8fa09b379b 100644 --- a/nf_core/pipelines/lint/modules_json.py +++ b/nf_core/pipelines/lint/modules_json.py @@ -25,32 +25,32 @@ def modules_json(self) -> dict[str, list[str]]: all_modules_passed = True for repo in modules_json_dict["repos"]: - # Check if the modules.json has been updated to keep the - if "modules" not in modules_json_dict["repos"][repo] or not repo.startswith("http"): - failed.append( - "Your `modules.json` file is outdated. " - "It will be automatically generated by running any module command." - ) - continue - - for install_dir in modules_json_dict["repos"][repo]["modules"]: - for module, module_entry in modules_json_dict["repos"][repo]["modules"][install_dir].items(): - if not Path(modules_dir, install_dir, module).exists(): - failed.append( - f"Entry for `{Path(modules_dir, install_dir, module)}` found in `modules.json` but module is not installed in " - "pipeline." - ) - all_modules_passed = False - if module_entry.get("branch") is None: - failed.append( - f"Entry for `{Path(modules_dir, install_dir, module)}` is missing branch information." - ) - if module_entry.get("git_sha") is None: - failed.append( - f"Entry for `{Path(modules_dir, install_dir, module)}` is missing version information." - ) - if all_modules_passed: - passed.append("Only installed modules found in `modules.json`") + if not repo.startswith("http"): + failed.append(f'Repository link for {repo} doesn\'t start with "http" in `modules.json`.') + + if "modules" in modules_json_dict["repos"][repo]: + # Module linting + for install_dir in modules_json_dict["repos"][repo]["modules"]: + for module, module_entry in modules_json_dict["repos"][repo]["modules"][install_dir].items(): + if not Path(modules_dir, install_dir, module).exists(): + failed.append( + f"Entry for `{Path(modules_dir, install_dir, module)}` found in `modules.json` but module is not installed in " + "pipeline." + ) + all_modules_passed = False + if module_entry.get("branch") is None: + failed.append( + f"Entry for `{Path(modules_dir, install_dir, module)}` is missing branch information." + ) + if module_entry.get("git_sha") is None: + failed.append( + f"Entry for `{Path(modules_dir, install_dir, module)}` is missing version information." + ) + if all_modules_passed: + passed.append("Only installed modules found in `modules.json`") + + if not any(component in modules_json_dict["repos"][repo] for component in ["modules", "subworkflows"]): + failed.append(f"No modules or subworkflows installed for {repo} in `modules.json`.") else: warned.append("Could not open `modules.json` file.") diff --git a/tests/pipelines/lint/test_modules_json.py b/tests/pipelines/lint/test_modules_json.py index 0d8333d9a2..6e72930009 100644 --- a/tests/pipelines/lint/test_modules_json.py +++ b/tests/pipelines/lint/test_modules_json.py @@ -1,10 +1,74 @@ +import json + +from nf_core.modules.modules_json import ( + ModulesJson, + ModulesJsonType, +) + from ..test_lint import TestLint class TestLintModulesJson(TestLint): + def setUp(self) -> None: + super().setUp() + self._modules_json_object: ModulesJson = ModulesJson(self.pipeline_dir) + self._modules_json_object.load() + self.modules_json_path = self._modules_json_object.modules_json_path + assert self._modules_json_object.modules_json is not None + self.modules_json: ModulesJsonType = self._modules_json_object.modules_json + + def _update_modules_json(self, new_modules_json) -> None: + # Update modules_json so that it is concordant at all levels of the class + self.modules_json = new_modules_json + self._modules_json_object.modules_json = new_modules_json + with open(self.modules_json_path, "w") as modules_json_file: + json.dump(new_modules_json, modules_json_file) + def test_modules_json_pass(self): self.lint_obj._load() results = self.lint_obj.modules_json() assert len(results.get("warned", [])) == 0 assert len(results.get("failed", [])) == 0 assert len(results.get("passed", [])) > 0 + + def test_modules_json_with_repo_not_starting_with_http_fail(self): + # Change the link of the first repo in modules_json to not start with "http" + new_modules_json = self.modules_json + first_repo = next(iter(new_modules_json["repos"])) + new_modules_json["repos"]["incorrect_repo_link"] = new_modules_json["repos"].pop(first_repo) + + self._update_modules_json(new_modules_json) + + # Check linting results + results = self.lint_obj.modules_json() + assert len(results.get("warned", [])) == 0 + assert len(results.get("failed", [])) == 1 + assert len(results.get("passed", [])) == 1 # The repository still contains only installed modules + + def test_modules_json_with_only_subworkflow_entries(self): + # Keep only "subworkflows" in the first repo in modules_json + new_modules_json = self.modules_json + first_repo = next(iter(new_modules_json["repos"])) + new_modules_json["repos"][first_repo] = {"subworkflows": new_modules_json["repos"][first_repo]["subworkflows"]} + + self._update_modules_json(new_modules_json) + + # Check linting results + results = self.lint_obj.modules_json() + assert len(results.get("warned", [])) == 0 + assert len(results.get("failed", [])) == 0 + assert len(results.get("passed", [])) == 0 # There is no subworkflow linting so no "passed" is returned + + def test_modules_json_with_repo_with_no_modules_or_subworkflows_fail(self): + # Change the first repo in modules_json to have no modules or subworkflows + new_modules_json = self.modules_json + first_repo = next(iter(new_modules_json["repos"])) + new_modules_json["repos"][first_repo] = {} + + self._update_modules_json(new_modules_json) + + # Check linting results + results = self.lint_obj.modules_json() + assert len(results.get("warned", [])) == 0 + assert len(results.get("failed", [])) == 1 + assert len(results.get("passed", [])) == 0 From 83bc6fb02dd4c37251af15e839dd4f84e23dc687 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 13:53:59 +0000 Subject: [PATCH 040/135] Update j178/prek-action digest to bdca6f1 (#4284) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/changelog.yml | 2 +- .github/workflows/clean-up.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/lint-code.yml | 2 +- .github/workflows/pytest.yml | 2 +- nf_core/pipeline-template/.github/workflows/clean-up.yml | 2 +- nf_core/pipeline-template/.github/workflows/fix_linting.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 39beaade4c..1bc939944b 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -65,7 +65,7 @@ jobs: python-version: "3.14" - name: Run pre-commit rules with prek - uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2 + uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 continue-on-error: true with: extra-args: --config .pre-commit-config.yaml --all-files diff --git a/.github/workflows/clean-up.yml b/.github/workflows/clean-up.yml index db2903eb28..b50679cf05 100644 --- a/.github/workflows/clean-up.yml +++ b/.github/workflows/clean-up.yml @@ -10,7 +10,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10 + - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10 with: stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment if it is still useful." diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 8178e8a2ab..648eeec9d7 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -33,7 +33,7 @@ jobs: # Install and run prek - name: Run prek id: prek - uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2 + uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 with: extra-args: --config .pre-commit-config.yaml --all-files continue-on-error: true diff --git a/.github/workflows/lint-code.yml b/.github/workflows/lint-code.yml index 11d2c5fd6e..fa39143cc0 100644 --- a/.github/workflows/lint-code.yml +++ b/.github/workflows/lint-code.yml @@ -22,6 +22,6 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Run prek - uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2 + uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 with: extra-args: --config .pre-commit-config.yaml --all-files diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 26aa1cc689..25e6566f8c 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -128,7 +128,7 @@ jobs: - name: Upload coverage to Codecov if: always() - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6 + uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6 with: files: ./coverage.xml flags: python-${{ matrix.python-version }} diff --git a/nf_core/pipeline-template/.github/workflows/clean-up.yml b/nf_core/pipeline-template/.github/workflows/clean-up.yml index dd71eaf55f..0228336d1b 100644 --- a/nf_core/pipeline-template/.github/workflows/clean-up.yml +++ b/nf_core/pipeline-template/.github/workflows/clean-up.yml @@ -10,7 +10,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10 + - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10 with: stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment if it is still useful." diff --git a/nf_core/pipeline-template/.github/workflows/fix_linting.yml b/nf_core/pipeline-template/.github/workflows/fix_linting.yml index 383a24494c..122c2b32b9 100644 --- a/nf_core/pipeline-template/.github/workflows/fix_linting.yml +++ b/nf_core/pipeline-template/.github/workflows/fix_linting.yml @@ -37,7 +37,7 @@ jobs: # Install and run prek - name: Run prek id: prek - uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2 + uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 continue-on-error: true # indication that the linting has finished diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 8e5261f2fd..be4a85af1f 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -17,7 +17,7 @@ jobs: uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 - name: Run prek - uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2 + uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 nf-core: runs-on: ubuntu-latest From f2f69f46d14d29cbaa9361361516e53a498d51a1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 13:31:30 +0200 Subject: [PATCH 041/135] Update GitHub Actions (#4297) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/push_dockerhub.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/push_dockerhub.yml b/.github/workflows/push_dockerhub.yml index 23411d275c..57888c2e41 100644 --- a/.github/workflows/push_dockerhub.yml +++ b/.github/workflows/push_dockerhub.yml @@ -40,10 +40,10 @@ jobs: uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4 + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4 - name: Log in to Docker Hub - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASS }} From 1c0e1455cccb1fa15cfcd7fc9da7da610327025f Mon Sep 17 00:00:00 2001 From: Nicolas Vannieuwkerke Date: Wed, 27 May 2026 14:59:19 +0200 Subject: [PATCH 042/135] make params.genomes a map --- .../pipeline-template/conf/igenomes.config | 856 +++++++++--------- 1 file changed, 427 insertions(+), 429 deletions(-) diff --git a/nf_core/pipeline-template/conf/igenomes.config b/nf_core/pipeline-template/conf/igenomes.config index 3f11437759..b8c8154eed 100644 --- a/nf_core/pipeline-template/conf/igenomes.config +++ b/nf_core/pipeline-template/conf/igenomes.config @@ -8,433 +8,431 @@ ---------------------------------------------------------------------------------------- */ -params { +params.genomes = [ // illumina iGenomes reference file paths - genomes { - 'GRCh37' { - fasta = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/README.txt" - mito_name = "MT" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/GRCh37-blacklist.bed" - } - 'GRCh38' { - fasta = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/hg38-blacklist.bed" - } - 'CHM13' { - fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAIndex/" - bwamem2 = "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAmem2Index/" - gtf = "${params.igenomes_base}/Homo_sapiens/NCBI/CHM13/Annotation/Genes/genes.gtf" - gff = "ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/009/914/755/GCF_009914755.1_T2T-CHM13v2.0/GCF_009914755.1_T2T-CHM13v2.0_genomic.gff.gz" - mito_name = "chrM" - } - 'GRCm38' { - fasta = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/README.txt" - mito_name = "MT" - macs_gsize = "1.87e9" - blacklist = "${projectDir}/assets/blacklists/GRCm38-blacklist.bed" - } - 'TAIR10' { - fasta = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/README.txt" - mito_name = "Mt" - } - 'EB2' { - fasta = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/README.txt" - } - 'UMD3.1' { - fasta = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/README.txt" - mito_name = "MT" - } - 'WBcel235' { - fasta = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.bed" - mito_name = "MtDNA" - macs_gsize = "9e7" - } - 'CanFam3.1' { - fasta = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/README.txt" - mito_name = "MT" - } - 'GRCz10' { - fasta = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'BDGP6' { - fasta = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.bed" - mito_name = "M" - macs_gsize = "1.2e8" - } - 'EquCab2' { - fasta = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/README.txt" - mito_name = "MT" - } - 'EB1' { - fasta = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/README.txt" - } - 'Galgal4' { - fasta = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'Gm01' { - fasta = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/README.txt" - } - 'Mmul_1' { - fasta = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/README.txt" - mito_name = "MT" - } - 'IRGSP-1.0' { - fasta = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.bed" - mito_name = "Mt" - } - 'CHIMP2.1.4' { - fasta = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/README.txt" - mito_name = "MT" - } - 'Rnor_5.0' { - fasta = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'Rnor_6.0' { - fasta = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.bed" - mito_name = "MT" - } - 'R64-1-1' { - fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.bed" - mito_name = "MT" - macs_gsize = "1.2e7" - } - 'EF2' { - fasta = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/README.txt" - mito_name = "MT" - macs_gsize = "1.21e7" - } - 'Sbi1' { - fasta = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/README.txt" - } - 'Sscrofa10.2' { - fasta = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/README.txt" - mito_name = "MT" - } - 'AGPv3' { - fasta = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.bed" - mito_name = "Mt" - } - 'hg38' { - fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/hg38-blacklist.bed" - } - 'hg19' { - fasta = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "2.7e9" - blacklist = "${projectDir}/assets/blacklists/hg19-blacklist.bed" - } - 'mm10' { - fasta = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "1.87e9" - blacklist = "${projectDir}/assets/blacklists/mm10-blacklist.bed" - } - 'bosTau8' { - fasta = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.bed" - mito_name = "chrM" - } - 'ce10' { - fasta = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "9e7" - } - 'canFam3' { - fasta = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/README.txt" - mito_name = "chrM" - } - 'danRer10' { - fasta = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "1.37e9" - } - 'dm6' { - fasta = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.bed" - mito_name = "chrM" - macs_gsize = "1.2e8" - } - 'equCab2' { - fasta = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/README.txt" - mito_name = "chrM" - } - 'galGal4' { - fasta = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/README.txt" - mito_name = "chrM" - } - 'panTro4' { - fasta = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/README.txt" - mito_name = "chrM" - } - 'rn6' { - fasta = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.bed" - mito_name = "chrM" - } - 'sacCer3' { - fasta = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BismarkIndex/" - readme = "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Annotation/README.txt" - mito_name = "chrM" - macs_gsize = "1.2e7" - } - 'susScr3' { - fasta = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/WholeGenomeFasta/genome.fa" - bwa = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BWAIndex/version0.6.0/" - bowtie2 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/Bowtie2Index/" - star = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/STARIndex/" - bismark = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BismarkIndex/" - gtf = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.gtf" - bed12 = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.bed" - readme = "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/README.txt" - mito_name = "chrM" - } - } -} + 'GRCh37' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Homo_sapiens/Ensembl/GRCh37/Annotation/README.txt", + mito_name : "MT", + macs_gsize : "2.7e9", + blacklist : "${projectDir}/assets/blacklists/GRCh37-blacklist.bed", + ], + 'GRCh38' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Homo_sapiens/NCBI/GRCh38/Annotation/Genes/genes.bed", + mito_name : "chrM", + macs_gsize : "2.7e9", + blacklist : "${projectDir}/assets/blacklists/hg38-blacklist.bed", + ], + 'CHM13' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAIndex/", + bwamem2 : "${params.igenomes_base}/Homo_sapiens/UCSC/CHM13/Sequence/BWAmem2Index/", + gtf : "${params.igenomes_base}/Homo_sapiens/NCBI/CHM13/Annotation/Genes/genes.gtf", + gff : "ftp://ftp.ncbi.nlm.nih.gov/genomes/all/GCF/009/914/755/GCF_009914755.1_T2T-CHM13v2.0/GCF_009914755.1_T2T-CHM13v2.0_genomic.gff.gz", + mito_name : "chrM", + ], + 'GRCm38' : [ + fasta : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Mus_musculus/Ensembl/GRCm38/Annotation/README.txt", + mito_name : "MT", + macs_gsize : "1.87e9", + blacklist : "${projectDir}/assets/blacklists/GRCm38-blacklist.bed", + ], + 'TAIR10' : [ + fasta : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Arabidopsis_thaliana/Ensembl/TAIR10/Annotation/README.txt", + mito_name : "Mt", + ], + 'EB2' : [ + fasta : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Bacillus_subtilis_168/Ensembl/EB2/Annotation/README.txt", + ], + 'UMD3.1' : [ + fasta : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Bos_taurus/Ensembl/UMD3.1/Annotation/README.txt", + mito_name : "MT", + ], + 'WBcel235' : [ + fasta : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Caenorhabditis_elegans/Ensembl/WBcel235/Annotation/Genes/genes.bed", + mito_name : "MtDNA", + macs_gsize : "9e7", + ], + 'CanFam3.1' : [ + fasta : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Canis_familiaris/Ensembl/CanFam3.1/Annotation/README.txt", + mito_name : "MT", + ], + 'GRCz10' : [ + fasta : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Danio_rerio/Ensembl/GRCz10/Annotation/Genes/genes.bed", + mito_name : "MT", + ], + 'BDGP6' : [ + fasta : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Drosophila_melanogaster/Ensembl/BDGP6/Annotation/Genes/genes.bed", + mito_name : "M", + macs_gsize : "1.2e8", + ], + 'EquCab2' : [ + fasta : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Equus_caballus/Ensembl/EquCab2/Annotation/README.txt", + mito_name : "MT", + ], + 'EB1' : [ + fasta : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Escherichia_coli_K_12_DH10B/Ensembl/EB1/Annotation/README.txt", + ], + 'Galgal4' : [ + fasta : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Gallus_gallus/Ensembl/Galgal4/Annotation/Genes/genes.bed", + mito_name : "MT", + ], + 'Gm01' : [ + fasta : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Glycine_max/Ensembl/Gm01/Annotation/README.txt", + ], + 'Mmul_1' : [ + fasta : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Macaca_mulatta/Ensembl/Mmul_1/Annotation/README.txt", + mito_name : "MT", + ], + 'IRGSP-1.0' : [ + fasta : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Oryza_sativa_japonica/Ensembl/IRGSP-1.0/Annotation/Genes/genes.bed", + mito_name : "Mt", + ], + 'CHIMP2.1.4' : [ + fasta : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Pan_troglodytes/Ensembl/CHIMP2.1.4/Annotation/README.txt", + mito_name : "MT", + ], + 'Rnor_5.0' : [ + fasta : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_5.0/Annotation/Genes/genes.bed", + mito_name : "MT", + ], + 'Rnor_6.0' : [ + fasta : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Rattus_norvegicus/Ensembl/Rnor_6.0/Annotation/Genes/genes.bed", + mito_name : "MT", + ], + 'R64-1-1' : [ + fasta : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Saccharomyces_cerevisiae/Ensembl/R64-1-1/Annotation/Genes/genes.bed", + mito_name : "MT", + macs_gsize : "1.2e7", + ], + 'EF2' : [ + fasta : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Schizosaccharomyces_pombe/Ensembl/EF2/Annotation/README.txt", + mito_name : "MT", + macs_gsize : "1.21e7", + ], + 'Sbi1' : [ + fasta : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Sorghum_bicolor/Ensembl/Sbi1/Annotation/README.txt", + ], + 'Sscrofa10.2' : [ + fasta : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Sus_scrofa/Ensembl/Sscrofa10.2/Annotation/README.txt", + mito_name : "MT", + ], + 'AGPv3' : [ + fasta : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Zea_mays/Ensembl/AGPv3/Annotation/Genes/genes.bed", + mito_name : "Mt", + ], + 'hg38' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Homo_sapiens/UCSC/hg38/Annotation/Genes/genes.bed", + mito_name : "chrM", + macs_gsize : "2.7e9", + blacklist : "${projectDir}/assets/blacklists/hg38-blacklist.bed", + ], + 'hg19' : [ + fasta : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Homo_sapiens/UCSC/hg19/Annotation/README.txt", + mito_name : "chrM", + macs_gsize : "2.7e9", + blacklist : "${projectDir}/assets/blacklists/hg19-blacklist.bed", + ], + 'mm10' : [ + fasta : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Mus_musculus/UCSC/mm10/Annotation/README.txt", + mito_name : "chrM", + macs_gsize : "1.87e9", + blacklist : "${projectDir}/assets/blacklists/mm10-blacklist.bed", + ], + 'bosTau8' : [ + fasta : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Bos_taurus/UCSC/bosTau8/Annotation/Genes/genes.bed", + mito_name : "chrM", + ], + 'ce10' : [ + fasta : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Caenorhabditis_elegans/UCSC/ce10/Annotation/README.txt", + mito_name : "chrM", + macs_gsize : "9e7", + ], + 'canFam3' : [ + fasta : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Canis_familiaris/UCSC/canFam3/Annotation/README.txt", + mito_name : "chrM", + ], + 'danRer10' : [ + fasta : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Danio_rerio/UCSC/danRer10/Annotation/Genes/genes.bed", + mito_name : "chrM", + macs_gsize : "1.37e9", + ], + 'dm6' : [ + fasta : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Drosophila_melanogaster/UCSC/dm6/Annotation/Genes/genes.bed", + mito_name : "chrM", + macs_gsize : "1.2e8", + ], + 'equCab2' : [ + fasta : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Equus_caballus/UCSC/equCab2/Annotation/README.txt", + mito_name : "chrM", + ], + 'galGal4' : [ + fasta : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Gallus_gallus/UCSC/galGal4/Annotation/README.txt", + mito_name : "chrM", + ], + 'panTro4' : [ + fasta : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Pan_troglodytes/UCSC/panTro4/Annotation/README.txt", + mito_name : "chrM", + ], + 'rn6' : [ + fasta : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Rattus_norvegicus/UCSC/rn6/Annotation/Genes/genes.bed", + mito_name : "chrM", + ], + 'sacCer3' : [ + fasta : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Sequence/BismarkIndex/", + readme : "${params.igenomes_base}/Saccharomyces_cerevisiae/UCSC/sacCer3/Annotation/README.txt", + mito_name : "chrM", + macs_gsize : "1.2e7", + ], + 'susScr3' : [ + fasta : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/WholeGenomeFasta/genome.fa", + bwa : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BWAIndex/version0.6.0/", + bowtie2 : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/Bowtie2Index/", + star : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/STARIndex/", + bismark : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Sequence/BismarkIndex/", + gtf : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.gtf", + bed12 : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/Genes/genes.bed", + readme : "${params.igenomes_base}/Sus_scrofa/UCSC/susScr3/Annotation/README.txt", + mito_name : "chrM", + ], +] From 7889a794fa097bf2f909a0a6f4f153ec917662a0 Mon Sep 17 00:00:00 2001 From: Adrien Coulier Date: Thu, 28 May 2026 13:58:13 +0200 Subject: [PATCH 043/135] Fix deadlink --- nf_core/pipeline-template/docs/output.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipeline-template/docs/output.md b/nf_core/pipeline-template/docs/output.md index d9bc3a188f..d474a4702f 100644 --- a/nf_core/pipeline-template/docs/output.md +++ b/nf_core/pipeline-template/docs/output.md @@ -69,4 +69,4 @@ Results generated by MultiQC collate pipeline QC from supported tools e.g. FastQ -[Nextflow](https://www.nextflow.io/docs/latest/tracing.html) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline, and also provide you with other information such as launch commands, run times and resource usage. +[Nextflow](https://docs.seqera.io/platform-cloud/reports/overview) provides excellent functionality for generating various reports relevant to the running and execution of the pipeline. This will allow you to troubleshoot errors with the running of the pipeline, and also provide you with other information such as launch commands, run times and resource usage. From 48791b22be68a4cca22f7b35cc41af24b179fbb0 Mon Sep 17 00:00:00 2001 From: Adrien Coulier Date: Thu, 28 May 2026 14:04:50 +0200 Subject: [PATCH 044/135] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1f0d17153..d46348e2db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ ### Template - add `process_low_memory` resource label to `base.config` ([#4264](https://github.com/nf-core/tools/pull/4264)) +- fix dead link ([#4307](https://github.com/nf-core/tools/pull/4307)) #### Version updates From f35a62b4a4a7ca53df9a1ac2b6a9355e2e961960 Mon Sep 17 00:00:00 2001 From: Phil Ewels Date: Fri, 29 May 2026 10:39:40 +0200 Subject: [PATCH 045/135] Fix duplicate `-b` short flag in `pipelines sync` `nf-core pipelines sync` assigned `-b` to both `--from-branch` and `--blog-post`, which triggered a `UserWarning: The parameter -b is used more than once` and made the short flag ambiguous. Drop `-b` from `--blog-post` (now long-form only), keeping `-b` for `--from-branch` to match the `-b`/branch convention used elsewhere in the CLI. Co-Authored-By: Claude Opus 4.8 (1M context) --- nf_core/__main__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index f115bf2bfa..16495ae344 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -630,7 +630,7 @@ def rocrate( @click.option("-g", "--github-repository", type=str, help="GitHub PR: target repository.") @click.option("-u", "--username", type=str, help="GitHub PR: auth username.") @click.option("-t", "--template-yaml", help="Pass a YAML file to customize the template") -@click.option("-b", "--blog-post", type=str, help="Link to the blog post") +@click.option("--blog-post", type=str, help="Link to the blog post") @click.option("-n", "--no-prompts", is_flag=True, default=False, help="Run without prompting for user input") def command_pipelines_sync( ctx, From ec2071db1a81bd1cc043a20b0bd508660013a6bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 13:46:54 +0200 Subject: [PATCH 046/135] Update pre-commit hooks (#4298) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index aa21f91d43..9bd6c0ddb1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.12 + rev: v0.15.16 hooks: - id: ruff-check # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix @@ -33,7 +33,7 @@ repos: tests/pipelines/__snapshots__/.* )$ - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v2.0.0" + rev: "v2.1.0" hooks: - id: mypy args: [--ignore-missing-imports, --scripts-are-modules, -n4] @@ -45,7 +45,7 @@ repos: - types-setuptools - pydantic - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.11.8 + rev: 0.11.19 hooks: - id: uv-lock - repo: local From 66de9fd942b8440da61d95b362107316c01138f1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 12:09:21 +0000 Subject: [PATCH 047/135] Update GitHub Actions to v7 (#4316) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/pytest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 25e6566f8c..45ac6f8821 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -128,7 +128,7 @@ jobs: - name: Upload coverage to Codecov if: always() - uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7 with: files: ./coverage.xml flags: python-${{ matrix.python-version }} From e9626e8602b6494df7a092affb4d8ab39a58ce31 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jun 2026 14:33:45 +0200 Subject: [PATCH 048/135] Update docker/setup-qemu-action digest to 0611638 (#4306) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Matthias Hörtenhuber --- .github/workflows/changelog.yml | 2 +- .github/workflows/create-lint-wf.yml | 4 ++-- .github/workflows/create-test-lint-wf-template.yml | 6 +++--- .github/workflows/create-test-wf.yml | 4 ++-- .github/workflows/deploy-pypi.yml | 4 ++-- .github/workflows/fix-linting.yml | 2 +- .github/workflows/lint-code.yml | 2 +- .github/workflows/nextflow-source-test.yml | 6 +++--- .github/workflows/push_dockerhub.yml | 6 +++--- .github/workflows/pytest.yml | 6 +++--- .github/workflows/sync.yml | 6 +++--- .github/workflows/test_offline_configs.yml | 4 ++-- .github/workflows/update-template-snapshots.yml | 8 ++++---- .github/workflows/update-textual-snapshots.yml | 4 ++-- .../.github/workflows/download_pipeline.yml | 2 +- .../pipeline-template/.github/workflows/fix_linting.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 6 +++--- nf_core/pipeline-template/.github/workflows/nf-test.yml | 4 ++-- .../.github/workflows/template-version-comment.yml | 2 +- 19 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 1bc939944b..355e3fc9ff 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -18,7 +18,7 @@ jobs: reaction: "eyes" stable_branch: "dev" - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 56033d8eaa..33ab1652b3 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -42,7 +42,7 @@ jobs: export NXF_WORK=$(pwd) # Get the repo code - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out source-code repository # Set up nf-core/tools @@ -52,7 +52,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index 9bb608e97f..47048ba41d 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -32,7 +32,7 @@ jobs: all_features: ${{ steps.create_matrix.outputs.matrix }} steps: - name: checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Create Matrix id: create_matrix run: | @@ -56,7 +56,7 @@ jobs: steps: - name: Check out source-code repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Set up Python 3.14 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 @@ -64,7 +64,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index 879bd68849..667821f695 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -41,7 +41,7 @@ jobs: cd create-test-wf export NXF_WORK=$(pwd) - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out source-code repository - name: Set up Python 3.14 @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index cd2c7c78d8..0e76048c38 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out source-code repository - name: Set up Python 3.14 @@ -22,7 +22,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 648eeec9d7..285c517c4e 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -19,7 +19,7 @@ jobs: stable_branch: "dev" # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/.github/workflows/lint-code.yml b/.github/workflows/lint-code.yml index fa39143cc0..37f2e68d44 100644 --- a/.github/workflows/lint-code.yml +++ b/.github/workflows/lint-code.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Run prek uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index 92dd32a763..a02fae87db 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Check out Nextflow - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: repository: nextflow-io/nextflow path: nextflow @@ -38,7 +38,7 @@ jobs: chmod +x $HOME/.local/bin/nextflow nextflow -version - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out nf-core/tools with: ref: dev @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true diff --git a/.github/workflows/push_dockerhub.yml b/.github/workflows/push_dockerhub.yml index 57888c2e41..d63d071306 100644 --- a/.github/workflows/push_dockerhub.yml +++ b/.github/workflows/push_dockerhub.yml @@ -34,10 +34,10 @@ jobs: swap-storage: true - name: Check out code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Set up QEMU for multi-architecture build - uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4 + uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4 @@ -74,7 +74,7 @@ jobs: --push --no-cache . - name: Build and push nfcore/devcontainer image - uses: devcontainers/ci@b63b30de439b47a52267f241112c5b453b673db5 # v0.3 + uses: devcontainers/ci@513af61f4de4f75d37e4438f184ba4358f0fc1ca # v0.3 with: configFile: .devcontainer/build-devcontainer/devcontainer.json imageName: nfcore/devcontainer diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 45ac6f8821..1c6009cf00 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -40,7 +40,7 @@ jobs: name: Get test file matrix runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out source-code repository - name: List tests @@ -72,7 +72,7 @@ jobs: cd pytest export NXF_WORK=$(pwd) - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out source-code repository - name: Set up Python ${{ matrix.python-version }} @@ -82,7 +82,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index f239c2eafd..5d4ff98ba0 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -62,12 +62,12 @@ jobs: matrix: ${{fromJson(needs.get-pipelines.outputs.matrix)}} fail-fast: false steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out nf-core/tools with: ref: ${{ github.ref_name }} - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out nf-core/${{ matrix.pipeline }} with: repository: nf-core/${{ matrix.pipeline }} @@ -82,7 +82,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true diff --git a/.github/workflows/test_offline_configs.yml b/.github/workflows/test_offline_configs.yml index 250f456d2c..12634162e6 100644 --- a/.github/workflows/test_offline_configs.yml +++ b/.github/workflows/test_offline_configs.yml @@ -53,11 +53,11 @@ jobs: matrix: ${{fromJson(needs.get-pipelines.outputs.matrix)}} fail-fast: false steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out nf-core/tools with: ref: ${{ github.ref_name }} - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out nf-core/${{ matrix.pipeline }} with: repository: nf-core/${{ matrix.pipeline }} diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index 3edff55a0f..910e93785b 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -22,7 +22,7 @@ jobs: stable_branch: "dev" - name: checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Create Matrix id: create_matrix @@ -43,7 +43,7 @@ jobs: fail-fast: false steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} @@ -61,7 +61,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true @@ -145,7 +145,7 @@ jobs: runs-on: ubuntu-latest if: always() && needs.update-snapshots.result != 'skipped' steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index 07e172b45d..bbb7534ab4 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -17,7 +17,7 @@ jobs: stable_branch: "dev" # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} @@ -42,7 +42,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 with: enable-cache: true diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index 65354ea1d9..b2dad9611b 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -39,7 +39,7 @@ jobs: needs: configure steps: - name: Check out pipeline code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 diff --git a/nf_core/pipeline-template/.github/workflows/fix_linting.yml b/nf_core/pipeline-template/.github/workflows/fix_linting.yml index 122c2b32b9..17314baca5 100644 --- a/nf_core/pipeline-template/.github/workflows/fix_linting.yml +++ b/nf_core/pipeline-template/.github/workflows/fix_linting.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index be4a85af1f..05f710dce7 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -11,7 +11,7 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 @@ -34,7 +34,7 @@ jobs: architecture: "x64" - name: Setup uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 - name: read .nf-core.yml uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 diff --git a/nf_core/pipeline-template/.github/workflows/nf-test.yml b/nf_core/pipeline-template/.github/workflows/nf-test.yml index a75dd68913..672c1ad17f 100644 --- a/nf_core/pipeline-template/.github/workflows/nf-test.yml +++ b/nf_core/pipeline-template/.github/workflows/nf-test.yml @@ -41,7 +41,7 @@ jobs: rm -rf ./* || true rm -rf ./.??* || true ls -la ./ - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: fetch-depth: 0 @@ -87,7 +87,7 @@ jobs: TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: fetch-depth: 0 diff --git a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml index cca374be84..a3333571e1 100644 --- a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml +++ b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 with: ref: ${{ github.event.pull_request.head.sha }} From 78a0ae5509b4a8c8dd2ee83b852ae39a6f27c998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Mon, 8 Jun 2026 15:34:05 +0200 Subject: [PATCH 049/135] parse container registries from `.nf-core.yml` (#4282) Co-authored-by: JulianFlesch --- docs/api/_src/api/nf_core_yml.md | 67 +++++++++++++ docs/api/_src/index.md | 1 + nf_core/__main__.py | 12 +-- nf_core/commands_modules.py | 3 +- nf_core/commands_subworkflows.py | 3 +- nf_core/components/lint/__init__.py | 13 ++- nf_core/modules/lint/__init__.py | 12 +-- nf_core/modules/lint/main_nf.py | 31 +++--- nf_core/pipelines/lint/nfcore_yml.py | 4 +- nf_core/subworkflows/lint/__init__.py | 14 ++- nf_core/utils.py | 6 +- tests/modules/lint/test_main_nf.py | 124 ++++++++++++++++++++++++ tests/modules/lint/test_patch.py | 2 +- tests/modules/test_patch.py | 31 +++--- tests/pipelines/lint/test_nfcore_yml.py | 9 ++ 15 files changed, 267 insertions(+), 65 deletions(-) create mode 100644 docs/api/_src/api/nf_core_yml.md diff --git a/docs/api/_src/api/nf_core_yml.md b/docs/api/_src/api/nf_core_yml.md new file mode 100644 index 0000000000..d264948f4b --- /dev/null +++ b/docs/api/_src/api/nf_core_yml.md @@ -0,0 +1,67 @@ +# .nf-core.yml configuration + +The `.nf-core.yml` file at the root of any nf-core repository controls how nf-core +tools behaves for that repository. It is read by `load_tools_config()` and validated +against the `NFCoreYamlConfig` Pydantic model. + +## Minimal examples + +Pipeline repository: + +```yaml +repository_type: pipeline +nf_core_version: "4.0.2" +``` + +Modules repository: + +```yaml +repository_type: modules +nf_core_version: "4.0.2" +container-registry: + - community.wave.seqera.io/library/ +``` + +## Schema + +### Top-level `.nf-core.yml` schema (`NFCoreYamlConfig`) + +```{eval-rst} +.. autopydantic_model:: nf_core.utils.NFCoreYamlConfig + :members: + :undoc-members: + :show-inheritance: + :model-show-json: false + :model-show-config-summary: false + :model-show-validator-members: false + :model-show-field-summary: true + :field-show-alias: true +``` + +### `lint` block (`NFCoreYamlLintConfig`) + +```{eval-rst} +.. autopydantic_model:: nf_core.utils.NFCoreYamlLintConfig + :members: + :undoc-members: + :show-inheritance: + :model-show-json: false + :model-show-config-summary: false + :model-show-validator-members: false + :model-show-field-summary: true + :field-show-alias: true +``` + +### `template` block (`NFCoreTemplateConfig`) + +```{eval-rst} +.. autopydantic_model:: nf_core.utils.NFCoreTemplateConfig + :members: + :undoc-members: + :show-inheritance: + :model-show-json: false + :model-show-config-summary: false + :model-show-validator-members: false + :model-show-field-summary: true + :field-show-alias: true +``` diff --git a/docs/api/_src/index.md b/docs/api/_src/index.md index e752b3b28b..8ebd988b1b 100644 --- a/docs/api/_src/index.md +++ b/docs/api/_src/index.md @@ -8,3 +8,4 @@ This API documentation is for the [`nf-core/tools`](https://github.com/nf-core/t - [Module code lint tests](./module_lint_tests/environment_yml.md) (run by `nf-core modules lint`) - [Subworkflow code lint tests](./subworkflow_lint_tests/main_nf.md) (run by `nf-core subworkflows lint`) - [nf-core/tools Python package API reference](./api/utils.md) +- [`.nf-core.yml` configuration reference](./api/nf_core_yml.md) diff --git a/nf_core/__main__.py b/nf_core/__main__.py index afb652ca75..5d232530a9 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -1325,8 +1325,8 @@ def command_modules_test(ctx, tool, directory, no_prompts, update, once, profile "--registry", type=str, metavar="", - default=None, - help="Registry to use for containers. If not specified it will use docker.registry value in the nextflow.config file", + default="quay.io,community.wave.seqera.io/library", + help="Comma-separated list of allowed container registry prefixes.", ) @click.option( "-k", @@ -1369,7 +1369,7 @@ def command_modules_lint( ctx, tool, directory, - registry, + tuple(registry.split(",")), key, all_modules, fail_warned, @@ -1617,8 +1617,8 @@ def command_subworkflows_list_local(ctx, keywords, json, directory): # pylint: "--registry", type=str, metavar="", - default=None, - help="Registry to use for containers. If not specified it will use docker.registry value in the nextflow.config file", + default="quay.io,community.wave.seqera.io/library", + help="Comma-separated list of allowed container registry prefixes.", ) @click.option( "-k", @@ -1656,7 +1656,7 @@ def command_subworkflows_lint( ctx, subworkflow, directory, - registry, + tuple(registry.split(",")), key, all_subworkflows, fail_warned, diff --git a/nf_core/commands_modules.py b/nf_core/commands_modules.py index 525121726b..f4e48e0e4c 100644 --- a/nf_core/commands_modules.py +++ b/nf_core/commands_modules.py @@ -256,7 +256,7 @@ def modules_lint( directory, fail_warned=fail_warned, fix=fix, - registry=ctx.params["registry"], + registry=registry, remote_url=ctx.obj["modules_repo_url"], branch=ctx.obj["modules_repo_branch"], no_pull=ctx.obj["modules_repo_no_pull"], @@ -264,7 +264,6 @@ def modules_lint( ) module_lint.lint( module=tool, - registry=registry, key=key, all_modules=all_modules, print_results=True, diff --git a/nf_core/commands_subworkflows.py b/nf_core/commands_subworkflows.py index 4ac3c321a9..f87fc9b5c2 100644 --- a/nf_core/commands_subworkflows.py +++ b/nf_core/commands_subworkflows.py @@ -122,7 +122,7 @@ def subworkflows_lint( directory, fail_warned=fail_warned, fix=fix, - registry=ctx.params["registry"], + registry=registry, remote_url=ctx.obj["modules_repo_url"], branch=ctx.obj["modules_repo_branch"], no_pull=ctx.obj["modules_repo_no_pull"], @@ -130,7 +130,6 @@ def subworkflows_lint( ) subworkflow_lint.lint( subworkflow=subworkflow, - registry=registry, key=key, all_subworkflows=all_subworkflows, print_results=True, diff --git a/nf_core/components/lint/__init__.py b/nf_core/components/lint/__init__.py index efcdc11d90..7b28ddef0b 100644 --- a/nf_core/components/lint/__init__.py +++ b/nf_core/components/lint/__init__.py @@ -62,7 +62,7 @@ def __init__( remote_url: str | None = None, branch: str | None = None, no_pull: bool = False, - registry: str | None = None, + registry: tuple[str, ...] = ("quay.io", "community.wave.seqera.io/library"), hide_progress: bool = False, ): super().__init__( @@ -156,12 +156,11 @@ def __init__( def __repr__(self) -> str: return f"ComponentLint({self.component_type}, {self.directory})" - def _set_registry(self, registry) -> None: - if registry is None: - self.registry = self.config.get("docker.registry", "quay.io") - else: - self.registry = registry - log.debug(f"Registry set to {self.registry}") + def _set_registry(self, registry: tuple[str, ...]) -> None: + _, tools_config = nf_core.utils.load_tools_config(self.directory) + user_registries: list[str] = (tools_config.container_registry or []) if tools_config else [] + self.registry: tuple[str, ...] = (*registry, *user_registries) + log.debug(f"Registries set to {self.registry}") @property def local_module_exclude_tests(self): diff --git a/nf_core/modules/lint/__init__.py b/nf_core/modules/lint/__init__.py index f2472db0d3..417ff7f17e 100644 --- a/nf_core/modules/lint/__init__.py +++ b/nf_core/modules/lint/__init__.py @@ -69,7 +69,7 @@ def __init__( remote_url: str | None = None, branch: str | None = None, no_pull: bool = False, - registry: str | None = None, + registry: tuple[str, ...] = ("quay.io", "community.wave.seqera.io/library"), hide_progress: bool = False, ): super().__init__( @@ -88,7 +88,6 @@ def __init__( def lint( self, module=None, - registry="quay.io", key=(), all_modules=False, print_results=True, @@ -173,25 +172,22 @@ def lint( # Lint local modules if local and len(local_modules) > 0: - self.lint_modules(local_modules, registry=registry, local=True, fix_version=fix_version) + self.lint_modules(local_modules, local=True, fix_version=fix_version) # Lint nf-core modules if not local and len(remote_modules) > 0: - self.lint_modules(remote_modules, registry=registry, local=False, fix_version=fix_version) + self.lint_modules(remote_modules, local=False, fix_version=fix_version) if print_results: self._print_results(show_passed=show_passed, sort_by=sort_by, plain_text=plain_text) self.print_summary(plain_text=plain_text) - def lint_modules( - self, modules: list[NFCoreComponent], registry: str = "quay.io", local: bool = False, fix_version: bool = False - ) -> None: + def lint_modules(self, modules: list[NFCoreComponent], local: bool = False, fix_version: bool = False) -> None: """ Lint a list of modules Args: modules ([NFCoreComponent]): A list of module objects - registry (str): The container registry to use. Should be quay.io in most situations. local (boolean): Whether the list consist of local or nf-core modules fix_version (boolean): Fix the module version if a newer version is available """ diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index b589bc3f0c..0b8df9c046 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -20,7 +20,7 @@ def main_nf( - module_lint_object, module: NFCoreComponent, fix_version: bool, registry: str, progress_bar: Progress + module_lint_object, module: NFCoreComponent, fix_version: bool, registry: tuple[str, ...], progress_bar: Progress ) -> tuple[list[str], list[str]]: """Lint a ``main.nf`` module file @@ -359,15 +359,17 @@ def check_when_section(self, lines): self.passed.append(("main_nf", "when_condition", "when: condition is unchanged", self.main_nf)) -def check_process_section(self, lines, registry, fix_version, progress_bar): +def check_process_section( + self, lines: list[str], registry: tuple[str, ...], fix_version: bool, progress_bar: Progress | None +): """Lint the section of a module between the process definition and the 'input:' definition Specifically checks for correct software versions and containers Args: - lines (List[str]): Content of process. - registry (str): Base Docker registry for containers. Typically quay.io. + lines (list[str]): Content of process. + registry (tuple[str, ...]): Allowed container registry prefixes. fix_version (bool): Fix software version progress_bar (ProgressBar): Progress bar to update. @@ -384,6 +386,7 @@ def check_process_section(self, lines, registry, fix_version, progress_bar): singularity_tag = None docker_tag = None bioconda_packages = [] + allowed_registries = registry # Process name should be all capital letters if all(x.upper() for x in self.process_name): @@ -450,7 +453,7 @@ def check_process_section(self, lines, registry, fix_version, progress_bar): else: self.failed.append(("main_nf", "docker_tag", "Unable to parse docker tag", self.main_nf)) docker_tag = None - if line.startswith((registry, "community.wave.seqera.io/library/")): + if line.startswith(allowed_registries): l_stripped = re.sub(r"\W+$", "", line) self.passed.append( ( @@ -465,15 +468,11 @@ def check_process_section(self, lines, registry, fix_version, progress_bar): ( "main_nf", "container_links", - "Container prefix is not correct. Please add the registry prefix (e.g. 'quay.io/')", + f"Container prefix is not correct. Please add one of the allowed registry prefixes: {', '.join(f'{r}' for r in allowed_registries)}", self.main_nf, ) ) - # Guess if container name is simple one (e.g. nfcore/ubuntu:20.04) - # If so, add quay.io as default container prefix - if line.count("/") == 1 and line.count(":") == 1: - line = "/".join([registry, line]).replace("//", "/") url = urlparse(line.split("'")[0]) if line.startswith("container") or _container_type(line) == "docker" or _container_type(line) == "singularity": @@ -564,7 +563,10 @@ def check_process_section(self, lines, registry, fix_version, progress_bar): log.debug(f"Unable to update package {package} due to error: {e}") else: if fixed: - progress_bar.print(f"[blue]INFO[/blue]\t Updating package '{package}' {ver} -> {last_ver}") + if progress_bar is not None: + progress_bar.print( + f"[blue]INFO[/blue]\t Updating package '{package}' {ver} -> {last_ver}" + ) log.debug(f"Updating package {package} {ver} -> {last_ver}") self.passed.append( ( @@ -575,9 +577,10 @@ def check_process_section(self, lines, registry, fix_version, progress_bar): ) ) else: - progress_bar.print( - f"[blue]INFO[/blue]\t Tried to update package. Unable to update package '{package}' {ver} -> {last_ver}" - ) + if progress_bar is not None: + progress_bar.print( + f"[blue]INFO[/blue]\t Tried to update package. Unable to update package '{package}' {ver} -> {last_ver}" + ) log.debug(f"Unable to update package {package} {ver} -> {last_ver}") self.warned.append( ( diff --git a/nf_core/pipelines/lint/nfcore_yml.py b/nf_core/pipelines/lint/nfcore_yml.py index f202adfd96..ff28a77129 100644 --- a/nf_core/pipelines/lint/nfcore_yml.py +++ b/nf_core/pipelines/lint/nfcore_yml.py @@ -12,11 +12,11 @@ def nfcore_yml(self) -> dict[str, list[str]]: The ``.nf-core.yml`` contains metadata for nf-core tools to correctly apply its features. - * repository type: + * ``repository_type``: Check that the repository type is set. - * nf core version: + * ``nf_core_version``: Check if the nf-core version is set to the latest version. diff --git a/nf_core/subworkflows/lint/__init__.py b/nf_core/subworkflows/lint/__init__.py index 7d5fbccdae..4cc4f774c2 100644 --- a/nf_core/subworkflows/lint/__init__.py +++ b/nf_core/subworkflows/lint/__init__.py @@ -51,7 +51,7 @@ def __init__( remote_url=None, branch=None, no_pull=False, - registry=None, + registry: tuple[str, ...] = ("quay.io", "community.wave.seqera.io/library"), hide_progress=False, ): super().__init__( @@ -69,7 +69,6 @@ def __init__( def lint( self, subworkflow=None, - registry="quay.io", key=(), all_subworkflows=False, print_results=True, @@ -152,23 +151,22 @@ def lint( # Lint local subworkflows if local and len(local_subworkflows) > 0: - self.lint_subworkflows(local_subworkflows, registry=registry, local=True) + self.lint_subworkflows(local_subworkflows, local=True) # Lint nf-core subworkflows if not local and len(remote_subworkflows) > 0: - self.lint_subworkflows(remote_subworkflows, registry=registry, local=False) + self.lint_subworkflows(remote_subworkflows, local=False) if print_results: self._print_results(show_passed=show_passed, sort_by=sort_by, plain_text=plain_text) self.print_summary(plain_text=plain_text) - def lint_subworkflows(self, subworkflows, registry="quay.io", local=False): + def lint_subworkflows(self, subworkflows, local=False): """ Lint a list of subworkflows Args: subworkflows ([NFCoreComponent]): A list of subworkflow objects - registry (str): The container registry to use. Should be quay.io in most situations. local (boolean): Whether the list consist of local or nf-core subworkflows """ # TODO: consider unifying modules and subworkflows lint_subworkflows() function and add it to the ComponentLint class @@ -189,9 +187,9 @@ def lint_subworkflows(self, subworkflows, registry="quay.io", local=False): for swf in subworkflows: progress_bar.update(lint_progress, advance=1, test_name=swf.component_name) - self.lint_subworkflow(swf, progress_bar, registry=registry, local=local) + self.lint_subworkflow(swf, progress_bar, local=local) - def lint_subworkflow(self, swf, progress_bar, registry, local=False): + def lint_subworkflow(self, swf, progress_bar, local=False): """ Perform linting on one subworkflow diff --git a/nf_core/utils.py b/nf_core/utils.py index 483d1b799b..b6973c8ca4 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -33,7 +33,7 @@ import rich.markup import yaml from packaging.version import Version -from pydantic import BaseModel, ValidationError, field_validator +from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator from rich.live import Live from rich.spinner import Spinner @@ -1400,6 +1400,8 @@ def __setitem__(self, item: str, value: Any) -> None: class NFCoreYamlConfig(BaseModel): """.nf-core.yml configuration file schema""" + model_config = ConfigDict(populate_by_name=True) + repository_type: Literal["pipeline", "modules"] | None = None """ Type of repository """ nf_core_version: str | None = None @@ -1414,6 +1416,8 @@ class NFCoreYamlConfig(BaseModel): """ Disable bumping of the version for a module/subworkflow (when repository_type is modules). See https://nf-co.re/docs/nf-core-tools/modules/bump-versions for more information. """ update: dict[str, str | bool | dict[str, str | dict[str, str | bool]]] | None = None """ Disable updating specific modules/subworkflows (when repository_type is pipeline). See https://nf-co.re/docs/nf-core-tools/modules/update for more information. """ + container_registry: list[str] | None = Field(default=None, alias="container-registry") + """ Additional container registry prefixes allowed when linting container directives. """ def __getitem__(self, item: str) -> Any: return getattr(self, item) diff --git a/tests/modules/lint/test_main_nf.py b/tests/modules/lint/test_main_nf.py index f6c3848f71..1eddede4d9 100644 --- a/tests/modules/lint/test_main_nf.py +++ b/tests/modules/lint/test_main_nf.py @@ -1,3 +1,6 @@ +from pathlib import Path +from unittest.mock import MagicMock, patch + import pytest import nf_core.modules.lint @@ -6,6 +9,7 @@ _parse_output_topics, check_container_link_line, check_process_labels, + check_process_section, check_script_section, ) @@ -101,6 +105,64 @@ def test_container_links(content, passed, warned, failed): assert len(mock_lint.failed) == failed +@pytest.mark.parametrize( + "container_line,additional_registries,should_pass", + [ + # Known additional registry passes when listed + ( + "container 'community.wave.seqera.io/library/samtools:1.17--h87f3376_0'", + ["community.wave.seqera.io/library/"], + True, + ), + # Same registry fails when not in additional_registries + ( + "container 'community.wave.seqera.io/library/samtools:1.17--h87f3376_0'", + [], + False, + ), + # Default registry still passes when additional_registries is populated + ( + "container 'quay.io/biocontainers/samtools:1.17--h87f3376_0'", + ["community.wave.seqera.io/library/"], + True, + ), + # Multiple additional registries: second one matches + ( + "container 'ghcr.io/org/tool:1.0--abc123'", + ["community.wave.seqera.io/library/", "ghcr.io/"], + True, + ), + ], +) +def test_check_process_section_additional_registries(container_line, additional_registries, should_pass, tmp_path): + """Test that container_links passes/fails based on additional_registries from .nf-core.yml.""" + mock_lint = MockModuleLint() + mock_lint.process_name = "TOOL_SUBTOOL" + mock_lint.component_dir = tmp_path + + with patch("requests.head") as mock_head: + mock_head.return_value = MagicMock(status_code=200) + check_process_section( + mock_lint, + [container_line], + ("quay.io", *additional_registries), + False, + None, + ) + + prefix_passed = any(r[1] == "container_links" and "Container prefix is correct" in r[2] for r in mock_lint.passed) + prefix_failed = any( + r[1] == "container_links" and "Container prefix is not correct" in r[2] for r in mock_lint.failed + ) + + if should_pass: + assert prefix_passed, f"Expected container prefix to pass; passed={mock_lint.passed}, failed={mock_lint.failed}" + assert not prefix_failed, f"Container prefix should not fail; failed={mock_lint.failed}" + else: + assert prefix_failed, f"Expected container prefix to fail; passed={mock_lint.passed}, failed={mock_lint.failed}" + assert not prefix_passed, f"Container prefix should not pass; passed={mock_lint.passed}" + + class TestMainNfLinting(TestModules): """ Test main.nf linting functionality. @@ -140,6 +202,68 @@ def test_main_nf_lint_with_alternative_registry(self): assert len(module_lint.failed) == 0, f"Linting failed with {[x.__dict__ for x in module_lint.failed]}" assert len(module_lint.passed) > 0 + def test_additional_registry_from_nf_core_yml_passes_container_link(self): + """Test that a container using a registry listed in .nf-core.yml container-registry passes linting. + + Creates a local module whose container URL uses a custom registry (myreg.io/library/). + When that registry is listed under ``container-registry`` in ``.nf-core.yml``, the + ``container_links`` check must pass. Without it, the same container must produce a + ``container_links`` warning (local-module failures are demoted to warnings). + """ + local_mod_dir = Path(self.pipeline_dir) / "modules" / "local" / "mock_tool" + local_mod_dir.mkdir(parents=True, exist_ok=True) + (local_mod_dir / "main.nf").write_text( + "process MOCK_TOOL {\n" + " container 'myreg.io/library/tool:1.0--abc123'\n" + " input:\n" + " val(x)\n" + " output:\n" + " path('out.txt'), emit: out\n" + " script:\n" + " 'echo hello > out.txt'\n" + "}\n" + ) + + nf_core_yml_path = Path(self.pipeline_dir) / ".nf-core.yml" + from ruamel.yaml import YAML + + yaml_parser = YAML() + nf_core_yml = yaml_parser.load(nf_core_yml_path) + + # --- positive: registry listed in .nf-core.yml --- + nf_core_yml["container-registry"] = ["myreg.io/library/"] + yaml_parser.dump(nf_core_yml, nf_core_yml_path) + + with patch("requests.head") as mock_head: + mock_head.return_value = MagicMock(status_code=200) + module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir) + module_lint.lint(local=True, print_results=False) + + container_link_warns = [ + r for r in module_lint.warned if r.lint_test == "container_links" and "mock_tool" in r.component_name + ] + assert not any("Container prefix is not correct" in r.message for r in container_link_warns), ( + f"Expected no container prefix failure for myreg.io when listed in .nf-core.yml; " + f"warned={[r.message for r in container_link_warns]}" + ) + + # --- negative: same container fails when registry is absent --- + del nf_core_yml["container-registry"] + yaml_parser.dump(nf_core_yml, nf_core_yml_path) + + with patch("requests.head") as mock_head: + mock_head.return_value = MagicMock(status_code=200) + module_lint2 = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir) + module_lint2.lint(local=True, print_results=False) + + container_link_warns2 = [ + r for r in module_lint2.warned if r.lint_test == "container_links" and "mock_tool" in r.component_name + ] + assert any("Container prefix is not correct" in r.message for r in container_link_warns2), ( + f"Expected container prefix failure for myreg.io when not in .nf-core.yml; " + f"warned={[r.message for r in container_link_warns2]}" + ) + def test_topics_and_emits_version_check(self): """Test that main_nf version emit and topics check works correctly""" diff --git a/tests/modules/lint/test_patch.py b/tests/modules/lint/test_patch.py index e42b0b84a6..2c93f70b24 100644 --- a/tests/modules/lint/test_patch.py +++ b/tests/modules/lint/test_patch.py @@ -55,6 +55,6 @@ def test_modules_lint_patched_modules(self): all_modules=True, ) - assert len(module_lint.failed) == 3, f"Linting failed with {[x.__dict__ for x in module_lint.failed]}" + assert len(module_lint.failed) == 1, f"Linting failed with {[x.__dict__ for x in module_lint.failed]}" assert len(module_lint.passed) > 0 assert len(module_lint.warned) >= 0 diff --git a/tests/modules/test_patch.py b/tests/modules/test_patch.py index a77701b8ca..9f1e9bff71 100644 --- a/tests/modules/test_patch.py +++ b/tests/modules/test_patch.py @@ -6,6 +6,7 @@ import nf_core.components.components_command import nf_core.components.patch +import nf_core.modules.install import nf_core.modules.modules_json import nf_core.modules.patch import nf_core.modules.update @@ -20,10 +21,10 @@ testing if the update commands works correctly with patch files """ -ORG_SHA = "3dc7c14d29af40f1a0871a675364e437559d97a8" -CORRECT_SHA = "63e780200600e340365b669f9c673b670764c569" -SUCCEED_SHA = "0d0515c3f11266e1314e129bec3e308f804c8dc7" -FAIL_SHA = "cb64a5c1ef85619b89ab99dec2e9097fe84e1dc8" +ORG_SHA = "262178fbd015cd9be248630eec267f27e6048b03" +CORRECT_SHA = "262178fbd015cd9be248630eec267f27e6048b03" +SUCCEED_SHA = "b300b7e53f080a174a717d8e394cca1a82a5ba54" +FAIL_SHA = "04d59325d44d309fb195f43d8b672674ee73d309" BISMARK_ALIGN = "bismark/align" REPO_NAME = "nf-core-test" PATCH_BRANCH = "patch-tester" @@ -50,14 +51,16 @@ def modify_main_nf(path): lines = fh.readlines() # We want a patch file that looks something like: # - tuple val(meta), path(reads) - # - path index + # - tuple val(meta3), path(index) # + tuple val(meta), path(reads), path(index) + to_pop = None for line_index in range(len(lines)): if lines[line_index] == " tuple val(meta), path(reads)\n": lines[line_index] = " tuple val(meta), path(reads), path(index)\n" - elif lines[line_index] == " path index\n": + elif lines[line_index] == " tuple val(meta3), path(index)\n": to_pop = line_index - lines.pop(to_pop) + if to_pop: + lines.pop(to_pop) with open(path, "w") as fh: fh.writelines(lines) @@ -108,7 +111,7 @@ def test_create_patch_change(self): assert f"--- {module_relpath / 'main.nf'}\n" in patch_lines, module_relpath / "main.nf" assert f"+++ {module_relpath / 'main.nf'}\n" in patch_lines assert "- tuple val(meta), path(reads)\n" in patch_lines - assert "- path index\n" in patch_lines + assert "- tuple val(meta3), path(index)\n" in patch_lines assert "+ tuple val(meta), path(reads), path(index)\n" in patch_lines def test_create_patch_try_apply_successful(self): @@ -167,7 +170,7 @@ def test_create_patch_try_apply_successful(self): assert f"--- {module_relpath / 'main.nf'}\n" in patch_lines assert f"+++ {module_relpath / 'main.nf'}\n" in patch_lines assert "- tuple val(meta), path(reads)\n" in patch_lines - assert "- path index\n" in patch_lines + assert "- tuple val(meta3), path(index)\n" in patch_lines assert "+ tuple val(meta), path(reads), path(index)\n" in patch_lines # Check that 'main.nf' is updated correctly @@ -175,7 +178,7 @@ def test_create_patch_try_apply_successful(self): main_nf_lines = fh.readlines() # These lines should have been removed by the patch assert " tuple val(meta), path(reads)\n" not in main_nf_lines - assert " path index\n" not in main_nf_lines + assert " tuple val(meta3), path(index)\n" not in main_nf_lines # This line should have been added assert " tuple val(meta), path(reads), path(index)\n" in main_nf_lines @@ -268,7 +271,7 @@ def test_create_patch_update_success(self): assert f"--- {module_relpath / 'main.nf'}\n" in patch_lines assert f"+++ {module_relpath / 'main.nf'}\n" in patch_lines assert "- tuple val(meta), path(reads)\n" in patch_lines - assert "- path index\n" in patch_lines + assert "- tuple val(meta3), path(index)\n" in patch_lines assert "+ tuple val(meta), path(reads), path(index)\n" in patch_lines # Check that 'main.nf' is updated correctly @@ -276,7 +279,7 @@ def test_create_patch_update_success(self): main_nf_lines = fh.readlines() # These lines should have been removed by the patch assert " tuple val(meta), path(reads)\n" not in main_nf_lines - assert " path index\n" not in main_nf_lines + assert " tuple val(meta3), path(index)\n" not in main_nf_lines # This line should have been added assert " tuple val(meta), path(reads), path(index)\n" in main_nf_lines @@ -323,8 +326,8 @@ def test_create_patch_update_fail(self): ).install_component_files(BISMARK_ALIGN, FAIL_SHA, update_obj.modules_repo, temp_dir) temp_module_dir = temp_dir / BISMARK_ALIGN - temp_files = {f.name for f in temp_module_dir.iterdir()} - module_files = {f.name for f in module_path.iterdir()} + temp_files = {f.name for f in temp_module_dir.iterdir() if f.is_file()} + module_files = {f.name for f in module_path.iterdir() if f.is_file()} for file_name in temp_files: assert file_name in module_files with open(module_path / file_name) as fh: diff --git a/tests/pipelines/lint/test_nfcore_yml.py b/tests/pipelines/lint/test_nfcore_yml.py index e888a1d6a1..a2c1babd6a 100644 --- a/tests/pipelines/lint/test_nfcore_yml.py +++ b/tests/pipelines/lint/test_nfcore_yml.py @@ -48,6 +48,15 @@ def test_nfcore_yml_fail_nfcore_version(self): assert len(results.get("passed", [])) >= 0 assert len(results.get("ignored", [])) == 0 + def test_nfcore_yml_container_registry_accepted(self): + """Lint test: nfcore_yml - PASS - container-registry field is accepted without errors""" + self.nf_core_yml["container-registry"] = ["community.wave.seqera.io/library/", "ghcr.io/"] + self.yaml.dump(self.nf_core_yml, self.nf_core_yml_path) + + assert self.lint_obj._load() + results = self.lint_obj.nfcore_yml() + assert len(results.get("failed", [])) == 0 + def test_nfcore_yml_nested_lint_config(self) -> None: """Lint test: nfcore_yml with nested lint config - PASS""" valid_yaml = """ From ac2258c477f4b69a63288fcdb77de62e2490ff11 Mon Sep 17 00:00:00 2001 From: simojoe <37026683+simojoe@users.noreply.github.com> Date: Tue, 9 Jun 2026 03:16:45 -0500 Subject: [PATCH 050/135] Update nf-core/tools docs link (#4312) --- CONTRIBUTING.md | 2 +- README.md | 2 +- nf_core/commands_pipelines.py | 2 +- nf_core/pipelines/lint/__init__.py | 14 ++++++++------ nf_core/pipelines/lint_utils.py | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 12f2a469ff..9405e36577 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -90,7 +90,7 @@ Note: The `--config` flag is important in this repository to ensure prek uses th ## API Documentation We aim to write function docstrings according to the [Google Python style-guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings). These are used to automatically generate package documentation on the nf-core website using Sphinx. -You can find this documentation here: [https://nf-co.re/tools/docs/](https://nf-co.re/tools/docs/) +You can find this documentation here: [nf-core tools Python API docs](https://nf-co.re/docs/nf-core-tools/api_reference/latest/). If you would like to test the documentation, you can install Sphinx locally by following Sphinx's [installation instruction](https://www.sphinx-doc.org/en/master/usage/installation.html). Once done, you can run `make clean` and then `make html` in the `docs/api` directory of `nf-core tools`. diff --git a/README.md b/README.md index 88542d2176..ed6652f7a6 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ A python package with helper tools for the nf-core community. The nf-core tools package is written in Python and can be imported and used within other packages. -For documentation of the internal Python functions, please refer to the [Tools Python API docs](https://nf-co.re/tools/docs/). +For documentation of the internal Python functions, please refer to the [nf-core tools Python API docs](https://nf-co.re/docs/nf-core-tools/api_reference/latest/). ## Installation diff --git a/nf_core/commands_pipelines.py b/nf_core/commands_pipelines.py index 273097c474..9815d324d6 100644 --- a/nf_core/commands_pipelines.py +++ b/nf_core/commands_pipelines.py @@ -120,7 +120,7 @@ def pipelines_lint( Runs a large number of automated tests to ensure that the supplied pipeline meets the nf-core guidelines. Documentation of all lint tests can be found - on the nf-core website: [link=https://nf-co.re/tools/docs/]https://nf-co.re/tools/docs/[/] + on the nf-core website: [link=https://nf-co.re/docs/nf-core-tools/api_reference/latest/]https://nf-co.re/docs/nf-core-tools/api_reference/latest/[/] You can ignore tests using a file called [blue].nf-core.yml[/] [i](if you have a good reason!)[/]. See the documentation for details. diff --git a/nf_core/pipelines/lint/__init__.py b/nf_core/pipelines/lint/__init__.py index 4cfe23ea69..d31930e735 100644 --- a/nf_core/pipelines/lint/__init__.py +++ b/nf_core/pipelines/lint/__init__.py @@ -328,7 +328,9 @@ def format_result(test_results): if "dev" in __version__: tools_version = "dev" for eid, msg in test_results: - yield Markdown(f"[{eid}](https://nf-co.re/tools/docs/{tools_version}/pipeline_lint_tests/{eid}): {msg}") + yield Markdown( + f"[{eid}](https://nf-co.re/docs/nf-core-tools/api_reference/{tools_version}/pipeline_lint_tests/{eid}): {msg}" + ) # Table of passed tests if len(self.passed) > 0 and show_passed: @@ -429,7 +431,7 @@ def _get_results_md(self): test_failures = "### :x: Test failures:\n\n{}\n\n".format( "\n".join( [ - f"* [{eid}](https://nf-co.re/tools/docs/{tools_version}/pipeline_lint_tests/{eid}) - " + f"* [{eid}](https://nf-co.re/docs/nf-core-tools/api_reference/{tools_version}/pipeline_lint_tests/{eid}) - " f"{strip_ansi_codes(msg, '`')}" for eid, msg in self.failed ] @@ -443,7 +445,7 @@ def _get_results_md(self): test_ignored = "### :grey_question: Tests ignored:\n\n{}\n\n".format( "\n".join( [ - f"* [{eid}](https://nf-co.re/tools/docs/{tools_version}/pipeline_lint_tests/{eid}) - " + f"* [{eid}](https://nf-co.re/docs/nf-core-tools/api_reference/{tools_version}/pipeline_lint_tests/{eid}) - " f"{strip_ansi_codes(msg, '`')}" for eid, msg in self.ignored ] @@ -457,7 +459,7 @@ def _get_results_md(self): test_fixed = "### :grey_question: Tests fixed:\n\n{}\n\n".format( "\n".join( [ - f"* [{eid}](https://nf-co.re/tools/docs/{tools_version}/pipeline_lint_tests/{eid}) - " + f"* [{eid}](https://nf-co.re/docs/nf-core-tools/api_reference/{tools_version}/pipeline_lint_tests/{eid}) - " f"{strip_ansi_codes(msg, '`')}" for eid, msg in self.fixed ] @@ -471,7 +473,7 @@ def _get_results_md(self): test_warnings = "### :heavy_exclamation_mark: Test warnings:\n\n{}\n\n".format( "\n".join( [ - f"* [{eid}](https://nf-co.re/tools/docs/{tools_version}/pipeline_lint_tests/{eid}) - " + f"* [{eid}](https://nf-co.re/docs/nf-core-tools/api_reference/{tools_version}/pipeline_lint_tests/{eid}) - " f"{strip_ansi_codes(msg, '`')}" for eid, msg in self.warned ] @@ -486,7 +488,7 @@ def _get_results_md(self): "\n".join( [ ( - f"* [{eid}](https://nf-co.re/tools/docs/{tools_version}/pipeline_lint_tests/{eid})" + f"* [{eid}](https://nf-co.re/docs/nf-core-tools/api_reference/{tools_version}/pipeline_lint_tests/{eid})" f" - {strip_ansi_codes(msg, '`')}" ) for eid, msg in self.passed diff --git a/nf_core/pipelines/lint_utils.py b/nf_core/pipelines/lint_utils.py index e1980cf89d..d2dc56f67a 100644 --- a/nf_core/pipelines/lint_utils.py +++ b/nf_core/pipelines/lint_utils.py @@ -49,7 +49,7 @@ def print_lines(text, strip_ansi=False): # Pipeline results: (eid, msg) eid, msg = r console.print( - f"\n[{color}]{eid}[/{color}] https://nf-co.re/tools/docs/{tools_version}/pipeline_lint_tests/{eid}" + f"\n[{color}]{eid}[/{color}] https://nf-co.re/docs/nf-core-tools/api_reference/{tools_version}/pipeline_lint_tests/{eid}" ) print_lines(msg, strip_ansi=True) else: From 32f94e758af042a3746e3332f5c97a0f22b9718c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Tue, 9 Jun 2026 18:11:12 -0400 Subject: [PATCH 051/135] fix: pipelines schema docs stdout capture clean markdown --- nf_core/pipelines/schema.py | 5 ++++- tests/pipelines/test_schema.py | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/nf_core/pipelines/schema.py b/nf_core/pipelines/schema.py index 0c42b718dc..245e9ac8a6 100644 --- a/nf_core/pipelines/schema.py +++ b/nf_core/pipelines/schema.py @@ -580,7 +580,10 @@ def print_documentation( if not output_fn: console = rich.console.Console() - console.print("\n", Syntax(prettified_docs, output_format, word_wrap=True), "\n") + if console.is_terminal: + console.print("\n", Syntax(prettified_docs, output_format, word_wrap=True), "\n") + else: + print(prettified_docs, end="") else: if Path(output_fn).exists() and not force: log.error(f"File '{output_fn}' exists! Please delete first, or use '--force'") diff --git a/tests/pipelines/test_schema.py b/tests/pipelines/test_schema.py index 5965a5c011..c378fb4346 100644 --- a/tests/pipelines/test_schema.py +++ b/tests/pipelines/test_schema.py @@ -5,6 +5,7 @@ import shutil import tempfile import unittest +from io import StringIO from pathlib import Path from unittest import mock @@ -130,6 +131,27 @@ def test_schema_docs(self): assert definition["title"] in docs assert definition["description"] in docs + def test_schema_docs_markdown_linebreak(self): + """Check that Markdown docs linebreak only happens in a terminal""" + self.schema_obj.schema_filename = self.template_schema + self.schema_obj.load_schema() + + with ( + mock.patch("rich.console.Console.is_terminal", new_callable=mock.PropertyMock, return_value=False), + mock.patch("sys.stdout", new_callable=StringIO) as mock_stdout, + ): + self.schema_obj.print_documentation() + docs = mock_stdout.getvalue() + + with ( + mock.patch("rich.console.Console.is_terminal", new_callable=mock.PropertyMock, return_value=True), + mock.patch("sys.stdout", new_callable=StringIO) as mock_stdout, + ): + self.schema_obj.print_documentation() + docs_tty = mock_stdout.getvalue() + + assert docs_tty.count("\n") > docs.count("\n") + @with_temporary_file def test_save_schema(self, tmp_file): """Try to save a schema""" From 454abd6df404ddd84cb8c82dea1ac695606979ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Tue, 9 Jun 2026 20:09:00 -0400 Subject: [PATCH 052/135] adding test for file identify --- tests/pipelines/test_schema.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/pipelines/test_schema.py b/tests/pipelines/test_schema.py index c378fb4346..bc5600f6e2 100644 --- a/tests/pipelines/test_schema.py +++ b/tests/pipelines/test_schema.py @@ -131,7 +131,8 @@ def test_schema_docs(self): assert definition["title"] in docs assert definition["description"] in docs - def test_schema_docs_markdown_linebreak(self): + @with_temporary_file + def test_schema_docs_markdown_linebreak(self, tmp_file): """Check that Markdown docs linebreak only happens in a terminal""" self.schema_obj.schema_filename = self.template_schema self.schema_obj.load_schema() @@ -150,7 +151,11 @@ def test_schema_docs_markdown_linebreak(self): self.schema_obj.print_documentation() docs_tty = mock_stdout.getvalue() + self.schema_obj.print_documentation(output_fn=tmp_file.name, force=True) + tmp_file.seek(0) + assert docs_tty.count("\n") > docs.count("\n") + assert tmp_file.read().decode() == docs @with_temporary_file def test_save_schema(self, tmp_file): From f97932189d92649be11e9da608972b1b449158ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Tue, 9 Jun 2026 20:19:55 -0400 Subject: [PATCH 053/135] typo: comma in column name --- nf_core/pipelines/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipelines/schema.py b/nf_core/pipelines/schema.py index 245e9ac8a6..e8f9cfe55a 100644 --- a/nf_core/pipelines/schema.py +++ b/nf_core/pipelines/schema.py @@ -566,7 +566,7 @@ def print_documentation( Prints documentation for the schema. """ if columns is None: - columns = ["parameter", "description", "type,", "default", "required", "hidden"] + columns = ["parameter", "description", "type", "default", "required", "hidden"] output = self.schema_to_markdown(columns) if output_format == "html": From df3bd93c96cdcd8e4d2a6f05c0818c74e4c92aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Tue, 9 Jun 2026 20:26:41 -0400 Subject: [PATCH 054/135] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d46348e2db..2828fdd39f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Update pre-commit hook pre-commit/mirrors-mypy to v2 ([#4270](https://github.com/nf-core/tools/pull/4270)) - container configs: use correct key for conda configs ([#4269](https://github.com/nf-core/tools/pull/4269)) +- generate valid Markdown when piping schema docs to file ([#4319](https://github.com/nf-core/tools/pull/4319)) ### Linting From 23061445f2ccbcd79781c87a180d47ab54491b2a Mon Sep 17 00:00:00 2001 From: Vincent Gao Date: Wed, 10 Jun 2026 10:04:36 +0200 Subject: [PATCH 055/135] Coerce launch params_out to Path to fix AttributeError (#4299) (#4317) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: mashehu Co-authored-by: nf-core-bot Co-authored-by: Matthias Hörtenhuber fix AttributeError (#4299) Closes #4299 --- CHANGELOG.md | 1 + nf_core/__main__.py | 2 +- tests/pipelines/test_launch.py | 12 ++++++++++++ tests/test_cli.py | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d46348e2db..f419023166 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Update pre-commit hook pre-commit/mirrors-mypy to v2 ([#4270](https://github.com/nf-core/tools/pull/4270)) - container configs: use correct key for conda configs ([#4269](https://github.com/nf-core/tools/pull/4269)) +- Coerce launch params_out to Path to fix AttributeError (#4299) ([#4317](https://github.com/nf-core/tools/pull/4317)) ### Linting diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 5d232530a9..2e77f1eb1d 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -485,7 +485,7 @@ def command_pipelines_create_params_file(ctx, pipeline, revision, output, force, @click.option( "-o", "--params-out", - type=click.Path(), + type=click.Path(path_type=Path), default=str(Path.cwd() / "nf-params.json"), help="Path to save run parameters file", ) diff --git a/tests/pipelines/test_launch.py b/tests/pipelines/test_launch.py index e97f2f10b6..9cbee9ece7 100644 --- a/tests/pipelines/test_launch.py +++ b/tests/pipelines/test_launch.py @@ -336,3 +336,15 @@ def test_build_command_params_cl(self): self.launcher.schema_obj.input_params.update({"input": "custom_input"}) self.launcher.build_command() assert self.launcher.nextflow_cmd == f'nextflow run {self.pipeline_dir} --input "custom_input"' + + +def test_launch_params_out_option_is_path(): + """The --params-out CLI option converts its value to a Path, so params_out never + reaches Launch as a str that would crash params_out.exists() (#4299).""" + import click + + from nf_core.__main__ import command_pipelines_launch + + param = next(p for p in command_pipelines_launch.params if p.name == "params_out") + ctx = click.Context(command_pipelines_launch) + assert isinstance(param.type.convert("nf-params.json", param, ctx), Path) diff --git a/tests/test_cli.py b/tests/test_cli.py index 60fd4606f8..312b94cc73 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -106,7 +106,7 @@ def test_cli_launch(self, mock_launcher): "revision": "abcdef", "id": "idgui", "command-only": None, - "params-out": "/path/params/out", + "params-out": Path("/path/params/out"), "params-in": temp_params_in.name, "save-all": None, "show-hidden": None, From db5e3bb533197ca552ba346f6f735a9d8f0a7a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 11 Jun 2026 10:24:47 +0200 Subject: [PATCH 056/135] fix API docs bug in pydantic autodoc (#4320) Co-authored-by: nf-core-bot --- CHANGELOG.md | 1 + docs/api/_src/api/nf_core_yml.md | 1 + docs/api/_src/api/pipelines/lint.md | 2 +- docs/api/_src/api/pipelines/{utils.md => lint_utils.md} | 2 +- nf_core/pipelines/create/utils.py | 8 +++++--- 5 files changed, 9 insertions(+), 5 deletions(-) rename docs/api/_src/api/pipelines/{utils.md => lint_utils.md} (73%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 584ff96191..7ebe6ba66d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - container configs: use correct key for conda configs ([#4269](https://github.com/nf-core/tools/pull/4269)) - Coerce launch params_out to Path to fix AttributeError (#4299) ([#4317](https://github.com/nf-core/tools/pull/4317)) - generate valid Markdown when piping schema docs to file ([#4319](https://github.com/nf-core/tools/pull/4319)) +- fix API docs bug in pydantic autodoc ([#4320](https://github.com/nf-core/tools/pull/4320)) ### Linting diff --git a/docs/api/_src/api/nf_core_yml.md b/docs/api/_src/api/nf_core_yml.md index d264948f4b..ab03b23304 100644 --- a/docs/api/_src/api/nf_core_yml.md +++ b/docs/api/_src/api/nf_core_yml.md @@ -64,4 +64,5 @@ container-registry: :model-show-validator-members: false :model-show-field-summary: true :field-show-alias: true + :no-index: ``` diff --git a/docs/api/_src/api/pipelines/lint.md b/docs/api/_src/api/pipelines/lint.md index 91b37c26f6..9fdfba0812 100644 --- a/docs/api/_src/api/pipelines/lint.md +++ b/docs/api/_src/api/pipelines/lint.md @@ -12,7 +12,7 @@ See the [Lint Tests](/docs/nf-core-tools/api_reference/dev/pipeline_lint_tests) ``` ```{eval-rst} -.. autoclass:: nf_core.lint.PipelineLint +.. autoclass:: nf_core.pipelines.lint.PipelineLint :members: _lint_pipeline :private-members: _print_results, _get_results_md, _save_json_results, _wrap_quotes :show-inheritance: diff --git a/docs/api/_src/api/pipelines/utils.md b/docs/api/_src/api/pipelines/lint_utils.md similarity index 73% rename from docs/api/_src/api/pipelines/utils.md rename to docs/api/_src/api/pipelines/lint_utils.md index 36c2ecca4d..f74c103ad3 100644 --- a/docs/api/_src/api/pipelines/utils.md +++ b/docs/api/_src/api/pipelines/lint_utils.md @@ -1,7 +1,7 @@ # nf_core.pipelines.utils ```{eval-rst} -.. automodule:: nf_core.pipelines.utils +.. automodule:: nf_core.pipelines.lint_utils :members: :undoc-members: :show-inheritance: diff --git a/nf_core/pipelines/create/utils.py b/nf_core/pipelines/create/utils.py index 5751ddbd77..d7609126ac 100644 --- a/nf_core/pipelines/create/utils.py +++ b/nf_core/pipelines/create/utils.py @@ -6,7 +6,7 @@ from typing import Any import yaml -from pydantic import ConfigDict, ValidationError, ValidationInfo, field_validator +from pydantic import ValidationError, ValidationInfo, field_validator from textual import on from textual.app import ComposeResult from textual.containers import Grid, HorizontalScroll @@ -18,6 +18,10 @@ import nf_core from nf_core.utils import NFCoreTemplateConfig +# Sphinx/autodoc triggers Pydantic model rebuilds which require `Dict` in this module's namespace. +# Using the builtin dict (not typing.Dict) because Pydantic v2 only accepts the lowercase form. +Dict = dict + # Use ContextVar to define a context on the model initialization _init_context_var: ContextVar = ContextVar("_init_context_var", default=None) @@ -41,8 +45,6 @@ def init_context(value: dict[str, Any]) -> Iterator[None]: class CreateConfig(NFCoreTemplateConfig): """Pydantic model for the nf-core create config.""" - model_config = ConfigDict(extra="allow") - def __init__(self, /, **data: Any) -> None: """Custom init method to allow using a context on the model initialization.""" context = _init_context_var.get() From df086dee8b4eaf19b3e18be58ee8f1913453cb5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Fri, 12 Jun 2026 12:41:27 +0200 Subject: [PATCH 057/135] switch to json format for nextflow inspect (#4271) Co-authored-by: Matthieu Muffato --- nf_core/modules/modules_json.py | 5 +- nf_core/pipelines/bump_version.py | 10 +- .../pipelines/download/container_fetcher.py | 7 +- nf_core/pipelines/lint/files_exist.py | 9 +- nf_core/pipelines/lint/files_unchanged.py | 28 ++-- nf_core/pipelines/lint/multiqc_config.py | 2 +- nf_core/pipelines/lint/nextflow_config.py | 145 ++++++++---------- nf_core/pipelines/lint/plugin_includes.py | 3 +- nf_core/pipelines/lint/version_consistency.py | 11 +- nf_core/pipelines/rocrate.py | 43 ++---- nf_core/pipelines/schema.py | 84 +++++----- nf_core/pipelines/sync.py | 20 ++- nf_core/test_datasets/test_datasets_utils.py | 2 +- nf_core/utils.py | 94 ++++++------ pyproject.toml | 2 + tests/pipelines/download/test_download.py | 2 +- tests/pipelines/download/test_singularity.py | 10 +- tests/pipelines/lint/test_files_exist.py | 4 +- tests/pipelines/lint/test_multiqc_config.py | 2 +- tests/pipelines/lint/test_nextflow_config.py | 10 +- .../lint/test_version_consistency.py | 4 +- tests/pipelines/test_bump_version.py | 6 +- tests/pipelines/test_rocrate.py | 2 +- tests/pipelines/test_sync.py | 6 +- tests/test_utils.py | 10 +- uv.lock | 46 ++++++ 26 files changed, 290 insertions(+), 277 deletions(-) diff --git a/nf_core/modules/modules_json.py b/nf_core/modules/modules_json.py index 716a40e8ea..c47b4378cf 100644 --- a/nf_core/modules/modules_json.py +++ b/nf_core/modules/modules_json.py @@ -81,8 +81,9 @@ def create(self) -> None: UserWarning: If the creation fails """ pipeline_config = nf_core.utils.fetch_wf_config(self.directory) - pipeline_name = pipeline_config.get("manifest.name", "") - pipeline_url = pipeline_config.get("manifest.homePage", "") + manifest = pipeline_config.get("manifest", {}) + pipeline_name = manifest.get("name", "") + pipeline_url = manifest.get("homePage", "") new_modules_json = ModulesJsonType(name=pipeline_name, homePage=pipeline_url, repos={}) if not self.modules_dir.exists(): diff --git a/nf_core/pipelines/bump_version.py b/nf_core/pipelines/bump_version.py index 604a85801d..ebb38aed99 100644 --- a/nf_core/pipelines/bump_version.py +++ b/nf_core/pipelines/bump_version.py @@ -26,8 +26,8 @@ def bump_pipeline_version(pipeline_obj: Pipeline, new_version: str) -> None: new_version (str): The new version tag for the pipeline. Semantic versioning only. """ - # Collect the old and new version numbers - current_version = pipeline_obj.nf_config.get("manifest.version", "").strip(" '\"") + manifest = pipeline_obj.nf_config.get("manifest", {}) + current_version = manifest.get("version", "") or "" if new_version.startswith("v"): log.warning("Stripping leading 'v' from new version number") new_version = new_version[1:] @@ -99,7 +99,7 @@ def bump_pipeline_version(pipeline_obj: Pipeline, new_version: str) -> None: yaml_key=["report_comment"], ) # nf-test snap files - pipeline_name = pipeline_obj.nf_config.get("manifest.name", "").strip(" '\"") + pipeline_name = manifest.get("name", "") snap_files = [f.relative_to(pipeline_obj.wf_path) for f in Path(pipeline_obj.wf_path).glob("tests/pipeline/*.snap")] for snap_file in snap_files: update_file_version( @@ -169,8 +169,8 @@ def bump_nextflow_version(pipeline_obj: Pipeline, new_version: str) -> None: new_version (str): The new version tag for the required Nextflow version. """ - # Collect the old and new version numbers - strip leading non-numeric characters (>=) - current_version = pipeline_obj.nf_config.get("manifest.nextflowVersion", "").strip(" '\"") + manifest = pipeline_obj.nf_config.get("manifest", {}) + current_version = manifest.get("nextflowVersion", "") or "" current_version = re.sub(r"^[^0-9\.]*", "", current_version) new_version = re.sub(r"^[^0-9\.]*", "", new_version) if not current_version: diff --git a/nf_core/pipelines/download/container_fetcher.py b/nf_core/pipelines/download/container_fetcher.py index bfcda9ed54..3916fb1b9c 100644 --- a/nf_core/pipelines/download/container_fetcher.py +++ b/nf_core/pipelines/download/container_fetcher.py @@ -292,8 +292,11 @@ def gather_config_registries(self, workflow_directory: Path, registry_keys: list config_registries = set() for registry_key in registry_keys: - if registry_key in nf_config: - config_registries.add(nf_config[registry_key]) + parts = registry_key.split(".", 1) + if len(parts) == 2 and parts[0] in nf_config and isinstance(nf_config[parts[0]], dict): + val = nf_config[parts[0]].get(parts[1]) + if val: + config_registries.add(val) return config_registries diff --git a/nf_core/pipelines/lint/files_exist.py b/nf_core/pipelines/lint/files_exist.py index 202906c184..9fb55ccedb 100644 --- a/nf_core/pipelines/lint/files_exist.py +++ b/nf_core/pipelines/lint/files_exist.py @@ -120,11 +120,12 @@ def files_exist(self) -> dict[str, list[str]]: # NB: Should all be files, not directories # List of lists. Passes if any of the files in the sublist are found. #: test autodoc - try: - _, short_name = self.nf_config["manifest.name"].strip("\"'").split("/") - except ValueError: + pipeline_name = self.nf_config.get("manifest", {}).get("name", "") + if "/" in pipeline_name: + _, short_name = pipeline_name.split("/") + else: log.warning("Expected manifest.name to be in the format '/'. Will assume it is ''.") - short_name = self.nf_config["manifest.name"].strip("\"'").split("/") + short_name = pipeline_name files_fail = [ [Path(".gitattributes")], diff --git a/nf_core/pipelines/lint/files_unchanged.py b/nf_core/pipelines/lint/files_unchanged.py index 4f9fe3fcd2..20cef65ae5 100644 --- a/nf_core/pipelines/lint/files_unchanged.py +++ b/nf_core/pipelines/lint/files_unchanged.py @@ -1,6 +1,5 @@ import filecmp import logging -import re import shutil import tempfile from pathlib import Path @@ -66,21 +65,18 @@ def files_unchanged(self) -> dict[str, list[str] | bool]: could_fix: bool = False # Check that we have the minimum required config - required_pipeline_config = { - "manifest.name", - "manifest.description", - "manifest.contributors", - } - missing_pipeline_config = required_pipeline_config.difference(self.nf_config) + manifest_config = self.nf_config.get("manifest", {}) + missing_pipeline_config = {k for k in ("name", "description", "contributors") if not manifest_config.get(k)} if missing_pipeline_config: - return {"ignored": [f"Required pipeline config not found - {missing_pipeline_config}"]} + missing_keys = {f"manifest.{k}" for k in missing_pipeline_config} + return {"ignored": [f"Required pipeline config not found - {missing_keys}"]} try: - prefix, short_name = self.nf_config["manifest.name"].strip("\"'").split("/") + prefix, short_name = manifest_config.get("name", "").split("/") except ValueError: log.warning( "Expected manifest.name to be in the format '/'. Will assume it is and default to repo 'nf-core'" ) - short_name = self.nf_config["manifest.name"].strip("\"'") + short_name = manifest_config.get("name", "") prefix = "nf-core" # NB: Should all be files, not directories @@ -118,14 +114,14 @@ def files_unchanged(self) -> dict[str, list[str] | bool]: tmp_dir.mkdir(parents=True) # Create a template.yaml file for the pipeline creation - if "manifest.author" in self.nf_config: - names = self.nf_config["manifest.author"].strip("\"'") - if "manifest.contributors" in self.nf_config: - contributors = self.nf_config["manifest.contributors"] - names = ", ".join(re.findall(r"name:'([^']+)'", contributors)) + contributors = manifest_config.get("contributors", []) + if contributors: + names = ", ".join(c.get("name", "") for c in contributors if c.get("name")) + else: + names = manifest_config.get("author", "") template_yaml = { "name": short_name, - "description": self.nf_config["manifest.description"].strip("\"'"), + "description": manifest_config.get("description", ""), "author": names, "org": prefix, } diff --git a/nf_core/pipelines/lint/multiqc_config.py b/nf_core/pipelines/lint/multiqc_config.py index 254caa925a..2b2c87e5b9 100644 --- a/nf_core/pipelines/lint/multiqc_config.py +++ b/nf_core/pipelines/lint/multiqc_config.py @@ -98,7 +98,7 @@ def multiqc_config(self) -> dict[str, list[str]]: if "report_comment" not in ignore_configs: # Check that the minimum plugins exist and are coming first in the summary - version = self.nf_config.get("manifest.version", "").strip(" '\"") + version = self.nf_config.get("manifest", {}).get("version", "") or "" # Get the org from .nf-core.yml config, defaulting to "nf-core" _, nf_core_yaml_config = load_tools_config(self.wf_path) diff --git a/nf_core/pipelines/lint/nextflow_config.py b/nf_core/pipelines/lint/nextflow_config.py index f5913f5521..caea0fa352 100644 --- a/nf_core/pipelines/lint/nextflow_config.py +++ b/nf_core/pipelines/lint/nextflow_config.py @@ -1,4 +1,3 @@ -import ast import logging import re from pathlib import Path @@ -170,7 +169,7 @@ def nextflow_config(self) -> dict[str, list[str]]: ] # Lint for plugins - config_plugins = ast.literal_eval(self.nf_config.get("plugins", "[]")) + config_plugins = self.nf_config.get("plugins", []) found_plugins = [] for plugin in config_plugins: if "@" not in plugin: @@ -203,39 +202,34 @@ def nextflow_config(self) -> dict[str, list[str]]: # Remove field that should be ignored according to the linting config ignore_configs = self.lint_config.get("nextflow_config", []) if self.lint_config is not None else [] - for cfs in config_fail: - for cf in cfs: - if cf in ignore_configs: - ignored.append(f"Config variable ignored: {self._wrap_quotes(cf)}") - break - if cf in self.nf_config: - passed.append(f"Config variable found: {self._wrap_quotes(cf)}") - break - else: - failed.append(f"Config variable not found: {self._wrap_quotes(cfs)}") - for cfs in config_warn: - for cf in cfs: - if cf in ignore_configs: - ignored.append(f"Config variable ignored: {self._wrap_quotes(cf)}") - break - if cf in self.nf_config: - passed.append(f"Config variable found: {self._wrap_quotes(cf)}") - break - else: - warned.append(f"Config variable not found: {self._wrap_quotes(cfs)}") + def _config_has_key(key: str) -> bool: + section, name = key.split(".", 1) + return name in self.nf_config.get(section, {}) + + for configs, not_found in [(config_fail, failed), (config_warn, warned)]: + for cfs in configs: + for cf in cfs: + if cf in ignore_configs: + ignored.append(f"Config variable ignored: {self._wrap_quotes(cf)}") + break + if _config_has_key(cf): + passed.append(f"Config variable found: {self._wrap_quotes(cf)}") + break + else: + not_found.append(f"Config variable not found: {self._wrap_quotes(cfs)}") for cf in config_fail_ifdefined: if cf in ignore_configs: ignored.append(f"Config variable ignored: {self._wrap_quotes(cf)}") - break - if cf not in self.nf_config: + continue + if not _config_has_key(cf): passed.append(f"Config variable (correctly) not found: {self._wrap_quotes(cf)}") else: failed.append(f"Config variable (incorrectly) found: {self._wrap_quotes(cf)}") # Check and warn if the process configuration is done with deprecated syntax - + process_config = self.nf_config.get("process", {}) process_with_deprecated_syntax = list( - {match.group(1) for ck in self.nf_config if (match := re.match(r"^(process\.\$.*?)\.+.*$", ck)) is not None} + {f"process.{ck}" for ck in (process_config if isinstance(process_config, dict) else {}) if re.match(r"^\$", ck)} ) for pd in process_with_deprecated_syntax: warned.append(f"Process configuration is done with deprecated_syntax: {pd}") @@ -244,90 +238,76 @@ def nextflow_config(self) -> dict[str, list[str]]: for k in ["timeline.enabled", "report.enabled", "trace.enabled", "dag.enabled"]: if k in ignore_configs: continue - if self.nf_config.get(k) == "true": - passed.append(f"Config ``{k}`` had correct value: ``{self.nf_config.get(k)}``") + section, name = k.split(".") + val = self.nf_config.get(section, {}).get(name) + if val is True: + passed.append(f"Config ``{k}`` had correct value: ``{val}``") else: - failed.append(f"Config ``{k}`` did not have correct value: ``{self.nf_config.get(k)}``") + failed.append(f"Config ``{k}`` did not have correct value: ``{val}``") _, nf_core_yaml_config = load_tools_config(self.wf_path) org_name = "nf-core" if nf_core_yaml_config and getattr(nf_core_yaml_config, "template", None): org_name = getattr(nf_core_yaml_config.template, "org", org_name) or org_name - if "manifest.name" not in ignore_configs: - # Check that the pipeline name starts with nf-core - try: - manifest_name = self.nf_config.get("manifest.name", "").strip("'\"") - if not manifest_name.startswith(f"{org_name}/"): - raise AssertionError - except (AssertionError, IndexError): - failed.append(f"Config ``manifest.name`` did not begin with ``{org_name}/``:\n {manifest_name}") - else: - passed.append(f"Config ``manifest.name`` began with ``{org_name}/``") - - if "manifest.homePage" not in ignore_configs: - # Check that the homePage is set to the GitHub URL - try: - manifest_homepage = self.nf_config.get("manifest.homePage", "").strip("'\"") - if not manifest_homepage.startswith(f"https://github.com/{org_name}/"): - raise AssertionError - except (AssertionError, IndexError): - failed.append( - f"Config variable ``manifest.homePage`` did not begin with https://github.com/{org_name}/:\n {manifest_homepage}" - ) - + manifest = self.nf_config.get("manifest", {}) + for key, expected_prefix in [ + ("name", f"{org_name}/"), + ("homePage", f"https://github.com/{org_name}/"), + ]: + config_key = f"manifest.{key}" + if config_key in ignore_configs: + continue + value = manifest.get(key, "") + if value.startswith(expected_prefix): + passed.append(f"Config ``{config_key}`` began with ``{expected_prefix}``") else: - passed.append(f"Config variable ``manifest.homePage`` began with https://github.com/{org_name}/") + failed.append(f"Config ``{config_key}`` did not begin with ``{expected_prefix}``") - # Check that the DAG filename ends in ``.svg`` - if "dag.file" in self.nf_config: + dag_file = self.nf_config.get("dag", {}).get("file", "") + if dag_file: default_dag_format = ".html" - if self.nf_config["dag.file"].strip("'\"").endswith(default_dag_format): + if dag_file.endswith(default_dag_format): passed.append(f"Config ``dag.file`` ended with ``{default_dag_format}``") else: failed.append(f"Config ``dag.file`` did not end with ``{default_dag_format}``") # Check that the minimum nextflowVersion is set properly - if "manifest.nextflowVersion" in self.nf_config: - if self.nf_config.get("manifest.nextflowVersion", "").strip("\"'").lstrip("!").startswith(">="): + nextflow_version = manifest.get("nextflowVersion", "") + if nextflow_version: + if nextflow_version.lstrip("!").startswith(">="): passed.append("Config variable ``manifest.nextflowVersion`` started with >= or !>=") else: failed.append( - "Config ``manifest.nextflowVersion`` did not start with ``>=`` or ``!>=`` : " - f"``{self.nf_config.get('manifest.nextflowVersion', '')}``".strip("\"'") + f"Config ``manifest.nextflowVersion`` did not start with ``>=`` or ``!>=`` : ``{nextflow_version}``" ) # Check that the pipeline version contains ``dev`` - if not self.release_mode and "manifest.version" in self.nf_config: - if self.nf_config["manifest.version"].strip(" '\"").endswith("dev"): - passed.append(f"Config ``manifest.version`` ends in ``dev``: ``{self.nf_config['manifest.version']}``") + manifest_version = self.nf_config.get("manifest", {}).get("version", "") + if not self.release_mode and manifest_version: + if manifest_version.endswith("dev"): + passed.append(f"Config ``manifest.version`` ends in ``dev``: ``{manifest_version}``") else: - warned.append( - f"Config ``manifest.version`` should end in ``dev``: ``{self.nf_config['manifest.version']}``" - ) - elif "manifest.version" in self.nf_config: - if "dev" in self.nf_config["manifest.version"]: + warned.append(f"Config ``manifest.version`` should end in ``dev``: ``{manifest_version}``") + elif manifest_version: + if "dev" in manifest_version: failed.append( - "Config ``manifest.version`` should not contain ``dev`` for a release: " - f"``{self.nf_config['manifest.version']}``" + f"Config ``manifest.version`` should not contain ``dev`` for a release: ``{manifest_version}``" ) else: - passed.append( - "Config ``manifest.version`` does not contain ``dev`` for release: " - f"``{self.nf_config['manifest.version']}``" - ) + passed.append(f"Config ``manifest.version`` does not contain ``dev`` for release: ``{manifest_version}``") if "custom_config" not in ignore_configs: # Check if custom profile params are set correctly - if self.nf_config.get("params.custom_config_version", "").strip("'") == "master": + if self.nf_config.get("params", {}).get("custom_config_version", "") == "master": passed.append("Config `params.custom_config_version` is set to `master`") else: failed.append("Config `params.custom_config_version` is not set to `master`") custom_config_base = "https://raw.githubusercontent.com/nf-core/configs/{}".format( - self.nf_config.get("params.custom_config_version", "").strip("'") + self.nf_config.get("params", {}).get("custom_config_version", "") ) - if self.nf_config.get("params.custom_config_base", "").strip("'") == custom_config_base: + if self.nf_config.get("params", {}).get("custom_config_base", "") == custom_config_base: passed.append(f"Config `params.custom_config_base` is set to `{custom_config_base}`") else: failed.append(f"Config `params.custom_config_base` is not set to `{custom_config_base}`") @@ -411,18 +391,19 @@ def nextflow_config(self) -> dict[str, list[str]]: schema.get_schema_types() # Get types from schema for param_name in schema.schema_defaults: param = "params." + param_name + param_value = self.nf_config.get("params", {}).get(param_name) if param in ignore_defaults: ignored.append(f"Config default ignored: {param}") - elif param in self.nf_config: + elif param_value is not None: config_default: str | float | int | None = None schema_default: str | float | int | None = None if schema.schema_types[param_name] == "boolean": schema_default = str(schema.schema_defaults[param_name]).lower() - config_default = str(self.nf_config[param]).lower() + config_default = str(param_value).lower() elif schema.schema_types[param_name] == "number": try: schema_default = float(schema.schema_defaults[param_name]) - config_default = float(self.nf_config[param]) + config_default = float(param_value) except ValueError: failed.append( f"Config default value incorrect: `{param}` is set as type `number` in nextflow_schema.json, but is not a number in `nextflow.config`." @@ -430,19 +411,19 @@ def nextflow_config(self) -> dict[str, list[str]]: elif schema.schema_types[param_name] == "integer": try: schema_default = int(schema.schema_defaults[param_name]) - config_default = int(self.nf_config[param]) + config_default = int(param_value) except ValueError: failed.append( f"Config default value incorrect: `{param}` is set as type `integer` in nextflow_schema.json, but is not an integer in `nextflow.config`." ) else: schema_default = str(schema.schema_defaults[param_name]) - config_default = str(self.nf_config[param]) + config_default = str(param_value) if config_default is not None and config_default == schema_default: passed.append(f"Config default value correct: {param}= {schema_default}") else: failed.append( - f"Config default value incorrect: `{param}` is set as {self._wrap_quotes(schema_default)} in `nextflow_schema.json` but is {self._wrap_quotes(self.nf_config[param])} in `nextflow.config`." + f"Config default value incorrect: `{param}` is set as {self._wrap_quotes(schema_default)} in `nextflow_schema.json` but is {self._wrap_quotes(param_value)} in `nextflow.config`." ) else: schema_default = str(schema.schema_defaults[param_name]) diff --git a/nf_core/pipelines/lint/plugin_includes.py b/nf_core/pipelines/lint/plugin_includes.py index b787405169..335d1a5501 100644 --- a/nf_core/pipelines/lint/plugin_includes.py +++ b/nf_core/pipelines/lint/plugin_includes.py @@ -1,4 +1,3 @@ -import ast import logging import re from pathlib import Path @@ -12,7 +11,7 @@ def plugin_includes(self) -> dict[str, list[str]]: When nf-schema is used in an nf-core pipeline, the include statements of the plugin functions have to use nf-schema instead of nf-validation and vice versa """ - config_plugins = [plugin.split("@")[0] for plugin in ast.literal_eval(self.nf_config.get("plugins", "[]"))] + config_plugins = [plugin.split("@")[0] for plugin in self.nf_config.get("plugins", [])] validation_plugin = "nf-validation" if "nf-validation" in config_plugins else "nf-schema" passed: list[str] = [] diff --git a/nf_core/pipelines/lint/version_consistency.py b/nf_core/pipelines/lint/version_consistency.py index c939938a46..03beef4c5f 100644 --- a/nf_core/pipelines/lint/version_consistency.py +++ b/nf_core/pipelines/lint/version_consistency.py @@ -32,15 +32,16 @@ def version_consistency(self): # Get the version definitions # Get version from nextflow.config versions = {} - versions["manifest.version"] = self.nf_config.get("manifest.version", "").strip(" '\"") + versions["manifest.version"] = self.nf_config.get("manifest", {}).get("version") or "" # Get version from the docker tag - if self.nf_config.get("process.container", "") and ":" not in self.nf_config.get("process.container", ""): - failed.append(f"Docker slug seems not to have a version tag: {self.nf_config.get('process.container', '')}") + process_container = self.nf_config.get("process", {}).get("container") or "" + if process_container and ":" not in process_container: + failed.append(f"Docker slug seems not to have a version tag: {process_container}") # Get config container tag (if set; one container per workflow) - if self.nf_config.get("process.container", ""): - versions["process.container"] = self.nf_config.get("process.container", "").strip(" '\"").split(":")[-1] + if process_container: + versions["process.container"] = process_container.split(":")[-1] # Get version from the $GITHUB_REF env var if this is a release if ( diff --git a/nf_core/pipelines/rocrate.py b/nf_core/pipelines/rocrate.py index b4735c2127..0bc0cf8e56 100644 --- a/nf_core/pipelines/rocrate.py +++ b/nf_core/pipelines/rocrate.py @@ -1,7 +1,6 @@ #!/usr/bin/env python """Code to deal with pipeline RO (Research Object) Crates""" -import json import logging import os import re @@ -103,7 +102,7 @@ def create_rocrate(self, json_path: None | Path = None, zip_path: None | Path = """ # Check that the checkout pipeline version is the same as the requested version - if self.version != "" and self.version != self.pipeline_obj.nf_config.get("manifest.version"): + if self.version and self.version != self.pipeline_obj.nf_config.get("manifest", {}).get("version"): # using git checkout to get the requested version log.info(f"Checking out pipeline version {self.version}") if self.pipeline_obj.repo is None: @@ -119,7 +118,7 @@ def create_rocrate(self, json_path: None | Path = None, zip_path: None | Path = except GitCommandError: log.error(f"Could not checkout version {self.version}") sys.exit(1) - self.version = self.pipeline_obj.nf_config.get("manifest.version", "") + self.version = self.pipeline_obj.nf_config.get("manifest", {}).get("version", "") self.make_workflow_rocrate() # Save just the JSON metadata file @@ -161,13 +160,14 @@ def make_workflow_rocrate(self) -> None: # Create the RO Crate object + manifest = self.pipeline_obj.nf_config.get("manifest", {}) self.crate = custom_make_crate( self.pipeline_dir, self.pipeline_dir / "main.nf", - self.pipeline_obj.nf_config.get("manifest.homePage", ""), - self.pipeline_obj.nf_config.get("manifest.name", ""), - self.pipeline_obj.nf_config.get("manifest.version", ""), - self.pipeline_obj.nf_config.get("manifest.nextflowVersion", ""), + manifest.get("homePage", ""), + manifest.get("name", ""), + manifest.get("version", ""), + manifest.get("nextflowVersion", ""), diagram=diagram, ) @@ -268,10 +268,11 @@ def add_main_authors(self, wf_file: rocrate.model.entity.Entity) -> None: """ Add workflow authors to the crate """ + manifest = self.pipeline_obj.nf_config.get("manifest", {}) contributors = [] - if "manifest.contributors" in self.pipeline_obj.nf_config: + if manifest.get("contributors"): contributors = self.parse_manifest_contributors() - if not contributors and "manifest.author" in self.pipeline_obj.nf_config: + if not contributors and manifest.get("author"): if self.pipeline_obj.repo: contributors = self.parse_manifest_authors() else: @@ -346,7 +347,7 @@ def _make_progress_bar(self): def parse_manifest_authors(self) -> list: # parse manifest.author" - authors = [a.strip() for a in self.pipeline_obj.nf_config["manifest.author"].split(",")] + authors = [a.strip() for a in self.pipeline_obj.nf_config.get("manifest", {}).get("author", "").split(",")] # remove duplicates authors = list(set(authors)) log.debug(f"Authors: {authors}") @@ -398,26 +399,14 @@ def parse_manifest_authors(self) -> list: # and return as a list of dictionaries def parse_manifest_contributors(self) -> list: field_names = ["name", "affiliation", "github", "contribution", "orcid", "email"] - # Grab the contributor list and convert to JSON - # TODO: can be removed once we switch to `nextflow config -o json` - contributors_str = self.pipeline_obj.nf_config["manifest.contributors"] - log.debug(f"manifest.contributors: {contributors_str}") - # JSON uses double quotes, not single quotes - contributors_str = contributors_str.replace("'", '"') - for key in field_names: - # All dictionary keys need to be quoted - contributors_str = contributors_str.replace(f"{key}:", f'"{key}":') - # Use curly brackets for dictionaries - contributors_str = contributors_str.replace("], [", "}, {").replace("[[", "[{").replace("]]", "}]") - log.debug(f"manifest.contributors (normalised): {contributors_str}") - try: - contributors = json.loads(contributors_str) - except json.JSONDecodeError as exc: + # Grab the contributor list directly from the nested config (already a list[dict]) + contributors = self.pipeline_obj.nf_config.get("manifest", {}).get("contributors", []) + log.debug(f"manifest.contributors: {contributors}") + if not isinstance(contributors, list): log.error( "Could not parse `manifest.contributors` from nextflow.config. " "Expected a list of maps, for example: [[name: 'First Last', github: 'user']]. " - f"Normalised string passed to JSON parser was: {contributors_str!r}. " - f"JSON decoding error: {exc}" + f"Got: {contributors!r}" ) return [] diff --git a/nf_core/pipelines/schema.py b/nf_core/pipelines/schema.py index e8f9cfe55a..c9b5558f23 100644 --- a/nf_core/pipelines/schema.py +++ b/nf_core/pipelines/schema.py @@ -93,16 +93,17 @@ def _update_validation_plugin_from_config(self) -> None: # Previous versions of nf-schema used "defs", but it's advised to use "$defs" if plugin == "nf-schema": self.defs_notation = "$defs" + validation = conf.get("validation", {}) + help_config = validation.get("help", {}) ignored_params = [ - conf.get("validation.help.shortParameter", "help"), - conf.get("validation.help.fullParameter", "helpFull"), - conf.get("validation.help.showHiddenParameter", "showHidden"), + help_config.get("shortParameter", "help"), + help_config.get("fullParameter", "helpFull"), + help_config.get("showHiddenParameter", "showHidden"), "trace_report_suffix", # report suffix should be ignored by default as it is a Java Date object ] # Help parameter should be ignored by default - ignored_params_config_str = conf.get("validation.defaultIgnoreParams", "") - ignored_params_config = [ - item.strip().strip("'") for item in ignored_params_config_str[1:-1].split(",") - ] # Extract list elements and remove whitespace + ignored_params_config = validation.get("defaultIgnoreParams", []) + if not isinstance(ignored_params_config, list): + ignored_params_config = [] if len(ignored_params_config) > 0: log.debug(f"Ignoring parameters from config: {ignored_params_config}") @@ -383,13 +384,13 @@ def validate_config_default_parameter(self, param, schema_param, config_default) return # if default is null, we're good - if config_default == "null": + if config_default is None or config_default == "null": return # Check variable types in nextflow.config - if schema_param["type"] == "string" and str(config_default) in ["false", "true", "''"]: + if schema_param["type"] == "string" and str(config_default).lower() in ["false", "true", "''"]: self.invalid_nextflow_config_default_parameters[param] = f"String should not be set to `{config_default}`" - if schema_param["type"] == "boolean" and str(config_default) not in ["false", "true"]: + if schema_param["type"] == "boolean" and str(config_default).lower() not in ["false", "true"]: self.invalid_nextflow_config_default_parameters[param] = ( f"Booleans should only be true or false, not `{config_default}`" ) @@ -761,16 +762,15 @@ def get_wf_params(self): log.debug("Collecting pipeline parameter defaults\n") config = nf_core.utils.fetch_wf_config(Path(self.schema_filename).parent) skipped_params = [] - # Pull out just the params. values - for ckey, cval in config.items(): - if ckey.startswith("params."): - # skip anything that's not a flat variable - if "." in ckey[7:]: - skipped_params.append(ckey) - continue - self.pipeline_params[ckey[7:]] = cval - if ckey.startswith("manifest."): - self.pipeline_manifest[ckey[9:]] = cval + # Pull out just the params values (top-level flat keys only) + for pkey, pval in config.get("params", {}).items(): + if isinstance(pval, dict): + skipped_params.append(f"params.{pkey}") + continue + self.pipeline_params[pkey] = pval + # Pull out manifest values + for mkey, mval in config.get("manifest", {}).items(): + self.pipeline_manifest[mkey] = mval # Log skipped params if len(skipped_params) > 0: log.debug( @@ -924,32 +924,30 @@ def build_schema_param(self, p_val): """ Build a pipeline schema dictionary for an param interactively """ + if p_val is None: + return {"type": "string"} + if isinstance(p_val, bool): + return {"type": "boolean", "default": p_val} if p_val else {"type": "boolean"} # no default for False + if isinstance(p_val, int): + return {"type": "integer", "default": p_val} + if isinstance(p_val, float): + return {"type": "number", "default": p_val} + + # TODO: remove string branch once old text-format config caches are no longer supported p_val = p_val.strip("\"'") - # p_val is always a string as it is parsed from nextflow config this way + if not p_val or p_val == "null": + return {"type": "string"} + if p_val in ("true", "True"): + return {"type": "boolean", "default": True} + if p_val in ("false", "False"): + return {"type": "boolean"} try: - p_val = float(p_val) - if p_val == int(p_val): - p_val = int(p_val) - p_type = "integer" - else: - p_type = "number" + num = float(p_val) + if num == int(num): + return {"type": "integer", "default": int(num)} + return {"type": "number", "default": num} except ValueError: - p_type = "string" - - # Anything can be "null", means that it is not set - if p_val == "null": - p_val = None - - # Booleans - if p_val in ["true", "false", "True", "False"]: - p_val = p_val in ["true", "True"] # Convert to bool - p_type = "boolean" - - # Don't return a default for anything false-y except 0 - if not p_val and not (p_val == 0 and p_val is not False): - return {"type": p_type} - - return {"type": p_type, "default": p_val} + return {"type": "string", "default": p_val} def launch_web_builder(self): """ diff --git a/nf_core/pipelines/sync.py b/nf_core/pipelines/sync.py index d5a167c6ba..003880491d 100644 --- a/nf_core/pipelines/sync.py +++ b/nf_core/pipelines/sync.py @@ -53,7 +53,7 @@ class PipelineSync: original_branch (str): Repo branch that was checked out before we started. made_changes (bool): Whether making the new template pipeline introduced any changes make_pr (bool): Whether to try to automatically make a PR on GitHub.com - required_config_vars (list): List of nextflow variables required to make template pipeline + required_config_vars (dict): Nextflow config variables required to make template pipeline, keyed by section gh_username (str): GitHub username gh_repo (str): GitHub repository name """ @@ -80,12 +80,9 @@ def __init__( self.made_changes = False self.make_pr = make_pr self.gh_pr_returned_data: dict = {} - self.required_config_vars = [ - "manifest.name", - "manifest.description", - "manifest.version", - "manifest.contributors", - ] + self.required_config_vars: dict[str, list[str]] = { + "manifest": ["name", "description", "version", "contributors"], + } self.force_pr = force_pr self.gh_username = gh_username @@ -231,9 +228,10 @@ def get_wf_config(self) -> None: self.wf_config = nf_core.utils.fetch_wf_config(Path(self.pipeline_dir)) # Check that we have the required variables - for rvar in self.required_config_vars: - if rvar not in self.wf_config: - raise SyncExceptionError(f"Workflow config variable `{rvar}` not found!") + for section, keys in self.required_config_vars.items(): + for key in keys: + if key not in self.wf_config.get(section, {}): + raise SyncExceptionError(f"Workflow config variable `{section}.{key}` not found!") def checkout_template_branch(self): """ @@ -320,7 +318,7 @@ def make_template_pipeline(self) -> None: from_config_file=True, no_git=True, force=True, - default_branch=self.wf_config.get("manifest.defaultBranch") or "master", + default_branch=self.wf_config.get("manifest", {}).get("defaultBranch") or "master", ) pipeline_create_obj.init_pipeline() diff --git a/nf_core/test_datasets/test_datasets_utils.py b/nf_core/test_datasets/test_datasets_utils.py index 7ed782cba4..61a7f60b30 100644 --- a/nf_core/test_datasets/test_datasets_utils.py +++ b/nf_core/test_datasets/test_datasets_utils.py @@ -204,7 +204,7 @@ def get_or_prompt_branch(maybe_branch: str) -> tuple[str, list[str]]: branch_prefill = MODULES_BRANCH_NAME elif repo_type == "pipeline": wf_config = fetch_wf_config(base_dir) - pipeline_name = wf_config.get("manifest.name", "").split("/")[-1] + pipeline_name = wf_config.get("manifest", {}).get("name", "").split("/")[-1] if pipeline_name in all_branches: branch_prefill = pipeline_name diff --git a/nf_core/utils.py b/nf_core/utils.py index b6973c8ca4..f8b7add797 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -25,6 +25,7 @@ from typing import TYPE_CHECKING, Any, Literal import git +import git.exc import prompt_toolkit.styles import questionary import requests.auth @@ -119,7 +120,7 @@ def unquote(s: str) -> str: Returns: String with outer quotes removed if present, otherwise original string """ - import ruamel.yaml + import ruamel.yaml.scalarstring if isinstance(s, ruamel.yaml.scalarstring.DoubleQuotedScalarString): return s @@ -271,12 +272,13 @@ def load_pipeline_config(self) -> bool: Once loaded, set a few convenience reference class attributes """ self.nf_config = fetch_wf_config(self.wf_path) + manifest = self.nf_config.get("manifest", {}) - self.pipeline_prefix, self.pipeline_name = self.nf_config.get("manifest.name", "/").strip("'").split("/") + self.pipeline_prefix, self.pipeline_name = manifest.get("name", "/").split("/") - nextflow_version_match = re.search(r"[0-9\.]+(-edge)?", self.nf_config.get("manifest.nextflowVersion", "")) + nextflow_version_match = re.search(r"(?P[0-9\.]+(-edge)?)", manifest.get("nextflowVersion", "") or "") if nextflow_version_match: - self.minNextflowVersion = nextflow_version_match.group(0) + self.minNextflowVersion = nextflow_version_match.group("version") return True return False @@ -395,7 +397,7 @@ def fetch_wf_config(wf_path: Path, cache_config: bool = True) -> dict: log.debug(f"Got '{wf_path}' as path") wf_path = Path(wf_path) - config = {} + config: dict[str, Any] = {} cache_fn = None cache_basedir = None cache_path = None @@ -440,35 +442,31 @@ def fetch_wf_config(wf_path: Path, cache_config: bool = True) -> dict: log.debug("No config cache found") # Call `nextflow config` - result = run_cmd("nextflow", f"config -flat {wf_path}") + result = run_cmd("nextflow", f"config -o json {wf_path}") if result is not None: nfconfig_raw, _ = result - nfconfig = nfconfig_raw.decode("utf-8") - multiline_key_value_pattern = re.compile(r"(^|\n)([^\n=\s]+?)\s*=\s*((?:(?!\n[^\n=]+?\s*=).)*)", re.DOTALL) - - for config_match in multiline_key_value_pattern.finditer(nfconfig): - k = config_match.group(2).strip() - v = config_match.group(3).strip().strip("'\"") - if k and v == "": - config[k] = "null" - log.debug(f"Config key: {k}, value: empty string") - elif k and v: - config[k] = v - log.debug(f"Config key: {k}, value: {v}") - else: - log.debug(f"Couldn't find key=value config pair:\n {config_match.group(0)}") - del config_match + try: + raw_str = nfconfig_raw.decode("utf-8") + json_start = raw_str.find("{") + parsed = json.loads(raw_str[json_start:] if json_start >= 0 else raw_str) + config.update(parsed) + for k in parsed: + log.debug(f"Config section: {k}") + except json.JSONDecodeError as e: + log.warning(f"Unable to parse nextflow config output as JSON: {e}") # Scrape main.nf for additional parameter declarations # Values in this file are likely to be complex, so don't both trying to capture them. Just get the param name. + + main_nf = Path(wf_path, "main.nf") try: - main_nf = Path(wf_path, "main.nf") with open(main_nf, "rb") as fh: + params_section = config.setdefault("params", {}) for line in fh: line_str = line.decode("utf-8") - match = re.match(r"^\s*(params\.[a-zA-Z0-9_]+)\s*=(?!=)", line_str) - if match and match.group(1): - config[match.group(1)] = "null" + match = re.match(r"^\s*params\.([a-zA-Z0-9_]+)\s*=(?!=)", line_str) + if match: + params_section[match.group(1)] = None except FileNotFoundError as e: log.debug(f"Could not open {main_nf} to look for parameter declarations - {e}") @@ -648,7 +646,7 @@ def lazy_init(self) -> None: """ log.debug("Initialising GitHub API requests session") cache_config = setup_requests_cachedir() - super().__init__(**cache_config) + super().__init__(**cache_config) # type: ignore[arg-type] self.setup_github_auth() self.has_init = True @@ -737,13 +735,13 @@ def safe_get(self, url): return request - def get(self, url, **kwargs): + def get(self, url, params=None, **kwargs): """ Initialise the session if we haven't already, then call the superclass get method. """ if not self.has_init: self.lazy_init() - return super().get(url, **kwargs) + return super().get(url, params=params, **kwargs) def request_retry(self, url, post_data=None): """ @@ -1127,17 +1125,12 @@ class SingularityCacheFilePathValidator(questionary.Validator): Validator for file path specified as --singularity-cache-index argument in nf-core pipelines download """ - def validate(self, value): - if len(value.text): - if Path(value.text).is_file(): - return True - else: - raise questionary.ValidationError( - message="Invalid remote cache index file", - cursor_position=len(value.text), - ) - else: - return True + def validate(self, document) -> None: + if len(document.text) and not Path(document.text).is_file(): + raise questionary.ValidationError( + message="Invalid remote cache index file", + cursor_position=len(document.text), + ) def get_repo_releases_branches(pipeline, wfs): @@ -1494,22 +1487,23 @@ def load_tools_config(directory: str | Path = ".") -> tuple[Path | None, NFCoreY template = tools_config.get("template") config_template_keys = template.keys() if template is not None else [] # Get author names from contributors first, then fallback to author - if "manifest.contributors" in wf_config: - contributors = wf_config["manifest.contributors"] - names = re.findall(r"name:'([^']+)'", contributors) + manifest = wf_config.get("manifest", {}) + contributors = manifest.get("contributors", []) + if contributors: + names = [c.get("name", "") for c in contributors if c.get("name")] author_names = ", ".join(names) - elif "manifest.author" in wf_config: - author_names = wf_config["manifest.author"].strip("'\"") + elif manifest.get("author"): + author_names = manifest.get("author", "") else: author_names = None if nf_core_yaml_config.template is None: # The .nf-core.yml file did not contain template information nf_core_yaml_config.template = NFCoreTemplateConfig( org="nf-core", - name=wf_config["manifest.name"].strip("'\"").split("/")[-1], - description=wf_config["manifest.description"].strip("'\""), + name=manifest.get("name", "/").split("/")[-1], + description=manifest.get("description", ""), author=author_names, - version=wf_config["manifest.version"].strip("'\""), + version=manifest.get("version", ""), outdir=str(directory), is_nfcore=True, ) @@ -1517,10 +1511,10 @@ def load_tools_config(directory: str | Path = ".") -> tuple[Path | None, NFCoreY # The .nf-core.yml file contained the old prefix or skip keys nf_core_yaml_config.template = NFCoreTemplateConfig( org=tools_config["template"].get("prefix", tools_config["template"].get("org", "nf-core")), - name=tools_config["template"].get("name", wf_config["manifest.name"].strip("'\"").split("/")[-1]), - description=tools_config["template"].get("description", wf_config["manifest.description"].strip("'\"")), + name=tools_config["template"].get("name", manifest.get("name", "/").split("/")[-1]), + description=tools_config["template"].get("description", manifest.get("description", "")), author=tools_config["template"].get("author", author_names), - version=tools_config["template"].get("version", wf_config["manifest.version"].strip("'\"")), + version=tools_config["template"].get("version", manifest.get("version", "")), outdir=tools_config["template"].get("outdir", str(directory)), skip_features=tools_config["template"].get("skip", tools_config["template"].get("skip_features")), is_nfcore=tools_config["template"].get("prefix", tools_config["template"].get("org")) == "nf-core", diff --git a/pyproject.toml b/pyproject.toml index a9e78a29e6..a263340cd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,6 +78,8 @@ dev = [ "types-setuptools", "typing_extensions>=4.0.0", "pytest-asyncio", + "pytest-clarity>=1.0.1", + "pytest-sugar>=1.1.1", "pytest-textual-snapshot==1.1.0", "pytest-workflow>=2.0.0", "pytest-xdist>=3.7.0", diff --git a/tests/pipelines/download/test_download.py b/tests/pipelines/download/test_download.py index 40228994cc..8000a4a413 100644 --- a/tests/pipelines/download/test_download.py +++ b/tests/pipelines/download/test_download.py @@ -241,7 +241,7 @@ def test_wf_use_local_configs(self, tmp_path): # Test the function download_obj.wf_use_local_configs("workflow") wf_config = nf_core.utils.fetch_wf_config(Path(test_outdir, "workflow"), cache_config=False) - assert wf_config["params.custom_config_base"] == f"{test_outdir}/workflow/../configs/" + assert wf_config["params"]["custom_config_base"] == f"{test_outdir}/workflow/../configs/" # # Test that `find_container_images` (uses `nextflow inspect`) fetches the correct Docker images diff --git a/tests/pipelines/download/test_singularity.py b/tests/pipelines/download/test_singularity.py index eb6bfe1bbb..78958dbcb6 100644 --- a/tests/pipelines/download/test_singularity.py +++ b/tests/pipelines/download/test_singularity.py @@ -456,11 +456,11 @@ def test_gather_registries_singularity(self, tmp_path, mock_cachedir_prompt, moc container_cache_index=None, ) mock_fetch_wf_config.return_value = { - "apptainer.registry": "apptainer-registry.io", - "docker.registry": "docker.io", - "podman.registry": "podman-registry.io", - "singularity.registry": "singularity-registry.io", - "someother.registry": "fake-registry.io", + "apptainer": {"registry": "apptainer-registry.io"}, + "docker": {"registry": "docker.io"}, + "podman": {"registry": "podman-registry.io"}, + "singularity": {"registry": "singularity-registry.io"}, + "someother": {"registry": "fake-registry.io"}, } singularity_fetcher.registry_set = singularity_fetcher.gather_registries(tmp_path) assert singularity_fetcher.registry_set diff --git a/tests/pipelines/lint/test_files_exist.py b/tests/pipelines/lint/test_files_exist.py index 6f5604d74f..2cef8aa105 100644 --- a/tests/pipelines/lint/test_files_exist.py +++ b/tests/pipelines/lint/test_files_exist.py @@ -19,7 +19,7 @@ def test_files_exist_missing_config(self): Path(self.new_pipeline, "CHANGELOG.md").unlink() assert self.lint_obj._load() - self.lint_obj.nf_config["manifest.name"] = "nf-core/testpipeline" + self.lint_obj.nf_config["manifest"]["name"] = "nf-core/testpipeline" results = self.lint_obj.files_exist() assert "File not found: `CHANGELOG.md`" in results["failed"] @@ -61,7 +61,7 @@ def test_files_exist_pass_conditional_nfschema(self): f.write(config) assert self.lint_obj._load() - self.lint_obj.nf_config["manifest.schema"] = "nf-core" + self.lint_obj.nf_config["manifest"]["schema"] = "nf-core" results = self.lint_obj.files_exist() assert results["failed"] == [] assert results["ignored"] == [] diff --git a/tests/pipelines/lint/test_multiqc_config.py b/tests/pipelines/lint/test_multiqc_config.py index 5da6e567ec..e3f691508f 100644 --- a/tests/pipelines/lint/test_multiqc_config.py +++ b/tests/pipelines/lint/test_multiqc_config.py @@ -104,7 +104,7 @@ def test_multiqc_config_report_comment_release_fail(self): lint_obj = nf_core.pipelines.lint.PipelineLint(self.new_pipeline) lint_obj._load() # bump version - lint_obj.nf_config["manifest.version"] = "1.0" + lint_obj.nf_config["manifest"]["version"] = "1.0" result = lint_obj.multiqc_config() # Reset the file with open(self.multiqc_config_yml, "w") as fh: diff --git a/tests/pipelines/lint/test_nextflow_config.py b/tests/pipelines/lint/test_nextflow_config.py index 63c58b149b..493aa49a76 100644 --- a/tests/pipelines/lint/test_nextflow_config.py +++ b/tests/pipelines/lint/test_nextflow_config.py @@ -34,7 +34,7 @@ def test_nextflow_config_bad_name_fail(self): lint_obj = nf_core.pipelines.lint.PipelineLint(self.new_pipeline) lint_obj.load_pipeline_config() - lint_obj.nf_config["manifest.name"] = "bad_name" + lint_obj.nf_config["manifest"]["name"] = "bad_name" result = lint_obj.nextflow_config() assert len(result["failed"]) > 0 assert len(result["warned"]) == 0 @@ -45,7 +45,7 @@ def test_nextflow_config_dev_in_release_mode_failed(self): lint_obj.load_pipeline_config() lint_obj.release_mode = True - lint_obj.nf_config["manifest.version"] = "dev_is_bad_name" + lint_obj.nf_config["manifest"]["version"] = "dev_is_bad_name" result = lint_obj.nextflow_config() assert len(result["failed"]) > 0 assert len(result["warned"]) == 0 @@ -105,9 +105,13 @@ def test_catch_params_assignment_in_main_nf(self): lint_obj.load_pipeline_config() result = lint_obj.nextflow_config() assert len(result["failed"]) == 2 + assert ( + result["failed"][0] + == "Config `params.custom_config_base` is not set to `https://raw.githubusercontent.com/nf-core/configs/master`" + ) assert ( result["failed"][1] - == "Config default value incorrect: `params.custom_config_base` is set as `https://raw.githubusercontent.com/nf-core/configs/master` in `nextflow_schema.json` but is `null` in `nextflow.config`." + == "Default value from the Nextflow schema `params.custom_config_base = `https://raw.githubusercontent.com/nf-core/configs/master`` not found in `nextflow.config`." ) def test_allow_params_reference_in_main_nf(self): diff --git a/tests/pipelines/lint/test_version_consistency.py b/tests/pipelines/lint/test_version_consistency.py index c7f7f28919..d11b3d3369 100644 --- a/tests/pipelines/lint/test_version_consistency.py +++ b/tests/pipelines/lint/test_version_consistency.py @@ -35,7 +35,7 @@ def test_version_consistency_pass(self): lint_obj.load_pipeline_config() lint_obj.nextflow_config() # Set the version for the container - lint_obj.nf_config["process.container"] = "nfcore/pipeline:1.0.0" + lint_obj.nf_config["process"]["container"] = "nfcore/pipeline:1.0.0" result = lint_obj.version_consistency() assert result["passed"] == [ "Version tags are consistent: manifest.version = 1.0.0, process.container = 1.0.0, nfcore_yml.version = 1.0.0", @@ -73,7 +73,7 @@ def test_version_consistency_not_consistent(self): lint_obj.load_pipeline_config() lint_obj.nextflow_config() - lint_obj.nf_config["process.container"] = "nfcore/pipeline:0.1" + lint_obj.nf_config["process"]["container"] = "nfcore/pipeline:0.1" result = lint_obj.version_consistency() assert len(result["passed"]) == 0 assert result["failed"] == [ diff --git a/tests/pipelines/test_bump_version.py b/tests/pipelines/test_bump_version.py index 3f34c18533..85c78e96a1 100644 --- a/tests/pipelines/test_bump_version.py +++ b/tests/pipelines/test_bump_version.py @@ -24,7 +24,7 @@ def test_bump_pipeline_version(self): # Check nextflow.config new_pipeline_obj.load_pipeline_config() - assert new_pipeline_obj.nf_config["manifest.version"].strip("'\"") == "1.1.0" + assert new_pipeline_obj.nf_config["manifest"]["version"].strip("'\"") == "1.1.0" # Check multiqc_config.yml with open(new_pipeline_obj._fp("assets/multiqc_config.yml")) as fh: @@ -47,7 +47,7 @@ def test_dev_bump_pipeline_version(self): # Check the pipeline config new_pipeline_obj.load_pipeline_config() - assert new_pipeline_obj.nf_config["manifest.version"].strip("'\"") == "1.2dev" + assert new_pipeline_obj.nf_config["manifest"]["version"].strip("'\"") == "1.2dev" def test_bump_nextflow_version(self): # Bump the version number to a specific version, preferably one @@ -58,7 +58,7 @@ def test_bump_nextflow_version(self): new_pipeline_obj._load() # Check nextflow.config - assert new_pipeline_obj.nf_config["manifest.nextflowVersion"].strip("'\"") == f"!>={version}" + assert new_pipeline_obj.nf_config["manifest"]["nextflowVersion"].strip("'\"") == f"!>={version}" # Check .github/workflows/nf-test.yml with open(new_pipeline_obj._fp(".github/workflows/nf-test.yml")) as fh: diff --git a/tests/pipelines/test_rocrate.py b/tests/pipelines/test_rocrate.py index 30df70f821..20ffbafd13 100644 --- a/tests/pipelines/test_rocrate.py +++ b/tests/pipelines/test_rocrate.py @@ -278,7 +278,7 @@ def test_parse_manifest_contributors_logs_parse_errors(self): # Set nf_config directly to avoid running nextflow config -flat on invalid Groovy syntax # (unquoted `alice` is valid Groovy but references an undefined variable, causing nextflow to fail) - self.rocrate_obj.pipeline_obj.nf_config["manifest.contributors"] = ( + self.rocrate_obj.pipeline_obj.nf_config["manifest"]["contributors"] = ( "[[\n name: 'Alice Example',\n github: alice\n]]" ) diff --git a/tests/pipelines/test_sync.py b/tests/pipelines/test_sync.py index aa27170f26..ffcf9bb9c1 100644 --- a/tests/pipelines/test_sync.py +++ b/tests/pipelines/test_sync.py @@ -143,14 +143,14 @@ def test_get_wf_config_missing_required_config(self): """Try getting a workflow config, then make it miss a required config option""" # Try to sync, check we halt with the right error psync = nf_core.pipelines.sync.PipelineSync(self.pipeline_dir) - psync.required_config_vars = ["fakethisdoesnotexist"] + psync.required_config_vars = {"fakesection": ["fakethisdoesnotexist"]} with pytest.raises(nf_core.pipelines.sync.SyncExceptionError) as exc_info: psync.inspect_sync_dir() psync.get_wf_config() # Check that we did actually get some config back - assert psync.wf_config["params.validate_params"] == "true" + assert psync.wf_config["params"]["validate_params"] is True # Check that we raised because of the missing fake config var - assert exc_info.value.args[0] == "Workflow config variable `fakethisdoesnotexist` not found!" + assert exc_info.value.args[0] == "Workflow config variable `fakesection.fakethisdoesnotexist` not found!" def test_checkout_template_branch(self): """Try checking out the TEMPLATE branch of the pipeline""" diff --git a/tests/test_utils.py b/tests/test_utils.py index fe5ff56d8e..aaf6e157bd 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -104,7 +104,7 @@ def test_rich_force_colours_true(self): def testload_pipeline_config(self): """Load the pipeline Nextflow config""" self.pipeline_obj.load_pipeline_config() - assert self.pipeline_obj.nf_config["dag.enabled"] == "true" + assert self.pipeline_obj.nf_config["dag"]["enabled"] is True # TODO nf-core: Assess and strip out if no longer required for DSL2 @@ -249,10 +249,10 @@ def test_set_wd_revert_on_raise(self): @mock.patch("nf_core.utils.run_cmd") def test_fetch_wf_config(self, mock_run_cmd): """Test the fetch_wf_config() regular expression to read config params.""" - mock_run_cmd.return_value = (b"params.param1 ? 'a=b' : ''\nparams.param2 = foo", b"mock") - config = nf_core.utils.fetch_wf_config(".", False) - assert len(config.keys()) == 1 - assert "params.param2" in list(config.keys()) + mock_run_cmd.return_value = (b'{"params": {"param2": "foo"}}', b"mock") + config = nf_core.utils.fetch_wf_config(Path(), False) + assert "params" in config + assert config["params"].get("param2") == "foo" @with_temporary_folder def test_get_wf_files(self, tmpdir): diff --git a/uv.lock b/uv.lock index ac0b46a1df..5038d67678 100644 --- a/uv.lock +++ b/uv.lock @@ -1654,8 +1654,10 @@ dev = [ { name = "myst-parser", version = "5.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pytest" }, { name = "pytest-asyncio" }, + { name = "pytest-clarity" }, { name = "pytest-cov" }, { name = "pytest-datafiles" }, + { name = "pytest-sugar" }, { name = "pytest-textual-snapshot" }, { name = "pytest-workflow" }, { name = "pytest-xdist" }, @@ -1693,8 +1695,10 @@ requires-dist = [ { name = "pygithub" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" }, { name = "pytest-asyncio", marker = "extra == 'dev'" }, + { name = "pytest-clarity", marker = "extra == 'dev'", specifier = ">=1.0.1" }, { name = "pytest-cov", marker = "extra == 'dev'" }, { name = "pytest-datafiles", marker = "extra == 'dev'" }, + { name = "pytest-sugar", marker = "extra == 'dev'", specifier = ">=1.1.1" }, { name = "pytest-textual-snapshot", marker = "extra == 'dev'", specifier = "==1.1.0" }, { name = "pytest-workflow", marker = "extra == 'dev'", specifier = ">=2.0.0" }, { name = "pytest-xdist", marker = "extra == 'dev'", specifier = ">=3.7.0" }, @@ -2153,6 +2157,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "pprintpp" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/06/1a/7737e7a0774da3c3824d654993cf57adc915cb04660212f03406334d8c0b/pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403", size = 17995, upload-time = "2018-07-01T01:42:34.87Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4e/d1/e4ed95fdd3ef13b78630280d9e9e240aeb65cc7c544ec57106149c3942fb/pprintpp-0.4.0-py2.py3-none-any.whl", hash = "sha256:b6b4dcdd0c0c0d75e4d7b2f21a9e933e5b2ce62b26e1a54537f9651ae5a5c01d", size = 16952, upload-time = "2018-07-01T01:42:36.496Z" }, +] + [[package]] name = "prek" version = "0.3.13" @@ -2601,6 +2614,17 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, ] +[[package]] +name = "pytest-clarity" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pprintpp" }, + { name = "pytest" }, + { name = "rich" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/5c/cafa97944de55738a6a2c5a7cee00d073cb80495032d2b112c4546525eca/pytest-clarity-1.0.1.tar.gz", hash = "sha256:505fe345fad4fe11c6a4187fe683f2c7c52c077caa1e135f3e483fe112db7772", size = 4891, upload-time = "2021-06-11T18:16:18.372Z" } + [[package]] name = "pytest-cov" version = "7.1.0" @@ -2627,6 +2651,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4b/23/88880d5dc36eac9696ad40823e37c1fdbfa81a67b9cfd0ed445b3ed7ec54/pytest_datafiles-3.0.1-py3-none-any.whl", hash = "sha256:c48f27a8afec03a482a10587ab5f5ab930ced4cbdeb2e3a2cbcc0323a51d22c7", size = 6357, upload-time = "2026-01-04T15:08:25.132Z" }, ] +[[package]] +name = "pytest-sugar" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, + { name = "termcolor" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/4e/60fed105549297ba1a700e1ea7b828044842ea27d72c898990510b79b0e2/pytest-sugar-1.1.1.tar.gz", hash = "sha256:73b8b65163ebf10f9f671efab9eed3d56f20d2ca68bda83fa64740a92c08f65d", size = 16533, upload-time = "2025-08-23T12:19:35.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/d5/81d38a91c1fdafb6711f053f5a9b92ff788013b19821257c2c38c1e132df/pytest_sugar-1.1.1-py3-none-any.whl", hash = "sha256:2f8319b907548d5b9d03a171515c1d43d2e38e32bd8182a1781eb20b43344cc8", size = 11440, upload-time = "2025-08-23T12:19:34.894Z" }, +] + [[package]] name = "pytest-textual-snapshot" version = "1.1.0" @@ -3334,6 +3371,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl", hash = "sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3", size = 39814, upload-time = "2026-03-04T18:55:31.284Z" }, ] +[[package]] +name = "termcolor" +version = "3.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/46/79/cf31d7a93a8fdc6aa0fbb665be84426a8c5a557d9240b6239e9e11e35fc5/termcolor-3.3.0.tar.gz", hash = "sha256:348871ca648ec6a9a983a13ab626c0acce02f515b9e1983332b17af7979521c5", size = 14434, upload-time = "2025-12-29T12:55:21.882Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/d1/8bb87d21e9aeb323cc03034f5eaf2c8f69841e40e4853c2627edf8111ed3/termcolor-3.3.0-py3-none-any.whl", hash = "sha256:cf642efadaf0a8ebbbf4bc7a31cec2f9b5f21a9f726f4ccbb08192c9c26f43a5", size = 7734, upload-time = "2025-12-29T12:55:20.718Z" }, +] + [[package]] name = "textual" version = "8.2.4" From b9c215dc42d4365b129e88b26389f7a3a6f7d1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Fri, 12 Jun 2026 19:48:51 -0400 Subject: [PATCH 058/135] feat: module lint for module name granularity --- nf_core/modules/lint/main_nf.py | 24 ++++++++++++++++++++++++ tests/modules/lint/test_main_nf.py | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 0b8df9c046..3d071aaaed 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -29,6 +29,10 @@ def main_nf( The following checks are performed: + * ``main_nf_module_granularity``: The module must represent a single command + as ```` or single subcommand with distinct functionality as + ````. + * ``main_nf_exists``: The ``main.nf`` file must exist. * ``deprecated_dsl2``: The file must not contain deprecated DSL2 identifiers @@ -64,6 +68,9 @@ def main_nf( emits: list[str] = [] topics: list[str] = [] + # Check the module name granularity + check_nf_module_name_modularity(module, module.component_name) + # Check if we have a patch file affecting the 'main.nf' file # otherwise read the lines directly from the module lines: list[str] = [] @@ -272,6 +279,23 @@ def main_nf( return inputs, emits +def check_nf_module_name_modularity(self, component_name): + """ + Lint the module granularity + Checks whether the module name has at most two levels of granularity. + """ + if component_name.count("/") > 1: + self.failed.append( + ("main_nf", "main_nf_module_granularity", "Module not named as `` or ``", self.main_nf) + ) + elif component_name.count("/") == 1: + self.passed.append( + ("main_nf", "main_nf_module_granularity", "Module properly named as ``", self.main_nf) + ) + else: + self.passed.append(("main_nf", "main_nf_module_granularity", "Module properly named as ``", self.main_nf)) + + def check_script_section(self, lines): """ Lint the script section diff --git a/tests/modules/lint/test_main_nf.py b/tests/modules/lint/test_main_nf.py index 1eddede4d9..c8c50de0e2 100644 --- a/tests/modules/lint/test_main_nf.py +++ b/tests/modules/lint/test_main_nf.py @@ -8,6 +8,7 @@ from nf_core.modules.lint.main_nf import ( _parse_output_topics, check_container_link_line, + check_nf_module_name_modularity, check_process_labels, check_process_section, check_script_section, @@ -18,6 +19,27 @@ from .test_lint_utils import MockModuleLint +@pytest.mark.parametrize( + "content,passed,warned,failed", + [ + # Valid module name + ("tar", 1, 0, 0), + # Valid module name + ("tabix/tabix", 1, 0, 0), + # Invalid module name + ("aws/s3/ls", 0, 0, 1), + ], +) +def test_module_name_granularity(content, passed, warned, failed): + """Test module name granularity""" + mock_lint = MockModuleLint() + check_nf_module_name_modularity(mock_lint, content) + + assert len(mock_lint.passed) == passed + assert len(mock_lint.warned) == warned + assert len(mock_lint.failed) == failed + + @pytest.mark.parametrize( "content,passed,warned,failed", [ From f8c7dfc5bffee05ef71c45dc1a006f32915f1b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Mon, 15 Jun 2026 09:39:49 +0200 Subject: [PATCH 059/135] Update tests/modules/test_modules_utils.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- tests/modules/test_modules_utils.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/modules/test_modules_utils.py b/tests/modules/test_modules_utils.py index 889c0ee2d4..ae0f0cfb02 100644 --- a/tests/modules/test_modules_utils.py +++ b/tests/modules/test_modules_utils.py @@ -94,10 +94,7 @@ def test_load_edam(self): cache_path = cache_dir / "EDAM.tsv" # Ensure clean state - if cache_dir.exists(): - for f in cache_dir.iterdir(): - f.unlink() - cache_dir.rmdir() + shutil.rmtree(cache_dir, ignore_errors=True) cache_dir.mkdir() From 38c1c20dcc6a2b69cc4d63504d4b40f5dfcee50d Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Mon, 15 Jun 2026 10:20:00 +0200 Subject: [PATCH 060/135] Update edam test --- tests/modules/test_modules_utils.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/tests/modules/test_modules_utils.py b/tests/modules/test_modules_utils.py index ae0f0cfb02..24e7a85bd2 100644 --- a/tests/modules/test_modules_utils.py +++ b/tests/modules/test_modules_utils.py @@ -1,4 +1,3 @@ -from pathlib import Path from unittest.mock import patch import nf_core.modules.modules_utils @@ -87,16 +86,10 @@ def test_filter_modules_by_name_empty_list(self): assert len(filtered) == 0 @patch("nf_core.modules.modules_utils.NFCORE_CACHE_DIR", new="test_cache") - def test_load_edam(self): + def test_load_edam(self, tmp_path): """Test EDAM ontology loading""" - cache_dir = Path("test_cache") - cache_path = cache_dir / "EDAM.tsv" - - # Ensure clean state - shutil.rmtree(cache_dir, ignore_errors=True) - - cache_dir.mkdir() + cache_path = tmp_path / "EDAM.tsv" # Cache should not exist before loading assert not cache_path.exists() @@ -111,8 +104,3 @@ def test_load_edam(self): assert isinstance(first_key, str) assert isinstance(first_value, tuple) assert len(first_value) == 2 - - # Cleanup (important since we're not using tmp_path) - for f in cache_dir.iterdir(): - f.unlink() - cache_dir.rmdir() From 2595f34923b95b2d0eac63c6188be3fdddcbcd56 Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Mon, 15 Jun 2026 10:31:01 +0200 Subject: [PATCH 061/135] Update test class --- tests/modules/test_modules_utils.py | 7 ++----- tests/test_modules.py | 4 ++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/modules/test_modules_utils.py b/tests/modules/test_modules_utils.py index 24e7a85bd2..0a71e213c7 100644 --- a/tests/modules/test_modules_utils.py +++ b/tests/modules/test_modules_utils.py @@ -1,5 +1,3 @@ -from unittest.mock import patch - import nf_core.modules.modules_utils from ..test_modules import TestModules @@ -85,11 +83,10 @@ def test_filter_modules_by_name_empty_list(self): filtered = nf_core.modules.modules_utils.filter_modules_by_name(modules, "fastqc") assert len(filtered) == 0 - @patch("nf_core.modules.modules_utils.NFCORE_CACHE_DIR", new="test_cache") - def test_load_edam(self, tmp_path): + def test_load_edam(self): """Test EDAM ontology loading""" - cache_path = tmp_path / "EDAM.tsv" + cache_path = self.tmp_path / "EDAM.tsv" # Cache should not exist before loading assert not cache_path.exists() diff --git a/tests/test_modules.py b/tests/test_modules.py index fce0c848ee..e40d914c01 100644 --- a/tests/test_modules.py +++ b/tests/test_modules.py @@ -179,3 +179,7 @@ def test_modulesrepo_class(self): @pytest.fixture(autouse=True) def _use_caplog(self, caplog): self.caplog = caplog + + @pytest.fixture(autouse=True) + def _tmp_path(self, tmp_path): + self.tmp_path = tmp_path From ef2e38464aa1af22dee6f7aa80969b3a01aa1f03 Mon Sep 17 00:00:00 2001 From: LouisLeNezet Date: Mon, 15 Jun 2026 10:38:16 +0200 Subject: [PATCH 062/135] Update test class --- tests/modules/test_modules_utils.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/tests/modules/test_modules_utils.py b/tests/modules/test_modules_utils.py index 0a71e213c7..dd72236c9f 100644 --- a/tests/modules/test_modules_utils.py +++ b/tests/modules/test_modules_utils.py @@ -1,3 +1,5 @@ +from unittest.mock import patch + import nf_core.modules.modules_utils from ..test_modules import TestModules @@ -86,18 +88,20 @@ def test_filter_modules_by_name_empty_list(self): def test_load_edam(self): """Test EDAM ontology loading""" - cache_path = self.tmp_path / "EDAM.tsv" + with patch( + "nf_core.modules.modules_utils.NFCORE_CACHE_DIR", + str(self.tmp_path), + ): + cache_path = self.tmp_path / "EDAM.tsv" - # Cache should not exist before loading - assert not cache_path.exists() + assert not cache_path.exists() - edam_formats = nf_core.modules.modules_utils.load_edam() + edam_formats = nf_core.modules.modules_utils.load_edam() - # Cache file should now exist - assert cache_path.exists() + assert cache_path.exists() - first_key, first_value = next(iter(edam_formats.items())) + first_key, first_value = next(iter(edam_formats.items())) - assert isinstance(first_key, str) - assert isinstance(first_value, tuple) - assert len(first_value) == 2 + assert isinstance(first_key, str) + assert isinstance(first_value, tuple) + assert len(first_value) == 2 From 70a6279dc4b12f08bae7a4a54cd9e062c15cb426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20Le=20N=C3=A9zet?= <58640615+LouisLeNezet@users.noreply.github.com> Date: Mon, 15 Jun 2026 16:03:01 +0200 Subject: [PATCH 063/135] Update CHANGELOG.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41da83f953..b053ad2b87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,7 +48,7 @@ ### Linting -- Store `EDAM.tsv` in `NFCORE_CACHE_DIR` and fix yaml comment loss ([#4242](https://github.com/nf-core/tools/pull/4242)) +- Store `EDAM.tsv` in `NFCORE_CACHE_DIR` and fix yaml comment loss when running `lint --fix` ([#4242](https://github.com/nf-core/tools/pull/4242)) ### Modules From 543055f97130e94c8a53120d7acf4607b37a1750 Mon Sep 17 00:00:00 2001 From: nf-core-bot Date: Tue, 16 Jun 2026 13:54:57 +0000 Subject: [PATCH 064/135] [automated] Update CHANGELOG.md [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15c49b35d7..fdd04b01a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ ### Modules - `modules info`: handle one element channels correctly ([#4268](https://github.com/nf-core/tools/pull/4268)) +- feat: module lint for module name granularity ([#4325](https://github.com/nf-core/tools/pull/4325)) ### Subworkflows From 2383503f7147c5b8848a9d4647b3ae59a05bd102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Tue, 16 Jun 2026 13:57:52 -0400 Subject: [PATCH 065/135] force ci trigger From 499807ab23d0e24c180749316a245fda7a8addba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Tue, 16 Jun 2026 21:42:30 -0400 Subject: [PATCH 066/135] feat: adding lint rule for module process name --- nf_core/modules/lint/main_nf.py | 28 +++++++++++++++++++++++----- tests/modules/lint/test_main_nf.py | 24 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 3d071aaaed..004a0624cb 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -412,11 +412,8 @@ def check_process_section( bioconda_packages = [] allowed_registries = registry - # Process name should be all capital letters - if all(x.upper() for x in self.process_name): - self.passed.append(("main_nf", "process_capitals", "Process name is in capital letters", self.main_nf)) - else: - self.failed.append(("main_nf", "process_capitals", "Process name is not in capital letters", self.main_nf)) + # Check that the process name is correctly formated from the component name + check_process_name_format(self, self.process_name, self.component_name) # Check that process labels are correct check_process_labels(self, lines) @@ -641,6 +638,27 @@ def check_process_section( return docker_tag == singularity_tag +def check_process_name_format(self, process_name, component_name): + """ + Lint the process name + Checks that the process name in the module file all is uppercase and derived + from the software and tool name separated by an underscore. + """ + # Process name should be all capital letters + if process_name.isupper(): + self.passed.append(("main_nf", "process_capitals", "Process name is in capital letters", self.main_nf)) + else: + self.failed.append(("main_nf", "process_capitals", "Process name is not in capital letters", self.main_nf)) + + # Process name should be made from the module name + if component_name.upper().replace("-", "").replace("/", "_") == process_name: + self.passed.append(("main_nf", "module_process_name", "Process name is derived from module name", self.main_nf)) + else: + self.failed.append( + ("main_nf", "module_process_name", "Process name is not derived from module name", self.main_nf) + ) + + def check_process_labels(self, lines): correct_process_labels = [ "process_single", diff --git a/tests/modules/lint/test_main_nf.py b/tests/modules/lint/test_main_nf.py index c8c50de0e2..7a822cc879 100644 --- a/tests/modules/lint/test_main_nf.py +++ b/tests/modules/lint/test_main_nf.py @@ -10,6 +10,7 @@ check_container_link_line, check_nf_module_name_modularity, check_process_labels, + check_process_name_format, check_process_section, check_script_section, ) @@ -40,6 +41,29 @@ def test_module_name_granularity(content, passed, warned, failed): assert len(mock_lint.failed) == failed +@pytest.mark.parametrize( + "process_name,component_name,passed,warned,failed", + [ + # Valid process name + ("STAR_ALIGN", "star/align", 2, 0, 0), + # Valid process name with dash + ("EAUTILS_GTF2BED", "ea-utils/gtf2bed", 2, 0, 0), + # Invalid process name, missing tool name + ("EIGSCIS", "cooltools/eigscis", 1, 0, 1), + # Invalid process name, missing tool name and small caps + ("cooltools/eigscis", "cooltools/eigscis", 0, 0, 2), + ], +) +def test_process_name_format(process_name, component_name, passed, warned, failed): + """Test process name format""" + mock_lint = MockModuleLint() + check_process_name_format(mock_lint, process_name, component_name) + + assert len(mock_lint.passed) == passed + assert len(mock_lint.warned) == warned + assert len(mock_lint.failed) == failed + + @pytest.mark.parametrize( "content,passed,warned,failed", [ From 8d62aad1cb28426bd8cc9120be01bd8797d7767b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Wed, 17 Jun 2026 07:13:10 -0400 Subject: [PATCH 067/135] fix broken test --- tests/modules/lint/test_main_nf.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/modules/lint/test_main_nf.py b/tests/modules/lint/test_main_nf.py index 7a822cc879..0e2ad76557 100644 --- a/tests/modules/lint/test_main_nf.py +++ b/tests/modules/lint/test_main_nf.py @@ -183,6 +183,7 @@ def test_container_links(content, passed, warned, failed): def test_check_process_section_additional_registries(container_line, additional_registries, should_pass, tmp_path): """Test that container_links passes/fails based on additional_registries from .nf-core.yml.""" mock_lint = MockModuleLint() + mock_lint.component_name = "tool/subtool" mock_lint.process_name = "TOOL_SUBTOOL" mock_lint.component_dir = tmp_path From 58575144511499f26f031c73b037c6b633c117b6 Mon Sep 17 00:00:00 2001 From: "James A. Fellows Yates" Date: Wed, 17 Jun 2026 13:39:29 +0200 Subject: [PATCH 068/135] Template: remove date placeholder from changelog title (#4333) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber Co-authored-by: nf-core-bot --- CHANGELOG.md | 1 + nf_core/pipeline-template/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdd04b01a6..7b6f7ce197 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - add `process_low_memory` resource label to `base.config` ([#4264](https://github.com/nf-core/tools/pull/4264)) - fix dead link ([#4307](https://github.com/nf-core/tools/pull/4307)) +- remove date placeholder from changelog title ([#4333](https://github.com/nf-core/tools/pull/4333)) #### Version updates diff --git a/nf_core/pipeline-template/CHANGELOG.md b/nf_core/pipeline-template/CHANGELOG.md index c9bd47f145..f69254be11 100644 --- a/nf_core/pipeline-template/CHANGELOG.md +++ b/nf_core/pipeline-template/CHANGELOG.md @@ -3,7 +3,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## v{{ version }} - [date] +## v{{ version }} - [unreleased] Initial release of {{ name }}, created with the [nf-core](https://nf-co.re/) template. From 174d33f663a0596e61927efc0f6043a3985d90ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Wed, 17 Jun 2026 07:54:12 -0400 Subject: [PATCH 069/135] adressing PR --- nf_core/modules/lint/main_nf.py | 4 ++-- tests/modules/lint/test_main_nf.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 004a0624cb..379fd56717 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -641,7 +641,7 @@ def check_process_section( def check_process_name_format(self, process_name, component_name): """ Lint the process name - Checks that the process name in the module file all is uppercase and derived + Checks that the process name in the module file is uppercase and derived from the software and tool name separated by an underscore. """ # Process name should be all capital letters @@ -651,7 +651,7 @@ def check_process_name_format(self, process_name, component_name): self.failed.append(("main_nf", "process_capitals", "Process name is not in capital letters", self.main_nf)) # Process name should be made from the module name - if component_name.upper().replace("-", "").replace("/", "_") == process_name: + if component_name.upper().replace("/", "_") == process_name: self.passed.append(("main_nf", "module_process_name", "Process name is derived from module name", self.main_nf)) else: self.failed.append( diff --git a/tests/modules/lint/test_main_nf.py b/tests/modules/lint/test_main_nf.py index 0e2ad76557..60e759f497 100644 --- a/tests/modules/lint/test_main_nf.py +++ b/tests/modules/lint/test_main_nf.py @@ -46,8 +46,6 @@ def test_module_name_granularity(content, passed, warned, failed): [ # Valid process name ("STAR_ALIGN", "star/align", 2, 0, 0), - # Valid process name with dash - ("EAUTILS_GTF2BED", "ea-utils/gtf2bed", 2, 0, 0), # Invalid process name, missing tool name ("EIGSCIS", "cooltools/eigscis", 1, 0, 1), # Invalid process name, missing tool name and small caps From 5ff8fd7e97655f7cf6ad37e6f74b91fa27c477a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jun 2026 12:09:50 +0200 Subject: [PATCH 070/135] Update pre-commit npm dependencies to v3.8.4 (#4335) Co-authored-by: nf-core-bot --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 1 + nf_core/.pre-commit-prettier-config.yaml | 2 +- nf_core/pipeline-template/.pre-commit-config.yaml | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9bd6c0ddb1..b6dd518ebc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - id: prettier entry: prettier --experimental-cli --write --ignore-unknown --no-cache additional_dependencies: - - prettier@3.8.3 + - prettier@3.8.4 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b6f7ce197..941eb7f076 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Coerce launch params_out to Path to fix AttributeError (#4299) ([#4317](https://github.com/nf-core/tools/pull/4317)) - generate valid Markdown when piping schema docs to file ([#4319](https://github.com/nf-core/tools/pull/4319)) - fix API docs bug in pydantic autodoc ([#4320](https://github.com/nf-core/tools/pull/4320)) +- Update pre-commit npm dependencies to v3.8.4 ([#4335](https://github.com/nf-core/tools/pull/4335)) ### Linting diff --git a/nf_core/.pre-commit-prettier-config.yaml b/nf_core/.pre-commit-prettier-config.yaml index d7235f440d..910d84508d 100644 --- a/nf_core/.pre-commit-prettier-config.yaml +++ b/nf_core/.pre-commit-prettier-config.yaml @@ -4,4 +4,4 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.8.3 + - prettier@3.8.4 diff --git a/nf_core/pipeline-template/.pre-commit-config.yaml b/nf_core/pipeline-template/.pre-commit-config.yaml index f51e1a28da..7bfe2466d0 100644 --- a/nf_core/pipeline-template/.pre-commit-config.yaml +++ b/nf_core/pipeline-template/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.8.3 + - prettier@3.8.4 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: From ae4e4650e01a0066fcf04e3648de27d8c111e324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Simoneau?= Date: Thu, 18 Jun 2026 15:12:38 -0400 Subject: [PATCH 071/135] feat: lint for module name lowercase and punctuation --- nf_core/modules/lint/main_nf.py | 28 +++++++++++++++++++++++----- tests/modules/lint/test_main_nf.py | 16 +++++++++------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 379fd56717..22b4e6d98e 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -68,8 +68,8 @@ def main_nf( emits: list[str] = [] topics: list[str] = [] - # Check the module name granularity - check_nf_module_name_modularity(module, module.component_name) + # Check the module name + check_nf_module_name(module, module.component_name) # Check if we have a patch file affecting the 'main.nf' file # otherwise read the lines directly from the module @@ -279,11 +279,29 @@ def main_nf( return inputs, emits -def check_nf_module_name_modularity(self, component_name): +def check_nf_module_name(self, component_name): """ - Lint the module granularity - Checks whether the module name has at most two levels of granularity. + Lint the module name + Checks whether the module name has at most two levels of granularity, no + punctuation and lowercase. """ + # Module name is lowercase + if component_name.islower(): + self.passed.append(("main_nf", "main_nf_module_lowercase", "Process name is lowercase", self.main_nf)) + else: + self.failed.append(("main_nf", "main_nf_module_lowercase", "Process name should be lowercase", self.main_nf)) + + # Module name has no punctuation + if component_name.replace("/", "").isalnum(): + self.passed.append( + ("main_nf", "main_nf_module_no_punctuation", "Module properly named without punctuation", self.main_nf) + ) + else: + self.failed.append( + ("main_nf", "main_nf_module_no_punctuation", "Module name should not have any punctuation", self.main_nf) + ) + + # Module name granularity if component_name.count("/") > 1: self.failed.append( ("main_nf", "main_nf_module_granularity", "Module not named as `` or ``", self.main_nf) diff --git a/tests/modules/lint/test_main_nf.py b/tests/modules/lint/test_main_nf.py index 60e759f497..399edc900f 100644 --- a/tests/modules/lint/test_main_nf.py +++ b/tests/modules/lint/test_main_nf.py @@ -8,7 +8,7 @@ from nf_core.modules.lint.main_nf import ( _parse_output_topics, check_container_link_line, - check_nf_module_name_modularity, + check_nf_module_name, check_process_labels, check_process_name_format, check_process_section, @@ -24,17 +24,19 @@ "content,passed,warned,failed", [ # Valid module name - ("tar", 1, 0, 0), + ("tar", 3, 0, 0), # Valid module name - ("tabix/tabix", 1, 0, 0), + ("tabix/tabix", 3, 0, 0), + # Invalid module name with punctuation and capital letters + ("ea-utils/GTF2BED", 1, 0, 2), # Invalid module name - ("aws/s3/ls", 0, 0, 1), + ("aws/s3/ls", 2, 0, 1), ], ) -def test_module_name_granularity(content, passed, warned, failed): - """Test module name granularity""" +def test_module_name_format(content, passed, warned, failed): + """Test module name format""" mock_lint = MockModuleLint() - check_nf_module_name_modularity(mock_lint, content) + check_nf_module_name(mock_lint, content) assert len(mock_lint.passed) == passed assert len(mock_lint.warned) == warned From 0a0a1dced7ecb67e05d055821a828fc923fe226b Mon Sep 17 00:00:00 2001 From: "James A. Fellows Yates" Date: Wed, 24 Jun 2026 12:22:45 +0200 Subject: [PATCH 072/135] Clarify execution context of nf-core modules test command (#4346) Co-authored-by: nf-core-bot --- CHANGELOG.md | 1 + nf_core/__main__.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 941eb7f076..ee052deaf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - `modules info`: handle one element channels correctly ([#4268](https://github.com/nf-core/tools/pull/4268)) - feat: module lint for module name granularity ([#4325](https://github.com/nf-core/tools/pull/4325)) +- Clarify execution context of nf-core modules test command ([#4346](https://github.com/nf-core/tools/pull/4346)) ### Subworkflows diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 2e77f1eb1d..43700ab2b7 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -1294,7 +1294,7 @@ def command_modules_create( ) def command_modules_test(ctx, tool, directory, no_prompts, update, once, profile, verbose): """ - Run nf-test for a module. + Run nf-test for a module. Only works on module repositories, not pipeline repositories. """ if verbose: ctx.obj["verbose"] = verbose From 3dba7b4693e4c6aba88088eef80180a2206b40d7 Mon Sep 17 00:00:00 2001 From: JulianFlesch Date: Wed, 24 Jun 2026 16:17:57 +0200 Subject: [PATCH 073/135] Implement wave container commands (#3954) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber Co-authored-by: JulianFlesch Co-authored-by: yuxinNing Co-authored-by: mashehu Co-authored-by: yuxinNing <92061677+ningyuxin1999@users.noreply.github.com> --- CHANGELOG.md | 2 + nf_core/__main__.py | 105 ++- nf_core/commands_modules.py | 140 +++- nf_core/commands_pipelines.py | 10 +- nf_core/components/components_command.py | 20 +- nf_core/components/components_utils.py | 21 + nf_core/components/create.py | 5 +- nf_core/components/nfcore_component.py | 95 +++ nf_core/modules/bump_versions.py | 20 +- nf_core/modules/containers.py | 741 ++++++++++++++++++ nf_core/modules/lint/__init__.py | 92 +-- nf_core/modules/lint/environment_yml.py | 193 ++++- nf_core/modules/lint/main_nf.py | 339 ++------ nf_core/modules/lint/meta_yml.py | 128 ++- nf_core/modules/lint/module_containers.py | 305 +++++++ nf_core/modules/modules_utils.py | 166 +++- nf_core/pipelines/download/docker.py | 3 +- nf_core/pipelines/download/download.py | 5 +- nf_core/pipelines/download/singularity.py | 2 +- nf_core/pipelines/download/utils.py | 26 - nf_core/pipelines/lint/__init__.py | 1 + nf_core/subworkflows/lint/__init__.py | 29 +- nf_core/subworkflows/lint/meta_yml.py | 7 +- nf_core/utils.py | 65 +- tests/components/test_components_utils.py | 19 + tests/modules/lint/test_environment_yml.py | 131 +++- tests/modules/lint/test_lint_utils.py | 8 + tests/modules/lint/test_main_nf.py | 27 +- tests/modules/lint/test_meta_yml.py | 16 +- tests/modules/lint/test_module_containers.py | 71 ++ .../lint/test_module_lint_integration.py | 9 +- .../modules/lint/test_module_lint_remotes.py | 2 +- tests/modules/test_containers.py | 355 +++++++++ tests/modules/test_modules_utils.py | 76 ++ tests/test_modules.py | 15 + 35 files changed, 2762 insertions(+), 487 deletions(-) create mode 100644 nf_core/modules/containers.py create mode 100644 nf_core/modules/lint/module_containers.py create mode 100644 tests/modules/lint/test_module_containers.py create mode 100644 tests/modules/test_containers.py diff --git a/CHANGELOG.md b/CHANGELOG.md index ee052deaf7..2e3af72c0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ - `modules info`: handle one element channels correctly ([#4268](https://github.com/nf-core/tools/pull/4268)) - feat: module lint for module name granularity ([#4325](https://github.com/nf-core/tools/pull/4325)) - Clarify execution context of nf-core modules test command ([#4346](https://github.com/nf-core/tools/pull/4346)) +- Add `nf-core modules containers create` to build module containers via Seqera Wave and record them in the `containers:` section of `meta.yml` ([#3954](https://github.com/nf-core/tools/pull/3954)) +- Container linting now validates the `containers:` section of `meta.yml` (Wave modules). The legacy `main.nf` container checks (URL reachability, registry prefix, docker/singularity tag match) have been removed; modules still using the old container syntax get a `deprecated_container_syntax` warning instead ([#3954](https://github.com/nf-core/tools/pull/3954)) ### Subworkflows diff --git a/nf_core/__main__.py b/nf_core/__main__.py index 43700ab2b7..ce79e8714a 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -9,6 +9,7 @@ import requests import rich.console import rich.logging +import rich.panel import rich.traceback import rich_click as click import rich_click.rich_click as rc @@ -17,6 +18,9 @@ from nf_core import __version__ from nf_core.commands_modules import ( modules_bump_versions, + modules_containers_conda_lock, + modules_containers_create, + modules_containers_list, modules_create, modules_info, modules_install, @@ -158,11 +162,14 @@ def nf_core_cli(ctx, verbose, hide_progress, log_file): # Set the base logger to output DEBUG log.setLevel(logging.DEBUG) - # Set up logs to the console + # Set up logs to the console - use the shared console so log output + # coordinates with progress spinners (avoids output on the same line) + from nf_core.pipelines.lint_utils import console as shared_console + log.addHandler( rich.logging.RichHandler( level=logging.DEBUG if verbose else logging.INFO, - console=rich.console.Console(stderr=True, force_terminal=rich_force_colors()), + console=shared_console, show_time=False, show_path=verbose, # True if verbose, false otherwise markup=True, @@ -901,7 +908,7 @@ def command_pipelines_schema_docs(directory, schema_file, output, output_format, help="Do not pull in latest changes to local clone of modules repository.", ) @click.command_panel("For pipeline development", commands=["list", "info", "install", "update", "remove", "patch"]) -@click.command_panel("For module development", commands=["create", "lint", "test", "bump-versions"]) +@click.command_panel("For module development", commands=["create", "lint", "test", "bump-versions", "containers"]) @click.pass_context def modules(ctx, git_remote, branch, no_pull): """ @@ -1438,6 +1445,98 @@ def command_modules_bump_versions(ctx, tool, directory, all_modules, show_all, d modules_bump_versions(ctx, tool, directory, all_modules, show_all, dry_run) +@modules.group("containers", aliases=["container", "con"]) +@click.pass_context +def modules_containers(ctx): + """Manage module container builds and metadata [yellow](beta)[/].""" + stderr.print( + rich.panel.Panel( + "The [bold]nf-core modules containers[/] commands are still in beta.\n" + "Their behaviour and output may change in future releases.\n" + "Best to always use the latest dev version.", + title="[bold][!] Beta feature", + title_align="left", + style="yellow", + ) + ) + + +# nf-core modules containers create +@modules_containers.command("create", aliases=["c"]) +@click.pass_context +@click.argument( + "module", + type=str, + required=False, + callback=normalize_case, + metavar=" or ", + shell_complete=autocomplete_modules, +) +@click.option( + "-d", + "--dir", + "directory", + type=click.Path(exists=True, path_type=Path), + default=".", + metavar="", +) +@click.option( + "-f", + "--force", + "force", + is_flag=True, + default=False, + help="Force container creation even if the container already exists.", +) +def command_modules_containers_create(ctx, module: str, directory: Path, force: bool) -> None: + """ + Build docker and singularity container files for linux/arm64 and linux/amd64 with wave from environment.yml and create container config file. + """ + modules_containers_create(ctx, module, directory, force) + + +@modules_containers.command("conda-lock") +@click.pass_context +@click.argument( + "module", + type=str, + required=False, + callback=normalize_case, + metavar=" or ", + shell_complete=autocomplete_modules, +) +def command_modules_containers_conda_lock(ctx, module: str) -> None: + """ + Build a Docker linux/arm64 container and fetch the conda lock file for a module. + """ + modules_containers_conda_lock(ctx, module) + + +# nf-core modules containers list +@modules_containers.command("list", aliases=["ls"]) +@click.pass_context +@click.argument( + "module", + type=str, + required=False, + callback=normalize_case, + metavar=" or ", + shell_complete=autocomplete_modules, +) +@click.option( + "-p", + "--plain-text", + is_flag=True, + default=False, + help="Output in plain text format", +) +def command_modules_containers_list(ctx, module, plain_text): + """ + Print containers defined in a module meta.yml. + """ + modules_containers_list(ctx, module, plain_text) + + # nf-core subworkflows click command @nf_core_cli.group(aliases=["s", "swf", "subworkflow"]) @click.option( diff --git a/nf_core/commands_modules.py b/nf_core/commands_modules.py index f4e48e0e4c..c2717b4852 100644 --- a/nf_core/commands_modules.py +++ b/nf_core/commands_modules.py @@ -1,9 +1,11 @@ import logging import sys +from pathlib import Path import rich -from nf_core.utils import rich_force_colors +from nf_core.pipelines.containers_utils import try_generate_container_configs +from nf_core.utils import CONTAINER_PLATFORMS, rich_force_colors log = logging.getLogger(__name__) stdout = rich.console.Console(force_terminal=rich_force_colors()) @@ -333,3 +335,139 @@ def modules_bump_versions(ctx, tool, directory, all_modules, show_all, dry_run): except (UserWarning, LookupError) as e: log.critical(e) sys.exit(1) + + +def modules_containers_create(ctx, module: str, directory: Path, force: bool) -> None: + """ + Build docker and singularity containers for linux/arm64 and linux/amd64 using wave. + """ + from rich.console import Group + from rich.live import Live + from rich.progress import BarColumn, MofNCompleteColumn, Progress, SpinnerColumn, TextColumn + + from nf_core.modules.containers import ModuleContainers + from nf_core.pipelines.lint_utils import console + + try: + manager = ModuleContainers(module=module, directory=directory, verbose=ctx.obj["verbose"]) + ModuleContainers.check_tower_token() + + # Normalize to a list of components: batch mode processes all available + # modules, single-module mode is just a list of one. + if manager.all_modules: + if not manager.available_modules: + log.error("No modules found to build containers for") + sys.exit(1) + log.info(f"Building containers for {len(manager.available_modules)} module(s)") + components = manager.available_modules + else: + assert manager.nfcore_component is not None + components = [manager.nfcore_component] + + failed_modules = [] + + overall_progress = Progress( + "[bold blue]{task.description}", + BarColumn(), + MofNCompleteColumn(), + console=console, + disable=ctx.obj["hide_progress"], + ) + module_progress = Progress( + SpinnerColumn(finished_text="[green]✓[/green]"), + "[bold blue]{task.description}", + TextColumn("{task.fields[status]}"), + console=console, + disable=ctx.obj["hide_progress"], + ) + + with Live(Group(overall_progress, module_progress), console=console, transient=True): + # The overall bar is only useful when processing more than one module + overall_task_id = overall_progress.add_task("modules", total=len(components), visible=len(components) > 1) + for component in components: + module_name = component.component_name + module_task_id = module_progress.add_task( + f"[cyan]{module_name}[/cyan]", + total=None, + status="building containers...", + ) + try: + if manager.all_modules: + # Per-module instance, reusing the already-scanned component list + module_manager = ModuleContainers( + module=module_name, + directory=directory, + verbose=ctx.obj["verbose"], + components=manager.available_modules, + ) + else: + module_manager = manager + _, success = module_manager.create( + progress_bar=module_progress, task_id=module_task_id, force=force + ) + if success: + module_manager.update_containers_in_meta() + if module_manager.repo_type == "pipeline": + try_generate_container_configs(directory, module_manager.module_directory) + else: + failed_modules.append(module_name) + except (ValueError, RuntimeError, OSError) as e: + log.error(f"✗ Failed to build containers for {module_name}: {e}") + failed_modules.append(module_name) + finally: + overall_progress.advance(overall_task_id) + module_progress.remove_task(module_task_id) + + if failed_modules: + if manager.all_modules: + log.warning( + f"Failed to build containers for {len(failed_modules)} module(s): {', '.join(failed_modules)}" + ) + else: + log.error(f"✗ Some container builds failed for {manager.module}") + sys.exit(1) + elif manager.all_modules: + log.info("Successfully built containers for all modules") + + except (UserWarning, LookupError, FileNotFoundError, ValueError, RuntimeError) as e: + log.error(e) + sys.exit(1) + + +def modules_containers_conda_lock(ctx, module, platform=CONTAINER_PLATFORMS[0]): + """ + Build a Docker linux/arm64 container and fetch the conda lock file using wave. + """ + from nf_core.modules.containers import ModuleContainers + + try: + manager = ModuleContainers(module, ".", verbose=ctx.obj["verbose"]) + lock_file = manager.get_conda_lock_file(platform) + stdout.print(lock_file) + except (UserWarning, LookupError, FileNotFoundError, ValueError, RuntimeError) as e: + log.error(e) + sys.exit(1) + + +def modules_containers_list(ctx, module, plain_text=False): + """ + Print containers defined in a module meta.yml. + """ + from nf_core.modules.containers import ModuleContainers + + try: + manager = ModuleContainers(module, ".", verbose=ctx.obj["verbose"]) + containers = manager.list_containers() + + if plain_text: + for cs, p, img in containers: + stdout.print(f"{cs} {p} {img}") + else: + t = rich.table.Table("Container System", "Platform") + t.add_column("Image", overflow="fold") + for cs, p, img in containers: + t.add_row(cs, p, img) + stdout.print(t) + except (UserWarning, LookupError, FileNotFoundError, ValueError) as e: + log.error(e) + sys.exit(1) diff --git a/nf_core/commands_pipelines.py b/nf_core/commands_pipelines.py index 9815d324d6..535ed074ca 100644 --- a/nf_core/commands_pipelines.py +++ b/nf_core/commands_pipelines.py @@ -95,7 +95,7 @@ def pipelines_bump_version(ctx, new_version, directory, nextflow): bump_pipeline_version(pipeline_obj, new_version) else: bump_nextflow_version(pipeline_obj, new_version) - except UserWarning as e: + except (UserWarning, ValueError) as e: log.error(e) sys.exit(1) @@ -162,8 +162,10 @@ def pipelines_lint( except AssertionError as e: log.critical(e) sys.exit(1) - except UserWarning as e: - log.error(e) + except (UserWarning, RuntimeError) as e: + from rich.text import Text + + log.error(Text.from_ansi(str(e))) sys.exit(1) @@ -359,7 +361,7 @@ def pipelines_sync( no_prompts, ) sync_obj.sync() - except (SyncExceptionError, PullRequestExceptionError) as e: + except (UserWarning, SyncExceptionError, PullRequestExceptionError) as e: log.error(e) sys.exit(1) diff --git a/nf_core/components/components_command.py b/nf_core/components/components_command.py index 2e01c245d3..7fffbf8e44 100644 --- a/nf_core/components/components_command.py +++ b/nf_core/components/components_command.py @@ -7,6 +7,7 @@ import nf_core.utils from nf_core.modules.modules_json import ModulesJson from nf_core.modules.modules_repo import ModulesRepo +from nf_core.modules.modules_utils import scan_modules_dir from .components_utils import get_repo_info @@ -74,12 +75,7 @@ def get_local_components(self) -> list[str]: Get the local modules/subworkflows in a pipeline """ local_component_dir = Path(self.directory, self.component_type, "local") - # TODO: Return list of Path objects instead of strings to avoid unnecessary conversion - return [ - str(Path(directory).relative_to(local_component_dir)) - for directory, _, files in os.walk(local_component_dir) - if "main.nf" in files - ] + [ + return scan_modules_dir(local_component_dir) + [ str(path.relative_to(local_component_dir)) for path in local_component_dir.iterdir() if path.suffix == ".nf" ] @@ -91,12 +87,7 @@ def get_components_clone_modules(self) -> list[str]: component_base_path = Path(self.directory, self.default_modules_path) elif self.component_type == "subworkflows": component_base_path = Path(self.directory, self.default_subworkflows_path) - # TODO: Return list of Path objects instead of strings to avoid unnecessary conversion - return [ - str(Path(directory).relative_to(component_base_path)) - for directory, _, files in os.walk(component_base_path) - if "main.nf" in files - ] + return scan_modules_dir(component_base_path) def has_valid_directory(self) -> bool: """Check that we were given a pipeline or clone of nf-core/modules""" @@ -162,10 +153,7 @@ def components_from_repo(self, install_dir: str) -> list[str]: if not repo_dir.exists(): raise LookupError(f"Nothing installed from {install_dir} in pipeline") - # TODO: Return list of Path objects instead of strings to avoid unnecessary conversion - return [ - str(Path(dir_path).relative_to(repo_dir)) for dir_path, _, files in os.walk(repo_dir) if "main.nf" in files - ] + return scan_modules_dir(repo_dir) def install_component_files( self, component_name: str, component_version: str, modules_repo: ModulesRepo, install_dir: str | Path diff --git a/nf_core/components/components_utils.py b/nf_core/components/components_utils.py index db33ad8b80..55238f2e8e 100644 --- a/nf_core/components/components_utils.py +++ b/nf_core/components/components_utils.py @@ -204,6 +204,27 @@ def get_components_to_install( return list(modules.values()), list(subworkflows.values()) +def read_meta_yml(meta_yml_path: Path) -> dict: + """ + Read and parse a meta.yml file. + + Args: + meta_yml_path: Path to the meta.yml file + + Returns: + dict: Parsed YAML content + + Raises: + FileNotFoundError: If meta.yml doesn't exist + """ + if not meta_yml_path.exists(): + raise FileNotFoundError(f"meta.yml not found at {meta_yml_path}") + + with open(meta_yml_path) as f: + meta = yaml.load(f) + return meta + + def get_biotools_response(tool_name: str) -> dict | None: """ Try to get bio.tools information for 'tool' diff --git a/nf_core/components/create.py b/nf_core/components/create.py index 270cf1355a..78e1c5f7d7 100644 --- a/nf_core/components/create.py +++ b/nf_core/components/create.py @@ -441,8 +441,9 @@ def generate_meta_yml_file(self) -> None: Generate the meta.yml file. """ # TODO: The meta.yml could be handled with a Pydantic model. The reason it is not implemented is because we want to maintain comments in the meta.yml file. - with open(self.file_paths["meta.yml"]) as fh: - meta_yml: ruamel.yaml.comments.CommentedMap = yaml.load(fh) + from nf_core.components.components_utils import read_meta_yml + + meta_yml: ruamel.yaml.comments.CommentedMap = read_meta_yml(self.file_paths["meta.yml"]) versions: dict[str, list | dict] = { f"versions_{self.component}": [ diff --git a/nf_core/components/nfcore_component.py b/nf_core/components/nfcore_component.py index 37744bf291..0fa3e19351 100644 --- a/nf_core/components/nfcore_component.py +++ b/nf_core/components/nfcore_component.py @@ -2,11 +2,14 @@ The NFCoreComponent class holds information and utility functions for a single module or subworkflow """ +import json import logging import re from pathlib import Path from typing import Any +from nf_core.utils import NF_INSPECT_MIN_NF_VERSION, check_nextflow_version, run_cmd, set_wd_tempdir + log = logging.getLogger(__name__) @@ -58,6 +61,9 @@ def __init__( self.is_patched: bool = False self.branch: str | None = None self.workflow_name: str | None = None + self.container: dict = {} + self.container_from_main_nf: str | None = None + self._meta_yml_content: dict | None = None if remote_component: # Initialize the important files @@ -109,6 +115,21 @@ def __init__( def __repr__(self) -> str: return f"" + def load_meta_yml(self, reload: bool = False) -> dict | None: + """ + Return the parsed content of the component's ``meta.yml``, cached after the first read. + + Pass ``reload=True`` after writing to ``meta.yml`` to refresh the cache. + Returns ``None`` if the component has no ``meta.yml``. + """ + if reload or self._meta_yml_content is None: + if self.meta_yml is None or not Path(self.meta_yml).exists(): + return None + from nf_core.components.components_utils import read_meta_yml + + self._meta_yml_content = read_meta_yml(Path(self.meta_yml)) + return self._meta_yml_content + def _get_main_nf_tags(self, test_main_nf: Path | str): """Collect all tags from the main.nf.test file.""" tags = [] @@ -377,3 +398,77 @@ def get_topics_from_main_nf(self) -> None: log.debug(f"Found {len(list(topics.keys()))} topics in {self.main_nf}") log.debug(f"Topics: {topics}") self.topics = topics + + def get_container_from_main_nf(self) -> str | None: + """Cached accessor for the (profile-agnostic) container resolved from ``main.nf``.""" + if self.container_from_main_nf is not None: + return self.container_from_main_nf + + self.container_from_main_nf = self.get_container_with_inspect() + + if not self.container_from_main_nf: + log.warning(f"No container was extracted for {self.component_name} from {self.main_nf}") + + return self.container_from_main_nf + + def get_container_with_inspect(self, profile: str | None = None) -> str | None: + """Resolve the container declared in the module's ``main.nf`` using ``nextflow inspect``. + + Running inspect lets Nextflow evaluate the container selection logic in the module + (and return the fully resolved container in its JSON output) instead of parsing it + with brittle regexes. Pass ``profile`` (e.g. ``"docker"`` or ``"singularity"``) to + resolve the container for a specific profile. + + Returns: + str | None: The resolved container, or ``None`` if it could not be resolved + (not a module, Nextflow too old to support ``nextflow inspect``, or inspect + failed). + """ + if self.component_type != "modules": + return None + + if not check_nextflow_version(NF_INSPECT_MIN_NF_VERSION, silent=True): + log.debug("Nextflow version too old to resolve containers with `nextflow inspect`") + return None + + main_nf_abs = self.main_nf.absolute() + + with set_wd_tempdir(): + # Provide a minimal nextflow.config to avoid falling back to docker branch when + # resolving singularity containers via `nextflow inspect`. + Path("nextflow.config").write_text( + "profiles {\n docker { docker.enabled = true }\n singularity { singularity.enabled = true }\n}\n" + ) + executable = "nextflow" + profile_param = f"-profile {profile} " if profile else "" + cmd_params = f"inspect {profile_param}-format json {main_nf_abs}" + try: + cmd_out = run_cmd(executable, cmd_params) + except RuntimeError: + cmd_out = None + if cmd_out is None: + log.debug("Failed to run `nextflow inspect`") + return None + out, _ = cmd_out + out_str = out.decode() + # nextflow inspect mixes status lines ([PIPELINE], [SUCCESS], etc.) with JSON on stdout + json_start = out_str.find("{") + json_end = out_str.rfind("}") + 1 + if json_start == -1 or json_end == 0: + log.debug("Could not find JSON in nextflow inspect output") + log.debug(f"Output of nextflow inspect: {out_str}") + return None + try: + out_json = json.loads(out_str[json_start:json_end]) + except json.JSONDecodeError: + log.debug("Failed to parse JSON from nextflow inspect output") + log.debug(f"Output of nextflow inspect: {out_str}") + return None + container = (out_json.get("processes") or [{}])[0].get("container", None) + if container is None: + log.debug( + f"Container for {self.component_name} could not be extracted from the output of nextflow inspect" + ) + log.debug(f"Output of nextflow inspect: {out_str}") + + return container diff --git a/nf_core/modules/bump_versions.py b/nf_core/modules/bump_versions.py index 7ab5da5855..eb0e923324 100644 --- a/nf_core/modules/bump_versions.py +++ b/nf_core/modules/bump_versions.py @@ -9,7 +9,6 @@ import re from pathlib import Path -import questionary import yaml from rich.box import ROUNDED from rich.console import Console @@ -94,24 +93,11 @@ def bump_versions( # Prompt for module or all if module is None and not all_modules: - self.require_prompts( - "No module name provided.\nPlease provide the module name as a command-line argument or use '--all'" + module = nf_core.modules.modules_utils.prompt_module_selection( + nfcore_modules, component_type="modules", action="Bump versions for" ) - question = { - "type": "list", - "name": "all_modules", - "message": "Bump versions for all modules or a single named module?", - "choices": ["All modules", "Named module"], - } - answer = questionary.unsafe_prompt([question], style=nf_core.utils.nfcore_question_style) - if answer["all_modules"] == "All modules": + if module is None: all_modules = True - else: - module = questionary.autocomplete( - "Tool name:", - choices=[m.component_name for m in nfcore_modules], - style=nf_core.utils.nfcore_question_style, - ).unsafe_ask() if module: self.show_up_to_date = True diff --git a/nf_core/modules/containers.py b/nf_core/modules/containers.py new file mode 100644 index 0000000000..bf7c1fee6d --- /dev/null +++ b/nf_core/modules/containers.py @@ -0,0 +1,741 @@ +import logging +import os +import re +import subprocess +from collections.abc import Callable +from concurrent.futures import ThreadPoolExecutor, as_completed +from pathlib import Path +from urllib.parse import quote + +import requests +import rich.progress +import yaml +from pydantic import ValidationError +from rich.pretty import pretty_repr + +from nf_core.components.components_utils import read_meta_yml +from nf_core.components.components_utils import yaml as ruamel_yaml +from nf_core.components.nfcore_component import NFCoreComponent +from nf_core.modules.lint import ModuleLint +from nf_core.modules.modules_utils import ( + CondaEntry, + ContainerEntry, + MetaYmlContainers, + filter_modules_by_name, + module_uses_dockerfile, + prompt_module_selection, + scan_modules_dir, +) +from nf_core.pipelines.lint_utils import run_prettier_on_file +from nf_core.utils import CONTAINER_PLATFORMS, CONTAINER_SYSTEMS, ContainerRegistryUrls, run_cmd + +log = logging.getLogger(__name__) + +WAVE_URL = "https://wave.seqera.io" + + +class ModuleContainers: + """ + Helpers for building, linting and listing module containers. + """ + + def __init__( + self, + module: str | None, + directory: str | Path = ".", + all_modules: bool = False, + verbose: bool = False, + components: list[NFCoreComponent] | None = None, + ): + from nf_core.components.components_utils import get_repo_info + + self.directory = Path(directory) + self.verbose = verbose + + # Detect repository type and organization + try: + _, self.repo_type, self.org = get_repo_info(self.directory, use_prompt=False) + except (UserWarning, FileNotFoundError): + self.repo_type = None + self.org = "nf-core" # Default to nf-core if repo info not available + + # Get available modules (local modules for pipelines, repo modules for modules repos). + # A pre-scanned list can be passed in to avoid re-scanning the modules directory. + self.available_modules = components if components is not None else self._get_available_modules() + + # Create a lookup dictionary for quick access by module name + self.components_by_name = {comp.component_name: comp for comp in self.available_modules} + + # Prompt for module selection if not provided + # Only allow "all modules" for pipeline repos + if module is None and not all_modules and len(self.available_modules) > 0: + allow_all = self.repo_type == "pipeline" + module = prompt_module_selection( + self.available_modules, component_type="modules", action="Build containers for", allow_all=allow_all + ) + # If None returned from prompt, user selected "All modules" (only possible in pipeline repos) + if module is None: + all_modules = True + + self.module = module + self.all_modules = all_modules + + # When a module name is given, use filter_modules_by_name so that a parent folder + # like "samtools" also selects submodules (samtools/sort, samtools/view, …). + matched: list[NFCoreComponent] = [] + if module is not None and not self.all_modules and self.available_modules: + matched = filter_modules_by_name(self.available_modules, module) + if len(matched) > 1: + # Prefix match returned several submodules – treat as a filtered "all" run + self.available_modules = matched + self.all_modules = True + + # Use NFCoreComponent to handle module directory and file paths + # For single module mode + if not self.all_modules: + # Try exact lookup in the components we already created + if module is not None and module in self.components_by_name: + self.nfcore_component: NFCoreComponent | None = self.components_by_name[module] + elif module is not None and self.available_modules: + if matched: + self.nfcore_component = matched[0] + else: + self.nfcore_component = self._init_nfcore_component(module) + elif module is not None: + # Fallback: no available_modules list, create component directly + self.nfcore_component = self._init_nfcore_component(module) + else: + raise ValueError("No module specified and no modules available") + + self.module_directory: Path | None = self.nfcore_component.component_dir + self.environment_yml: Path | None = self.nfcore_component.environment_yml + self.meta_yml: Path | None = self.nfcore_component.meta_yml + else: + # For all modules mode, these will be set per module during iteration + self.nfcore_component = None + self.module_directory = None + self.environment_yml = None + self.meta_yml = None + + self.containers: MetaYmlContainers | None = None + self._module_lint: ModuleLint | None = None + + @staticmethod + def check_tower_token() -> None: + """ + Check if TOWER_ACCESS_TOKEN is set and warn about API limits if not. + + Wave API has rate limits that can be increased by setting the TOWER_ACCESS_TOKEN + environment variable. This method checks if the token is set and logs a warning + if it's missing. + """ + if not os.environ.get("TOWER_ACCESS_TOKEN"): + log.warning( + "TOWER_ACCESS_TOKEN is not set. Wave API requests will be subject to stricter rate limits. \n" + "To increase your quota, set the TOWER_ACCESS_TOKEN environment variable with your Seqera Platform token. \n" + "See https://docs.seqera.io/wave/api#api-limits for more information." + ) + + def _get_available_modules(self) -> list[NFCoreComponent]: + """ + Get list of available modules based on repository type. + + For pipeline repos: Returns only local modules (modules/local/) + For modules repos: Returns modules from the repository + """ + if not self.repo_type: + log.debug("Could not determine repository type") + return [] + + if self.repo_type == "pipeline": + local_modules_dir = self.directory / "modules" / "local" + return [ + NFCoreComponent( + name, + None, + local_modules_dir / name, + self.repo_type, + self.directory, + "modules", + remote_component=False, + ) + for name in scan_modules_dir(local_modules_dir) + ] + elif self.repo_type == "modules": + return [ + self._init_nfcore_component(name) for name in scan_modules_dir(self.directory / "modules" / self.org) + ] + return [] + + def _init_nfcore_component(self, module: str) -> NFCoreComponent: + """Initialize NFCoreComponent for the module.""" + # Construct the correct module directory path + module_dir = self.directory / "modules" / self.org / module + return NFCoreComponent( + component_name=module, + repo_url="https://github.com/nf-core/modules.git", + component_dir=module_dir, + repo_type="modules", + base_dir=self.directory, + component_type="modules", + ) + + def _uses_dockerfile(self) -> bool: + """Return True if the module has a Dockerfile (in its dir or parent) but no environment.yml.""" + if self.nfcore_component is None: + return False + return module_uses_dockerfile(self.nfcore_component) + + def cleanup_stale_conda_lock_files(self, new_lock_files: set[Path]) -> None: + """ + Remove stale conda-lock files that are no longer in the new set. + + Args: + new_lock_files: Set of new conda lock file paths that should be kept + """ + if not self.module_directory: + return + + conda_lock_dir = self.module_directory / ".conda-lock" + if not conda_lock_dir.exists(): + return + + # Remove all files that aren't in the new set + for lock_file in conda_lock_dir.glob("*.txt"): + if lock_file not in new_lock_files: + try: + lock_file.unlink() + log.debug(f"Removed stale conda-lock file: {lock_file}") + except OSError as e: + log.warning(f"Failed to remove stale conda-lock file {lock_file}: {e}") + + # Clean up empty directory + try: + if not any(conda_lock_dir.iterdir()): + conda_lock_dir.rmdir() + log.debug(f"Removed empty .conda-lock directory: {conda_lock_dir}") + except OSError as e: + log.debug(f"Could not remove .conda-lock directory: {e}") + + def update_main_nf_container(self, force=False) -> None: + """Update the container name in main.nf using the docker amd64 image without registry. + Don't update if the container name is already correct. + """ + import re + + if self._uses_dockerfile(): + log.info(f"Module '{self.module}' uses a Dockerfile - skipping main.nf container update") + return + + if not self.containers or not self.nfcore_component: + log.warning("Cannot update main.nf: containers or nfcore_component not available") + return + + linux_amd64 = CONTAINER_PLATFORMS[0] + + # Get docker image + _docker_entry = self.containers.docker.get(linux_amd64) + docker_image = _docker_entry.name if _docker_entry else "" + if not docker_image: + log.error(f"No docker image found for {linux_amd64}") + return + + # Get singularity image, preferring the https download URL over the image name + _singularity_entry = self.containers.singularity.get(linux_amd64) + singularity_image = (_singularity_entry.https or _singularity_entry.name) if _singularity_entry else "" + if not singularity_image: + log.error(f"No singularity image found for {linux_amd64}") + return + + # Read main.nf + main_nf_path = self.nfcore_component.main_nf + content = main_nf_path.read_text() + + # Check if the container directive is already correct + if docker_image in content and singularity_image in content and not force: + log.debug(f"Container directive in `{self.nfcore_component.component_name}/main.nf` is already correct") + return + + # Replace container directive (may span multiple lines), preserving indentation. + # The directive uses double quotes on the outside and single quotes inside, so a + # non-greedy match up to the next double quote captures the whole ternary. + def _replace(match: "re.Match[str]") -> str: + indent = match.group(1) + inner_indent = indent + " " + return ( + f"{indent}container \"${{ workflow.containerEngine in ['singularity', 'apptainer'] " + "&& !task.ext.singularity_pull_docker_container\n" + f"? {inner_indent}'{singularity_image}'\n" + f": {inner_indent}'{docker_image}' }}\"" + ) + + new_content = re.sub( + r"^([ \t]*)container\s+\".*?\"", _replace, content, count=1, flags=re.DOTALL | re.MULTILINE + ) + + main_nf_path.write_text(new_content) + log.debug( + f"Updated container in `{self.nfcore_component.component_name}/main.nf` " + f"(docker: `{docker_image}`, singularity: `{singularity_image}`)" + ) + + def create( + self, + progress_bar: rich.progress.Progress | None = None, + task_id: rich.progress.TaskID | None = None, + force: bool = False, + ) -> tuple[MetaYmlContainers, bool]: + """ + Build docker and singularity containers for linux/amd64 and linux/arm64 using wave. + + Args: + progress_bar: Optional progress bar to use for tracking progress + task_id: Optional task ID for this module in the progress bar + + Returns: + Tuple of (MetaYmlContainers, success boolean). Success is False if any build failed. + """ + containers = MetaYmlContainers() + build_tasks = {} + threads = max(len(CONTAINER_SYSTEMS) * len(CONTAINER_PLATFORMS), 1) + has_failures = False + + if not self.environment_yml: + if self._uses_dockerfile(): + log.info(f"Module '{self.module}' uses a Dockerfile - skipping Wave container build") + return MetaYmlContainers(), True + raise RuntimeError("No environment.yml found.") + assert self.module_directory is not None + + # One spinner per build target — they run visually in parallel + build_task_ids: dict[tuple[str, str], rich.progress.TaskID] = {} + if progress_bar: + for cs in CONTAINER_SYSTEMS: + for platform in CONTAINER_PLATFORMS: + short_platform = platform.split("/")[-1] + build_task_ids[(cs, platform)] = progress_bar.add_task( + f" {cs}/{short_platform}", + total=1, + completed=0, + status="submitting wave build request...", + ) + + def make_on_build_id(cs: str, platform: str) -> Callable[[str], None]: + def callback(build_id: str) -> None: + build_tid = build_task_ids.get((cs, platform)) + if progress_bar and build_tid is not None: + url = f"{WAVE_URL}/view/builds/{build_id}" + progress_bar.update(build_tid, status=f"building… {url}") + + return callback + + # Submit all container build tasks + with ThreadPoolExecutor(max_workers=threads) as pool: + for cs in CONTAINER_SYSTEMS: + for platform in CONTAINER_PLATFORMS: + fut = pool.submit( + self.request_container, + cs, + platform, + self.environment_yml, + self.verbose, + make_on_build_id(cs, platform) if progress_bar else None, + ) + build_tasks[fut] = (cs, platform) + + # Process completed container builds + for fut in as_completed(build_tasks): + cs, platform = build_tasks[fut] + short_platform = platform.split("/")[-1] + build_tid = build_task_ids.get((cs, platform)) + + try: + getattr(containers, cs)[platform] = fut.result() + if progress_bar and build_tid is not None: + progress_bar.update(build_tid, completed=1, status="[green]done[/green]") + except (ValueError, RuntimeError, OSError, AssertionError) as e: + # make it a warning for arm (not required), but fail for other platforms + if platform == "linux/arm64": + log.warning( + f"Failed to build {cs} container for {platform}: {e}. This is only critical if the tool should support arm64." + ) + else: + log.error(f"Failed to build {cs} container for {platform}: {e}") + has_failures = True + if progress_bar and build_tid is not None: + progress_bar.update(build_tid, completed=1, status="[red]failed[/red]") + continue + + # Remove the per-build spinners now that all builds are done + if progress_bar: + for tid in build_task_ids.values(): + progress_bar.remove_task(tid) + + # Set containers early so get_conda_lock_file can access it + self.containers = containers + + # Download conda lock files as separate tasks + new_lock_files = set() + for platform in CONTAINER_PLATFORMS: + # Get docker build ID for this platform + _docker_entry = containers.docker.get(platform) + build_id = _docker_entry.build_id if _docker_entry else "" + short_platform = platform.split("/")[-1] + if not build_id: + log.debug(f"Docker image for {platform} missing - Conda-lock skipped") + if progress_bar and task_id is not None: + progress_bar.update(task_id, status=f"conda lock {short_platform} skipped") + continue + + conda_lock_path = self.module_directory / ".conda-lock" / f"{platform.replace('/', '_')}-{build_id}.txt" + conda_lock_path.parent.mkdir(parents=True, exist_ok=True) + + try: + # Download conda lock file (it will look up build_id from docker container) + log.debug(f"Downloading conda lock file for {platform} to {conda_lock_path}") + if progress_bar and task_id is not None: + progress_bar.update(task_id, status=f"conda lock {short_platform}...") + conda_lock_path.write_text(self.get_conda_lock_file(platform)) + # Only register the entry once the lock has actually been written, so + # meta.yml never points at a missing lock file. + containers.conda[platform] = CondaEntry(lock_file=str(conda_lock_path)) + new_lock_files.add(conda_lock_path) + if progress_bar and task_id is not None: + progress_bar.update(task_id, status=f"conda lock {short_platform} done") + + except (ValueError, OSError, requests.RequestException) as e: + # Wave does not always expose a conda lock for every build (e.g. some + # freshly built arm64 images). A missing lock is not fatal: keep the + # other platforms' containers and locks instead of failing the module. + log.warning(f"No conda lock file available for {platform}: {e}") + if progress_bar and task_id is not None: + progress_bar.update(task_id, status=f"conda lock {short_platform} unavailable") + + # Clean up stale conda-lock files + self.cleanup_stale_conda_lock_files(new_lock_files) + + # Persist everything (docker, singularity and conda locks) to meta.yml in a + # single write. Partial results are kept even if some builds failed. + if any(getattr(containers, cs) for cs in CONTAINER_SYSTEMS + ["conda"]): + try: + self.update_containers_in_meta() + log.debug("Updated meta.yml with built containers") + except (ValueError, RuntimeError, OSError) as meta_error: + log.warning(f"Failed to update meta.yml after container builds: {meta_error}") + + # Update main.nf with new container name (docker amd64 without registry) + try: + self.update_main_nf_container(force) + except OSError as e: + log.warning(f"Failed to update main.nf with container name: {e}") + has_failures = True + + return containers, not has_failures + + @staticmethod + def _extract_yaml_from_wave_output(output: str) -> str: + """ + Extract YAML content from Wave CLI output in verbose mode. + + Wave CLI with --log-level DEBUG outputs multi-line DEBUG logs before the YAML response. + This method finds the first line that looks like YAML (key: value format) and returns + everything from that point onwards. + + Args: + output: Raw stdout from Wave CLI + + Returns: + YAML content with DEBUG lines removed + """ + lines = output.splitlines() + for i, line in enumerate(lines): + # Look for lines that start with a simple word followed by colon (YAML key) + # Expected keys from Wave: buildId, cached, containerImage, duration, freeze, etc. + if "DEBUG" not in line and re.match(r"^[a-zA-Z]\w*:\s", line): + return "\n".join(lines[i:]) + # If no YAML start found, return original output + return output + + @classmethod + def request_container( + cls, + container_system: str, + platform: str, + conda_file: Path, + verbose=False, + on_build_id: Callable[[str], None] | None = None, + ) -> ContainerEntry: + assert conda_file.exists() + assert container_system in CONTAINER_SYSTEMS + assert platform in CONTAINER_PLATFORMS + + executable = "wave" + log_level = "DEBUG" if verbose else "INFO" + args = [ + "--conda-file", + str(conda_file.absolute()), + "--freeze", + "--platform", + platform, + "-o", + "yaml", + "--build-template", + "conda/pixi:v1", + "--log-level", + log_level, + ] + if container_system == "singularity": + args.append("--singularity") + args.append("--await") + + if on_build_id is not None: + # Stream stdout line-by-line so we can fire on_build_id as soon as + # "buildId:" appears in the debug output, without waiting for the build to finish. + try: + proc = subprocess.Popen([executable] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except FileNotFoundError as e: + raise RuntimeError( + f"It looks like {executable} is not installed. Please ensure it is available in your PATH." + ) from e + assert proc.stdout and proc.stderr + stdout_chunks: list[bytes] = [] + build_id_notified = False + for raw_line in proc.stdout: + stdout_chunks.append(raw_line) + if not build_id_notified: + m = re.search(rb"buildId:\s*(\S+)", raw_line) + if m: + on_build_id(m.group(1).decode().strip("\"'")) + build_id_notified = True + stderr_bytes = proc.stderr.read() + proc.wait() + if proc.returncode != 0: + raise RuntimeError( + f"wave command returned non-zero error code '{proc.returncode}':\n" + f"{stderr_bytes.decode()}{b''.join(stdout_chunks).decode()}" + ) + out: tuple[bytes, bytes] | None = (b"".join(stdout_chunks), stderr_bytes) + else: + args_str = " ".join(args) + out = run_cmd(executable, args_str) + + if out is None: + raise RuntimeError("Wave command did not return any output") + + # Log stderr when verbose (Wave outputs debug logs there) + if verbose and out[1]: + stderr_output = out[1].decode().strip() + if stderr_output: + for line in stderr_output.splitlines(): + log.info(line) + + # Parse Wave output + stdout_output = out[0].decode() + + # In verbose mode, Wave outputs DEBUG lines before YAML - extract only the YAML part + if verbose: + stdout_output = cls._extract_yaml_from_wave_output(stdout_output) + + try: + meta_data = yaml.safe_load(stdout_output) or {} + log.debug(f"Wave YAML metadata: \n{pretty_repr(meta_data)}") + except (KeyError, AttributeError, yaml.YAMLError) as e: + log.error(f"Failed to parse Wave output. Raw output:\n{stdout_output}") + raise RuntimeError(f"Could not parse wave YAML metadata ({container_system} {platform})") from e + if not meta_data.get("succeeded"): + raise RuntimeError( + f"Wave build ({container_system} {platform}) failed. Reason: {meta_data.get('reason', 'Unknown')}" + + ( + f"\nBuild log: {WAVE_URL}/view/builds/{meta_data.get('buildId')}" + if meta_data.get("buildId") + else "" + ) + ) + image = meta_data.get("targetImage") or meta_data.get("containerImage") or "" + if not image: + raise RuntimeError(f"Wave build ({container_system} {platform}) did not return an image name") + + build_id = meta_data.get("buildId", "") or "" + scan_id = "" + https_url = "" + + if container_system == "docker": + scan_id = meta_data.get("scanId", "") or "" + + if container_system == "singularity": + inspect_out = cls.request_image_inspect(image) + container_layers = inspect_out.get("container", {}).get("manifest", {}).get("layers", {}) + + if not ( + len(container_layers) == 1 + and container_layers[0].get("mediaType", "").endswith(".sif") + and container_layers[0].get("digest") + ): + log.warning(f"Https-url for image {image} could not be extracted from image inspect output") + + else: + log.debug(f"Extracting https-uri for {image} from image inspect:\n{pretty_repr(container_layers[0])}") + digest = container_layers[0]["digest"].replace("sha256:", "") + https_url = ( + f"https://{ContainerRegistryUrls.SEQERA_SINGULARITY.value}/blobs/sha256/{digest[:2]}/{digest}/data" + ) + + return ContainerEntry(name=image, build_id=build_id, scan_id=scan_id, https=https_url) + + @classmethod + def request_image_inspect(cls, image: str) -> dict: + """ + Request wave container inspect. + """ + executable = "wave" + args = ["--inspect", "-o yaml", "-i", image] + + args_str = " ".join(args) + log.debug(f"Wave command to request image inspect for image {image}: `wave {args_str}`") + out = run_cmd(executable, args_str) + + if out is None: + raise RuntimeError("Wave command did not return any output") + + try: + inspect_out = yaml.safe_load(out[0].decode()) or {} + except (KeyError, AttributeError, yaml.YAMLError) as e: + raise RuntimeError(f"Could not parse wave inspect yaml output for image {image}") from e + + return inspect_out + + @staticmethod + def get_conda_lock_url(build_id) -> str: + build_id_safe = quote(build_id, safe="") + url = f"{WAVE_URL}/v1alpha1/builds/{build_id_safe}/condalock" + return url + + def get_conda_lock_file(self, platform: str) -> str: + """ + Get the conda lock file for an existing environment. + Try (in that order): + 1. reading from meta.yml + 2. reading from cached containers + 3. recreating with wave commands + """ + assert platform in CONTAINER_PLATFORMS + + containers = self.containers or self.get_containers_from_meta() or self.create()[0] + + # Get build_id from docker container for this platform + _docker_entry = containers.docker.get(platform) if containers else None + build_id = _docker_entry.build_id if _docker_entry else None + if not build_id: + raise ValueError(f"No build_id found for docker container on platform {platform}") + + # Generate the conda lock URL from the build_id + conda_lock_url = self.get_conda_lock_url(build_id) + + resp = requests.get(conda_lock_url) + log.debug(f"Downloading conda lock file from {conda_lock_url}") + if resp.status_code != 200: + raise ValueError(f"Failed to download conda lock file from {conda_lock_url}") + log.debug(f"Successfully downloaded conda lock file from {conda_lock_url}") + return resp.text + + def list_containers(self) -> list[tuple[str, str, str]]: + """ + Return containers defined in the module meta.yml as a list of (, , ). + """ + containers_valid = self.get_containers_from_meta() + if not containers_valid: + return [] + containers_flat = [] + for cs in CONTAINER_SYSTEMS + ["conda"]: + for p in CONTAINER_PLATFORMS: + if cs == "conda": + conda_entry = containers_valid.conda.get(p) + if conda_entry: + containers_flat.append((cs, p, conda_entry.lock_file)) + else: + entry = getattr(containers_valid, cs).get(p) + if entry: + containers_flat.append((cs, p, entry.name)) + if cs == "singularity" and entry.https: + containers_flat.append((cs, p, entry.https)) + return containers_flat + + def get_containers_from_meta(self) -> MetaYmlContainers | None: + """ + Return containers defined in the module meta.yml. + Returns None if containers section is missing, incomplete, or invalid. + """ + if self.meta_yml is None or not self.meta_yml.exists(): + raise FileNotFoundError(f"No meta.yml found for module '{self.module}'") + + meta = read_meta_yml(self.meta_yml) + containers = meta.get("containers", {}) + if not containers: + log.debug(f"Section 'containers' missing from meta.yaml for module '{self.module}'") + return None + + try: + return MetaYmlContainers.model_validate(containers, context={"require_complete": True}) + except ValidationError as e: + log.debug(f"Could not parse containers from meta.yml: {e}") + return None + + def update_containers_in_meta(self, module_lint: ModuleLint | None = None) -> None: + """ + Update the containers section in meta.yml. + + Args: + module_lint: Optional ModuleLint instance to use for sorting. + If not provided, a new instance will be created. + """ + if self._uses_dockerfile(): + log.info(f"Module '{self.module}' uses a Dockerfile - skipping meta.yml container update") + return + + if self.containers is None: + log.debug("Containers not initialized - running `create()` ...") + self.containers, _ = self.create() + + if self.meta_yml is None or not self.meta_yml.exists(): + raise FileNotFoundError(f"No meta.yml found for module '{self.module}'") + + meta = read_meta_yml(self.meta_yml) + meta_containers = meta.get("containers", {}) + # Remove stale entries for all known systems/platforms so old containers don't + # mix with new ones when a build partially fails. + for cs in CONTAINER_SYSTEMS + ["conda"]: + for platform in CONTAINER_PLATFORMS: + meta_containers.get(cs, {}).pop(platform, None) + new_containers = self.containers.dump_for_meta_yml() + for cs, platforms in new_containers.items(): + for platform, data in platforms.items(): + if data: + meta_containers.setdefault(cs, {})[platform] = data + # Remove empty container system dicts left after clearing stale entries + meta_containers = {cs: platforms for cs, platforms in meta_containers.items() if platforms} + meta["containers"] = meta_containers + + # Sort the YAML according to the schema's property order using ModuleLint + # (constructed once per instance - it re-scans the modules repo) + if module_lint is None: + if self._module_lint is None: + try: + self._module_lint = ModuleLint(self.directory) + except (UserWarning, ValueError, OSError) as e: + log.warning(f"Failed to initialize ModuleLint for sorting: {e}") + module_lint = self._module_lint + + if module_lint is not None: + try: + meta = module_lint.sort_meta_yml(meta) + except UserWarning as e: + log.warning(f"Failed to sort meta.yml: {e}") + + with open(self.meta_yml, "w") as f: + ruamel_yaml.dump(meta, f) + + # Format with prettier for consistent styling + try: + run_prettier_on_file(self.meta_yml) + except (FileNotFoundError, OSError) as e: + log.debug(f"Could not run prettier on meta.yml: {e}") diff --git a/nf_core/modules/lint/__init__.py b/nf_core/modules/lint/__init__.py index aecc18b01b..f21c28b2d5 100644 --- a/nf_core/modules/lint/__init__.py +++ b/nf_core/modules/lint/__init__.py @@ -14,7 +14,6 @@ from pathlib import Path from typing import Any -import questionary import rich import rich.progress import ruamel.yaml @@ -29,9 +28,9 @@ log = logging.getLogger(__name__) -from .environment_yml import environment_yml +from .environment_yml import lint_environment_yml from .main_nf import main_nf -from .meta_yml import meta_yml, obtain_inputs, obtain_outputs, obtain_topics, read_meta_yml +from .meta_yml import meta_yml, meta_yml_containers, obtain_inputs, obtain_outputs, obtain_topics, read_meta_yml_patched from .module_changes import module_changes from .module_deprecations import module_deprecations from .module_patch import module_patch @@ -47,13 +46,13 @@ class ModuleLint(ComponentLint): """ # Import lint functions - environment_yml = environment_yml + environment_yml = lint_environment_yml main_nf = main_nf meta_yml = meta_yml obtain_inputs = obtain_inputs obtain_outputs = obtain_outputs obtain_topics = obtain_topics - read_meta_yml = read_meta_yml + read_meta_yml_patched = read_meta_yml_patched module_changes = module_changes module_deprecations = module_deprecations module_patch = module_patch @@ -123,24 +122,9 @@ def lint( # TODO: consider unifying modules and subworkflows lint() function and add it to the ComponentLint class # Prompt for module or all if module is None and not (local or all_modules) and len(self.all_remote_components) > 0: - questions = [ - { - "type": "list", - "name": "all_modules", - "message": "Lint all modules or a single named module?", - "choices": ["All modules", "Named module"], - }, - { - "type": "autocomplete", - "name": "tool_name", - "message": "Tool name:", - "when": lambda x: x["all_modules"] == "Named module", - "choices": [m.component_name for m in self.all_remote_components], - }, - ] - answers = questionary.unsafe_prompt(questions, style=nf_core.utils.nfcore_question_style) - all_modules = answers["all_modules"] == "All modules" - module = answers.get("tool_name") + module = nf_core.modules.modules_utils.prompt_module_selection( + self.all_remote_components, component_type="modules", action="Lint" + ) # Only lint the given module if module: @@ -239,6 +223,7 @@ def lint_module( mod.get_inputs_from_main_nf() mod.get_outputs_from_main_nf() mod.get_topics_from_main_nf() + # TODO container-conversion: get_containers from main_nf # Update meta.yml file if requested if self.fix and mod.meta_yml is not None: self.update_meta_yml_file(mod) @@ -248,7 +233,11 @@ def lint_module( continue if test_name == "main_nf": getattr(self, test_name)(mod, fix_version, self.registry, progress_bar) - elif test_name in ["meta_yml", "environment_yml"]: + elif test_name == "environment_yml": + getattr(self, test_name)( + mod, allow_missing=True, fix_version=fix_version, progress_bar=progress_bar + ) + elif test_name == "meta_yml": # Allow files to be missing for local getattr(self, test_name)(mod, allow_missing=True) else: @@ -266,6 +255,8 @@ def lint_module( mod.get_inputs_from_main_nf() mod.get_outputs_from_main_nf() mod.get_topics_from_main_nf() + # TODO container-conversion: get_containers from main_nf + # Update meta.yml file if requested if self.fix: self.update_meta_yml_file(mod) @@ -278,6 +269,8 @@ def lint_module( for test_name in self.lint_tests: if test_name == "main_nf": getattr(self, test_name)(mod, fix_version, self.registry, progress_bar) + elif test_name == "environment_yml": + getattr(self, test_name)(mod, fix_version=fix_version, progress_bar=progress_bar) else: getattr(self, test_name)(mod) @@ -312,11 +305,33 @@ def load_meta_schema(self) -> Mapping[str, Any]: self.meta_schema = json.load(fh) return self.meta_schema + def sort_meta_yml(self, meta_yml: dict) -> dict: + """Sort meta.yml keys according to the schema's property order. + + Recurses into nested objects that the schema describes with ``properties`` + (e.g. ``containers`` -> docker, singularity, conda), so sub-sections are sorted + too. Arrays, ``$ref``/``patternProperties`` nodes and scalars are left untouched. + """ + try: + schema = self.load_meta_schema() + except LintExceptionError as e: + raise UserWarning("Failed to load meta schema", e) from e + + def sort_by_schema(data, node): + properties = node.get("properties", {}) if isinstance(node, dict) else {} + if not isinstance(data, dict) or not properties: + return data + # Schema-ordered keys first (recursing into each), then any extras preserved + ordered = {key: sort_by_schema(data[key], child) for key, child in properties.items() if key in data} + return {**ordered, **{key: value for key, value in data.items() if key not in ordered}} + + return sort_by_schema(meta_yml, schema) + def update_meta_yml_file(self, mod): """ - Update the meta.yml file with the correct inputs and outputs + Update the meta.yml file with the correct inputs, outputs, topics and containers """ - meta_yml = self.read_meta_yml(mod) + meta_yml = self.read_meta_yml_patched(mod) if meta_yml is None: log.warning(f"Could not read meta.yml for {mod.component_name}, skipping update") return @@ -364,29 +379,6 @@ def check_match(element: dict) -> dict | None: return {} - def _sort_meta_yml(meta_yml: dict) -> dict: - """Sort meta.yml keys according to the schema's property order""" - # Get the schema to determine the correct key order - try: - schema = self.load_meta_schema() - schema_keys = list(schema["properties"].keys()) - except (LintExceptionError, KeyError) as e: - raise UserWarning("Failed to load meta schema", e) from e - - result: dict = {} - - # First, add keys in the order they appear in the schema - for key in schema_keys: - if key in meta_yml: - result[key] = meta_yml[key] - - # Then add any keys that aren't in the schema (to preserve custom keys) - for key in meta_yml: - if key not in result: - result[key] = meta_yml[key] - - return result - # Obtain inputs, outputs and topics from main.nf and meta.yml # Used to compare only the structure of channels and elements # Do not compare features to allow for custom features in meta.yml (i.e. pattern) @@ -699,7 +691,7 @@ def _ensure_string_keys(obj): else: return obj - corrected_meta_yml = _sort_meta_yml(corrected_meta_yml) + corrected_meta_yml = self.sort_meta_yml(corrected_meta_yml) corrected_meta_yml = _ensure_string_keys(corrected_meta_yml) with open(mod.meta_yml, "w") as fh: diff --git a/nf_core/modules/lint/environment_yml.py b/nf_core/modules/lint/environment_yml.py index 63b3aac752..45b3160433 100644 --- a/nf_core/modules/lint/environment_yml.py +++ b/nf_core/modules/lint/environment_yml.py @@ -4,9 +4,12 @@ import ruamel.yaml from jsonschema import exceptions, validators +from rich.progress import Progress -from nf_core.components.lint import ComponentLint, LintExceptionError +import nf_core.utils +from nf_core.components.lint import ComponentLint from nf_core.components.nfcore_component import NFCoreComponent +from nf_core.modules.modules_utils import module_uses_dockerfile log = logging.getLogger(__name__) @@ -15,7 +18,23 @@ yaml.indent(mapping=2, sequence=2, offset=2) -def environment_yml(module_lint_object: ComponentLint, module: NFCoreComponent, allow_missing: bool = False) -> None: +def _fix_module_version(self, current_version, latest_version): + """Update the conda package version in environment.yml.""" + with open(self.environment_yml) as source: + content = source.read() + new_content = content.replace(f"={current_version}", f"={latest_version}", 1) + with open(self.environment_yml, "w") as source: + source.write(new_content) + return True + + +def lint_environment_yml( + module_lint_object: ComponentLint, + module: NFCoreComponent, + allow_missing: bool = False, + fix_version: bool = False, + progress_bar: Progress | None = None, +) -> None: """ Lint an ``environment.yml`` file. @@ -25,8 +44,12 @@ def environment_yml(module_lint_object: ComponentLint, module: NFCoreComponent, The following checks are performed: - * ``environment_yml_exists``: The ``environment.yml`` file must exist if it is - referenced in ``main.nf``. + * ``environment_yml_exists``: The ``environment.yml`` file must exist, unless the + module has a Dockerfile. If neither ``environment.yml`` nor a Dockerfile is + present, the test fails. + + * ``environment_yml_dockerfile_conflict``: A module must not have both an + ``environment.yml`` and a Dockerfile; Remove the Dockerfile if present. * ``environment_yml_valid``: The ``environment.yml`` must be valid according to the JSON schema defined at https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json. @@ -34,6 +57,13 @@ def environment_yml(module_lint_object: ComponentLint, module: NFCoreComponent, * ``environment_yml_sorted``: The dependencies listed in ``environment.yml`` must be sorted alphabetically. If they are not, they will be sorted automatically. + + * ``bioconda_version``: The version specified for each bioconda package must + be a valid, known version available in the bioconda channel. + + * ``bioconda_latest``: Each bioconda package should be pinned to the latest + available version. A warning is raised (or the version updated if + ``fix_version`` is set) when a newer version exists. """ env_yml = None has_schema_header = False @@ -47,6 +77,16 @@ def environment_yml(module_lint_object: ComponentLint, module: NFCoreComponent, # load the environment.yml file if module.environment_yml is None: + if module_uses_dockerfile(module): + module.passed.append( + ( + "environment_yml", + "environment_yml_exists", + "Module's `environment.yml` does not exist, but module has a Dockerfile", + Path(module.component_dir, "environment.yml"), + ) + ) + return if allow_missing: module.warned.append( ( @@ -57,7 +97,15 @@ def environment_yml(module_lint_object: ComponentLint, module: NFCoreComponent, ), ) return - raise LintExceptionError("Module does not have an `environment.yml` file") + module.failed.append( + ( + "environment_yml", + "environment_yml_exists", + "Module's `environment.yml` does not exist and module has no Dockerfile", + Path(module.component_dir, "environment.yml"), + ) + ) + return try: # Read the entire file content to handle headers properly with open(module.environment_yml) as fh: @@ -86,6 +134,26 @@ def environment_yml(module_lint_object: ComponentLint, module: NFCoreComponent, ) ) + component_dir = Path(module.component_dir) + if (component_dir / "Dockerfile").exists() or (component_dir.parent / "Dockerfile").exists(): + module.failed.append( + ( + "environment_yml", + "environment_yml_dockerfile_conflict", + "Module has both an `environment.yml` and a Dockerfile; only one should be present", + module.environment_yml, + ) + ) + else: + module.passed.append( + ( + "environment_yml", + "environment_yml_dockerfile_conflict", + "Module does not have conflicting `environment.yml` and Dockerfile", + module.environment_yml, + ) + ) + except FileNotFoundError: # check if the module's main.nf requires a conda environment with open(Path(module.component_dir, "main.nf")) as fh: @@ -229,3 +297,118 @@ def sort_key(x): module.environment_yml, ) ) + + # Check bioconda package versions + if "dependencies" in env_yml: + bioconda_packages = [x for x in env_yml["dependencies"] if isinstance(x, str) and "bioconda::" in x] + for bp in bioconda_packages: + bp = bp.strip("'").strip('"') + try: + bioconda_version = bp.split("=")[1] + response = nf_core.utils.anaconda_package(bp) + module.passed.append( + ( + "environment_yml", + "bioconda_version", + f"Conda version specified correctly: {bp}", + module.environment_yml, + ) + ) + except LookupError: + module.warned.append( + ( + "environment_yml", + "bioconda_version", + f"Conda version not specified correctly: {bp}", + module.environment_yml, + ) + ) + except ValueError: + module.failed.append( + ( + "environment_yml", + "bioconda_version", + f"Conda version not specified correctly: {bp}", + module.environment_yml, + ) + ) + else: + # Check that required version is available at all + if bioconda_version not in response.get("versions"): + module.failed.append( + ( + "environment_yml", + "bioconda_version", + f"Conda package {bp} had unknown version: `{bioconda_version}`", + module.environment_yml, + ) + ) + continue # No need to test for latest version, continue linting + # Check version is latest available + last_ver = response.get("latest_version") + if last_ver is not None and last_ver != bioconda_version: + package, ver = bp.split("=", 1) + if fix_version: + try: + fixed = _fix_module_version(module, bioconda_version, last_ver) + except FileNotFoundError as e: + fixed = False + log.debug(f"Unable to update package {package} due to error: {e}") + else: + if fixed: + if progress_bar is not None: + progress_bar.print( + f"[blue]INFO[/blue]\t Updating package '{package}' {ver} -> {last_ver}" + ) + log.debug(f"Updating package {package} {ver} -> {last_ver}") + module.passed.append( + ( + "environment_yml", + "bioconda_latest", + f"Conda package has been updated to the latest available: `{bp}`", + module.environment_yml, + ) + ) + # If the version was updated, we should also try to rebuild the container to ensure it works with the new version + try: + from nf_core.modules.containers import ModuleContainers + + mc = ModuleContainers( + module=module.component_name, + directory=module.base_dir, + ) + mc.create(progress_bar=progress_bar) + except (ImportError, ValueError, RuntimeError, OSError) as e: + log.warning(f"Container rebuild after version update failed: {e}") + else: + if progress_bar is not None: + progress_bar.print( + f"[blue]INFO[/blue]\t Tried to update package. Unable to update package '{package}' {ver} -> {last_ver}" + ) + log.debug(f"Unable to update package {package} {ver} -> {last_ver}") + module.warned.append( + ( + "environment_yml", + "bioconda_latest", + f"Conda update: {package} `{ver}` -> `{last_ver}`", + module.environment_yml, + ) + ) + else: + module.warned.append( + ( + "environment_yml", + "bioconda_latest", + f"Conda update: {package} `{ver}` -> `{last_ver}`", + module.environment_yml, + ) + ) + else: + module.passed.append( + ( + "environment_yml", + "bioconda_latest", + f"Conda package is the latest available: `{bp}`", + module.environment_yml, + ) + ) diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 22b4e6d98e..1bbd11c1b0 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -4,15 +4,10 @@ import logging import re -import sqlite3 from pathlib import Path -from urllib.parse import urlparse, urlunparse -import requests -import yaml from rich.progress import Progress -import nf_core from nf_core.components.components_differ import ComponentsDiffer from nf_core.components.nfcore_component import NFCoreComponent @@ -41,9 +36,10 @@ def main_nf( * ``main_nf_script_outputs``: The process must have an ``output:`` block. - * ``main_nf_container``: Container tags across the ``singularity``, ``docker``, - and ``conda`` directives must reference the same software version. A warning - is issued if they do not match. + * ``main_nf_container``: When both a ``singularity`` and a ``docker`` container + are specified, their tags must reference the same software version. A warning + is issued if they do not match. Modules using the newer docker-only format + (no singularity container) skip this check. * ``main_nf_script_shell``: Exactly one of ``script:``, ``shell:``, or ``exec:`` blocks must be present. @@ -178,10 +174,13 @@ def main_nf( module.passed.append(("main_nf", "main_nf_script_outputs", "Process 'output' block found", module.main_nf)) # Check the process definitions - if check_process_section(module, process_lines, registry, fix_version, progress_bar): + containers_match = check_process_section(module, process_lines, registry, fix_version, progress_bar) + if containers_match is True: module.passed.append(("main_nf", "main_nf_container", "Container versions match", module.main_nf)) - else: + elif containers_match is False: module.warned.append(("main_nf", "main_nf_container", "Container versions do not match", module.main_nf)) + # ``None`` means only one (or no) container type was specified (e.g. the newer + # docker-only format), so there is nothing to compare and no check is emitted. # Check the when statement check_when_section(module, when_lines) @@ -416,19 +415,42 @@ def check_process_section( progress_bar (ProgressBar): Progress bar to update. Returns: - bool | None: True if singularity and docker containers match, False otherwise. If process definition does not exist, None. + bool | None: True if the singularity and docker container versions match, + False if they do not. None if the versions cannot be compared (e.g. modern + content-addressed Seqera containers, where the singularity URL carries no + version tag) or if the process definition does not exist. """ # Check that we have a process section if len(lines) == 0: self.failed.append(("main_nf", "process_exist", "Process definition does not exist", self.main_nf)) - return + return None self.passed.append(("main_nf", "process_exist", "Process definition exists", self.main_nf)) - # Checks that build numbers of bioconda, singularity and docker container are matching - singularity_tag = None - docker_tag = None - bioconda_packages = [] - allowed_registries = registry + # Resolve the docker and singularity containers via `nextflow inspect` rather than + # parsing the container ternary in main.nf with regexes. Running inspect once per + # profile lets Nextflow evaluate the container selection logic for us and return the + # fully resolved container in its JSON output. Either may be None if the corresponding + # container could not be resolved (e.g. Nextflow too old, or no such container). + docker_container = self.get_container_with_inspect(profile="docker") + singularity_container = self.get_container_with_inspect(profile="singularity") + + # `nextflow inspect -profile singularity` falls back to the docker container when the + # module has no singularity-specific image. A genuine singularity reference is a remote + # URL (`https://…`) or an `oras://…` reference, so anything else is the docker fallback + # and must not be treated as a singularity container. + if singularity_container is not None and not singularity_container.startswith(("https:", "oras:")): + singularity_container = None + + if singularity_container is not None: + self.passed.append( + ("main_nf", "singularity_tag", f"Found singularity container: {singularity_container}", self.main_nf) + ) + else: + self.failed.append(("main_nf", "singularity_tag", "Unable to resolve singularity container", self.main_nf)) + if docker_container is not None: + self.passed.append(("main_nf", "docker_tag", f"Found docker container: {docker_container}", self.main_nf)) + else: + self.failed.append(("main_nf", "docker_tag", "Unable to resolve docker container", self.main_nf)) # Check that the process name is correctly formated from the component name check_process_name_format(self, self.process_name, self.component_name) @@ -438,7 +460,6 @@ def check_process_section( # Deprecated enable_conda for _i, raw_line in enumerate(lines): - url = None line = raw_line.strip(" \n'\"}:?") # Catch preceding "container " @@ -446,8 +467,6 @@ def check_process_section( line = line.replace("container", "").strip(" \n'\"}:?") if _container_type(line) == "conda": - if "bioconda::" in line: - bioconda_packages = [b for b in line.split() if "bioconda::" in b] match = re.search(r"params\.enable_conda", line) if match is None: self.passed.append( @@ -467,193 +486,22 @@ def check_process_section( self.main_nf, ) ) - if _container_type(line) == "singularity": - # e.g. "https://containers.biocontainers.pro/s3/SingImgsRepo/biocontainers/v1.2.0_cv1/biocontainers_v1.2.0_cv1.img -> v1.2.0_cv1 - # e.g. "https://depot.galaxyproject.org/singularity/fastqc:0.11.9--0 -> 0.11.9--0 - # Please god let's find a better way to do this than regex - match = re.search(r"(?:[:.])?([A-Za-z\d\-_.]+?)(?:\.img)?(?:\.sif)?$", line) - if match is not None: - singularity_tag = match.group(1) - self.passed.append( - ("main_nf", "singularity_tag", f"Found singularity tag: {singularity_tag}", self.main_nf) - ) - else: - self.failed.append(("main_nf", "singularity_tag", "Unable to parse singularity tag", self.main_nf)) - singularity_tag = None - url = urlparse(line.split("'")[0]) - - if _container_type(line) == "docker": - # e.g. "quay.io/biocontainers/krona:2.7.1--pl526_5 -> 2.7.1--pl526_5 - # e.g. "biocontainers/biocontainers:v1.2.0_cv1 -> v1.2.0_cv1 - match = re.search(r":([A-Za-z\d\-_.]+)$", line) - if match is not None: - docker_tag = match.group(1) - self.passed.append(("main_nf", "docker_tag", f"Found docker tag: {docker_tag}", self.main_nf)) - else: - self.failed.append(("main_nf", "docker_tag", "Unable to parse docker tag", self.main_nf)) - docker_tag = None - if line.startswith(allowed_registries): - l_stripped = re.sub(r"\W+$", "", line) - self.passed.append( - ( - "main_nf", - "container_links", - f"Container prefix is correct: {l_stripped}", - self.main_nf, - ) - ) - else: - self.failed.append( - ( - "main_nf", - "container_links", - f"Container prefix is not correct. Please add one of the allowed registry prefixes: {', '.join(f'{r}' for r in allowed_registries)}", - self.main_nf, - ) - ) - - url = urlparse(line.split("'")[0]) if line.startswith("container") or _container_type(line) == "docker" or _container_type(line) == "singularity": check_container_link_line(self, raw_line, registry) - # Try to connect to container URLs - if url is None: - continue - try: - container_url = "https://" + urlunparse(url) if url.scheme != "https" else urlunparse(url) - log.debug(f"Trying to connect to URL: {container_url}") - response = requests.head( - container_url, - stream=True, - allow_redirects=True, - ) - log.debug( - f"Connected to URL: {'https://' + urlunparse(url) if url.scheme != 'https' else urlunparse(url)}, " - f"status_code: {response.status_code}" - ) - except (requests.exceptions.RequestException, sqlite3.InterfaceError) as e: - log.debug(f"Unable to connect to url '{urlunparse(url)}' due to error: {e}") - self.failed.append(("main_nf", "container_links", "Unable to connect to container URL", self.main_nf)) - continue - if not response.ok: - self.warned.append( - ( - "main_nf", - "container_links", - f"Unable to connect to container registry, code: {response.status_code}, url: {response.url}", - self.main_nf, - ) - ) - - # Get bioconda packages from environment.yml - try: - with open(Path(self.component_dir, "environment.yml")) as fh: - env_yml = yaml.safe_load(fh) - if "dependencies" in env_yml: - bioconda_packages = [x for x in env_yml["dependencies"] if isinstance(x, str) and "bioconda::" in x] - except FileNotFoundError: - pass - except NotADirectoryError: - pass - - # Check that all bioconda packages have build numbers - # Also check for newer versions - for bp in bioconda_packages: - bp = bp.strip("'").strip('"') - # Check for correct version and newer versions - try: - bioconda_version = bp.split("=")[1] - # response = _bioconda_package(bp) - response = nf_core.utils.anaconda_package(bp) - self.passed.append( - ("main_nf", "bioconda_version", f"Conda version specified correctly: {bp}", self.main_nf) - ) - except LookupError: - self.warned.append( - ("main_nf", "bioconda_version", f"Conda version not specified correctly: {bp}", self.main_nf) - ) - except ValueError: - self.failed.append( - ("main_nf", "bioconda_version", f"Conda version not specified correctly: {bp}", self.main_nf) - ) - else: - # Check that required version is available at all - if bioconda_version not in response.get("versions"): - self.failed.append( - ( - "main_nf", - "bioconda_version", - f"Conda package {bp} had unknown version: `{bioconda_version}`", - self.main_nf, - ) - ) - continue # No need to test for latest version, continue linting - # Check version is latest available - last_ver = response.get("latest_version") - if last_ver is not None and last_ver != bioconda_version: - package, ver = bp.split("=", 1) - # If a new version is available and fix is True, update the version - if fix_version: - try: - fixed = _fix_module_version(self, bioconda_version, last_ver, singularity_tag, response) - except FileNotFoundError as e: - fixed = False - log.debug(f"Unable to update package {package} due to error: {e}") - else: - if fixed: - if progress_bar is not None: - progress_bar.print( - f"[blue]INFO[/blue]\t Updating package '{package}' {ver} -> {last_ver}" - ) - log.debug(f"Updating package {package} {ver} -> {last_ver}") - self.passed.append( - ( - "main_nf", - "bioconda_latest", - f"Conda package has been updated to the latest available: `{bp}`", - self.main_nf, - ) - ) - else: - if progress_bar is not None: - progress_bar.print( - f"[blue]INFO[/blue]\t Tried to update package. Unable to update package '{package}' {ver} -> {last_ver}" - ) - log.debug(f"Unable to update package {package} {ver} -> {last_ver}") - self.warned.append( - ( - "main_nf", - "bioconda_latest", - f"Conda update: {package} `{ver}` -> `{last_ver}`", - self.main_nf, - ) - ) - # Add available update as a warning - else: - self.warned.append( - ( - "main_nf", - "bioconda_latest", - f"Conda update: {package} `{ver}` -> `{last_ver}`", - self.main_nf, - ) - ) - else: - self.passed.append( - ( - "main_nf", - "bioconda_latest", - f"Conda package is the latest available: `{bp}`", - self.main_nf, - ) - ) - - # Check if a tag exists at all. If not, return None. - if singularity_tag is None or docker_tag is None: + # Compare versions only when both resolved containers expose a parseable version tag. + # Legacy biocontainers-style URLs carry a shared `:` tag (e.g. `:0.11.9--0`) + # on both the docker and singularity side, so a mismatch flags an author error. Modern + # Seqera containers are content-addressed (the singularity URL is a sha digest with no + # version), so there is nothing to compare and we return None. + if docker_container is None or singularity_container is None: return None - else: - return docker_tag == singularity_tag + docker_match = re.search(r":([A-Za-z\d\-_.]+)$", docker_container) + singularity_match = re.search(r":([A-Za-z\d\-_.]+)$", singularity_container) + if docker_match is None or singularity_match is None: + return None + return docker_match.group(1) == singularity_match.group(1) def check_process_name_format(self, process_name, component_name): @@ -747,6 +595,7 @@ def check_container_link_line(self, raw_line, registry): """Look for common problems in the container name / URL, for docker and singularity.""" line = raw_line.strip(" \n'\"}:?") + log.debug(f"container line: '{line}'") # lint double quotes if line.count('"') > 2: @@ -775,8 +624,10 @@ def check_container_link_line(self, raw_line, registry): # (if there are multiple links, this will be warned in the next check) container_link = None if len(single_quoted_items) == 3 or len(single_quoted_items) == 5 and " in [" in raw_line: + log.debug(f"Single-quoted container link: '{single_quoted_items[1]}'") container_link = single_quoted_items[1] elif len(double_quoted_items) == 3: + log.debug(f"Double-quoted container link: '{double_quoted_items[1]}'") container_link = double_quoted_items[1] if container_link: if " " in container_link: @@ -798,6 +649,28 @@ def check_container_link_line(self, raw_line, registry): ) ) + # Check container registry prefix. + if _container_type(container_link) == "docker": + if container_link.startswith(registry): + self.passed.append( + ( + "main_nf", + "container_links", + f"Container prefix is correct: {container_link}", + self.main_nf, + ) + ) + else: + log.debug(f"Container link: '{container_link}' does not start with registry prefix: {registry}") + self.failed.append( + ( + "main_nf", + "container_links", + f"Container prefix is not correct. Please add one of the allowed registry prefixes: {', '.join(registry) if isinstance(registry, tuple) else registry}", + self.main_nf, + ) + ) + # lint more than one container in the same line if ("https://containers" in line or "https://depot" in line) and ( "biocontainers/" in line or line.startswith(registry) @@ -1023,68 +896,6 @@ def _is_empty(line): return empty -def _fix_module_version(self, current_version, latest_version, singularity_tag, response): - """Updates the module version - - Changes the bioconda current version by the latest version. - Obtains the latest build from bioconda response - Checks that the new URLs for docker and singularity with the tag [version]--[build] are valid - Changes the docker and singularity URLs - """ - # Get latest build - build = _get_build(response) - - with open(self.main_nf) as source: - lines = source.readlines() - - # Check if the new version + build exist and replace - new_lines = [] - for line in lines: - line_stripped = line.strip(" '\"") - build_type = _container_type(line_stripped) - if build_type == "conda": - new_lines.append(re.sub(rf"{current_version}", f"{latest_version}", line)) - elif build_type in ("singularity", "docker"): - # Check that the new url is valid - new_url = re.search( - "(?:['\"])(.+)(?:['\"])", re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line) - ).group(1) - try: - response_new_container = requests.get( - "https://" + new_url if not new_url.startswith("https://") else new_url, stream=True - ) - log.debug( - f"Connected to URL: {'https://' + new_url if not new_url.startswith('https://') else new_url}, " - f"status_code: {response_new_container.status_code}" - ) - except (requests.exceptions.RequestException, sqlite3.InterfaceError) as e: - log.debug(f"Unable to connect to url '{new_url}' due to error: {e}") - return False - if response_new_container.status_code != 200: - return False - new_lines.append(re.sub(rf"{singularity_tag}", f"{latest_version}--{build}", line)) - else: - new_lines.append(line) - - # Replace outdated versions by the latest one - with open(self.main_nf, "w") as source: - for line in new_lines: - source.write(line) - - return True - - -def _get_build(response): - """Get the latest build of the container version""" - build_times = [] - latest_v = response.get("latest_version") - files = response.get("files") - for f in files: - if f.get("version") == latest_v: - build_times.append((f.get("upload_time"), f.get("attrs").get("build"))) - return sorted(build_times, key=lambda tup: tup[0], reverse=True)[0][1] - - def _container_type(line): """Returns the container type of a build.""" if line.startswith("conda"): diff --git a/nf_core/modules/lint/meta_yml.py b/nf_core/modules/lint/meta_yml.py index 27bf1b9d6f..6ee8025522 100644 --- a/nf_core/modules/lint/meta_yml.py +++ b/nf_core/modules/lint/meta_yml.py @@ -1,16 +1,24 @@ from __future__ import annotations +import json import logging +from functools import cache from pathlib import Path from typing import TYPE_CHECKING -import ruamel.yaml from jsonschema import exceptions, validators from nf_core.components.components_differ import ComponentsDiffer +from nf_core.components.components_utils import read_meta_yml as read_component_meta_yml +from nf_core.components.components_utils import yaml as ruamel_yaml from nf_core.components.lint import ComponentLint, LintExceptionError from nf_core.components.nfcore_component import NFCoreComponent -from nf_core.utils import unquote +from nf_core.modules.lint.module_containers import ( + lint_conda_lock_files, + lint_main_nf_container, + lint_meta_yml_containers, +) +from nf_core.utils import ContainerRegistryUrls, unquote if TYPE_CHECKING: from nf_core.modules.lint import ModuleLint @@ -18,6 +26,46 @@ log = logging.getLogger(__name__) +@cache +def _load_skip_nf_test_sets(base_dir: str) -> dict[str, frozenset[str]]: + """ + Load the per-system skip sets from ``.github/skip_nf_test.json``, cached per base directory. + + Skip entries may be recorded as absolute or repo-relative paths, + so everything is resolved to absolute paths for comparison. + """ + skip_file = Path(base_dir, ".github", "skip_nf_test.json") + if not skip_file.is_file(): + return {} + with open(skip_file) as fh: + data = json.load(fh) + return { + k: frozenset(str((Path(base_dir) / p).resolve()) for p in v) for k, v in data.items() if isinstance(v, list) + } + + +def meta_yml_containers(module: NFCoreComponent) -> None: + """ + Lints the container information in the meta.yml file and the module's main.nf file. + Respects per-system skips from `skip_nf_test.json`. + """ + skip_sets = _load_skip_nf_test_sets(str(module.base_dir)) + module_path = str(Path(module.component_dir).resolve()) + skip_docker = module_path in skip_sets.get("docker", frozenset()) + skip_singularity = module_path in skip_sets.get("singularity", frozenset()) + skip_conda = module_path in skip_sets.get("conda", frozenset()) + if skip_docker or skip_singularity or skip_conda: + log.debug( + f"Skip entries found for {module.component_name}: " + f"docker={skip_docker}, singularity={skip_singularity}, conda={skip_conda}" + ) + + lint_meta_yml_containers(module, skip_docker=skip_docker, skip_conda=skip_conda, skip_singularity=skip_singularity) + lint_main_nf_container(module, skip_docker=skip_docker, skip_conda=skip_conda, skip_singularity=skip_singularity) + if not skip_conda: + lint_conda_lock_files(module) + + def meta_yml(module_lint_object: ModuleLint, module: NFCoreComponent, allow_missing: bool = False) -> None: """Lint a ``meta.yml`` file @@ -58,6 +106,14 @@ def meta_yml(module_lint_object: ModuleLint, module: NFCoreComponent, allow_miss match those parsed from ``main.nf``. Run ``nf-core modules lint --fix`` to auto-correct. + * ``has_meta_containers``: If ``main.nf`` declares containers, ``meta.yml`` + must also contain a non-empty ``containers:`` block. Run + ``nf-core modules lint --fix`` to auto-correct. + + * ``correct_meta_containers``: The containers listed in ``meta.yml`` must + exactly match those parsed from ``main.nf``. Run + ``nf-core modules lint --fix`` to auto-correct. + If the module has inputs or outputs, they are expected to be formatted as: .. code-block:: groovy @@ -81,25 +137,14 @@ def meta_yml(module_lint_object: ModuleLint, module: NFCoreComponent, allow_miss ) return raise LintExceptionError("Module does not have a `meta.yml` file") - # Check if we have a patch file, get original file in that case - meta_yaml = read_meta_yml(module_lint_object, module) - if module.is_patched and module_lint_object.modules_repo.repo_path is not None: - lines = ComponentsDiffer.try_apply_patch( - module.component_type, - module.component_name, - module_lint_object.modules_repo.repo_path, - module.patch_path, - Path(module.component_dir).relative_to(module.base_dir), - reverse=True, - ).get("meta.yml") - if lines is not None: - yaml = ruamel.yaml.YAML() - meta_yaml = yaml.load("".join(lines)) + # read_meta_yml returns the reverse-patched content for patched modules + meta_yaml = read_meta_yml_patched(module_lint_object, module) if meta_yaml is None: module.failed.append(("meta_yml", "meta_yml_exists", "Module `meta.yml` does not exist.", module.meta_yml)) return else: module.passed.append(("meta_yml", "meta_yml_exists", "Module `meta.yml` exists", module.meta_yml)) + module.container = meta_yaml.get("containers", {}) # Confirm that the meta.yml file is valid according to the JSON schema valid_meta_yml = False @@ -283,8 +328,40 @@ def meta_yml(module_lint_object: ModuleLint, module: NFCoreComponent, allow_miss ) ) + # Check that meta_yml specifies containers (skip modules that use a Dockerfile) + from nf_core.modules.modules_utils import module_uses_dockerfile + + container = module.get_container_from_main_nf() + if container and not module_uses_dockerfile(module): + if "containers" not in meta_yaml: + if ContainerRegistryUrls.SEQERA_DOCKER.value in container: + module.failed.append( + ( + "meta_yml", + "has_meta_containers", + f"Module `meta.yml` does not contain any containers, even though they appear in `main.nf`. Use `nf-core modules lint {module.component_name} --fix` to automatically resolve this.", + module.meta_yml, + ) + ) + else: + log.debug( + f"Module `{module.component_name}` has no containers section in `meta.yml` but does not use the Wave registry — skipping container lint." + ) + return + + module.passed.append( + ( + "meta_yml", + "has_meta_containers", + "Module `meta.yml` and `main.nf` contain container definition.", + module.meta_yml, + ) + ) + + meta_yml_containers(module) + -def read_meta_yml(module_lint_object: ComponentLint, module: NFCoreComponent) -> dict | None: +def read_meta_yml_patched(module_lint_object: ComponentLint, module: NFCoreComponent) -> dict | None: """ Read a `meta.yml` file and return it as a dictionary @@ -295,9 +372,9 @@ def read_meta_yml(module_lint_object: ComponentLint, module: NFCoreComponent) -> Returns: dict: The `meta.yml` file as a dictionary """ - meta_yaml = None - yaml = ruamel.yaml.YAML() - yaml.preserve_quotes = True + if module_lint_object.modules_repo.repo_path is None: + raise ValueError("modules_repo.repo_path is None") + # Check if we have a patch file, get original file in that case if module.is_patched: lines = ComponentsDiffer.try_apply_patch( @@ -309,13 +386,10 @@ def read_meta_yml(module_lint_object: ComponentLint, module: NFCoreComponent) -> reverse=True, ).get("meta.yml") if lines is not None: - meta_yaml = yaml.load("".join(lines)) - if meta_yaml is None: - if module.meta_yml is None: - return None - with open(module.meta_yml) as fh: - meta_yaml = yaml.load(fh) - return meta_yaml + return ruamel_yaml.load("".join(lines)) + if module.meta_yml is None: + return None + return read_component_meta_yml(module.meta_yml) def obtain_inputs(_, inputs: list) -> list: diff --git a/nf_core/modules/lint/module_containers.py b/nf_core/modules/lint/module_containers.py new file mode 100644 index 0000000000..25d0dce6e0 --- /dev/null +++ b/nf_core/modules/lint/module_containers.py @@ -0,0 +1,305 @@ +import logging +from pathlib import Path + +import requests +from pydantic_core import ValidationError + +from nf_core.components.nfcore_component import NFCoreComponent +from nf_core.modules.modules_utils import ContainerEntry, MetaYmlContainers, module_uses_dockerfile +from nf_core.utils import CONTAINER_PLATFORMS + +log = logging.getLogger(__name__) + + +def lint_meta_yml_containers(module: NFCoreComponent, skip_docker=False, skip_conda=False, skip_singularity=False): + if module_uses_dockerfile(module): + log.info(f"Module '{module.component_name}' uses a Dockerfile - skipping container lint") + return + + meta_path = Path(module.component_dir, "meta.yml") + meta_yml = module.load_meta_yml() + assert meta_yml and "containers" in meta_yml + + containers_raw = meta_yml["containers"] + + skip_system = {"docker": skip_docker, "singularity": skip_singularity, "conda": skip_conda} + + # Validate each container system separately with the pydantic model, so one + # invalid system doesn't suppress the checks for the others. Lint messages + # are derived from the collected validation errors. + containers = MetaYmlContainers() + for system_key in skip_system: + if skip_system[system_key]: + continue + + try: + validated = MetaYmlContainers.model_validate( + {system_key: containers_raw.get(system_key, {})}, + context={"require_complete": [system_key]}, + ) + except ValidationError as e: + for err in e.errors(): + loc = ".".join(str(part) for part in err["loc"]) + module.failed.append( + ("meta_yml", f"containers_section_{system_key}", f"`{loc}`: {err['msg']}", meta_path) + ) + continue + + setattr(containers, system_key, getattr(validated, system_key)) + module.passed.append( + ( + "meta_yml", + f"containers_section_{system_key}", + f"{system_key} containers section is valid", + meta_path, + ) + ) + + if system_key == "conda": + continue + + # check build_id hash matches hash in container tag + for platform, system in getattr(containers, system_key).items(): + if not system.build_id.removeprefix("bd-"): + module.warned.append( + ( + "meta_yml", + "containers_build_id_hash", + f"No build_id found for {system_key} {platform}", + meta_path, + ) + ) + continue + + build_hash = system.build_hash + name_hash = system.tag_hash + if build_hash and name_hash: + if build_hash != name_hash: + module.failed.append( + ( + "meta_yml", + "containers_build_id_hash", + f"Build ID `{build_hash}` hash does not match {system_key} container tag `{name_hash}` for {platform}", + meta_path, + ) + ) + else: + module.passed.append( + ( + "meta_yml", + "containers_build_id_hash", + f"Build ID hash matches {system_key} container tag for {platform}", + meta_path, + ) + ) + else: + module.warned.append( + ( + "meta_yml", + "containers_build_id_hash", + f"Could not compare build ID hash with {system} container tag for {platform}", + meta_path, + ) + ) + + # Check docker container images exist for all platforms (unless skipped) + if skip_docker: + pass + elif not containers.docker: + module.warned.append( + ("meta_yml", "containers_docker_exist", "Docker containers section missing or empty", meta_path) + ) + else: + for platform in containers.docker: + docker_name = containers.docker[platform].name + if not docker_name: + module.warned.append( + ( + "meta_yml", + f"containers_docker_{platform}_exists", + f"Docker {platform} container name missing", + meta_path, + ) + ) + continue + if docker_name.startswith(("http://", "https://")): + docker_url = docker_name + elif "://" in docker_name: + docker_url = "" + else: + # OCI distribution spec: /v2//manifests/ + host, _, image_ref = docker_name.partition("/") + image_name, _, tag = image_ref.partition(":") + docker_url = f"https://{host}/v2/{image_name}/manifests/{tag or 'latest'}" + if not docker_url: + module.warned.append( + ( + "meta_yml", + f"containers_docker_{platform}_exists", + f"Docker {platform} container has non-http protocol; existence check skipped", + meta_path, + ) + ) + else: + try: + response = requests.head( + docker_url, + allow_redirects=True, + headers={"Accept": "application/vnd.oci.image.manifest.v1+json"}, + ) + if response.ok or response.status_code == 401: + module.passed.append( + ( + "meta_yml", + f"containers_docker_{platform}_exists", + f"Docker {platform} image exists", + meta_path, + ) + ) + else: + module.warned.append( + ( + "meta_yml", + f"containers_docker_{platform}_exists", + f"Docker {platform} image not reachable at {docker_url} (status {response.status_code})", + meta_path, + ) + ) + except requests.RequestException as e: + module.warned.append( + ( + "meta_yml", + f"containers_docker_{platform}_exists", + f"Unable to connect to docker image URL: {e}", + meta_path, + ) + ) + + # Conda lock files and hash checks + if skip_conda: + pass + elif not containers.conda: + module.warned.append( + ("meta_yml", "containers_conda_lock_exists", "Conda containers section missing or empty", meta_path) + ) + else: + for platform in containers.conda: + lock_file = containers.conda[platform].lock_file + if not lock_file: + module.warned.append( + ("meta_yml", "containers_conda_lock_exists", f"Missing conda lock_file for {platform}", meta_path) + ) + continue + lock_path = Path(lock_file) + if lock_path.exists(): + module.passed.append( + ( + "meta_yml", + "containers_conda_lock_exists", + f"Conda lock_file exists for {platform}", + meta_path, + ) + ) + else: + module.warned.append( + ( + "meta_yml", + "containers_conda_lock_exists", + f"Conda lock_file not found for {platform}: {lock_path}", + meta_path, + ) + ) + + for plat in CONTAINER_PLATFORMS: + conda_entry = containers.conda.get(plat) + docker_entry = containers.docker.get(plat) if containers.docker else None + conda_lock = conda_entry.lock_file if conda_entry else "" + + if not (docker_entry and docker_entry.build_id and conda_lock): + module.warned.append( + ( + "meta_yml", + "containers_conda_lock_hash", + f"Could not compare conda lock_file with docker {plat} buildId hash", + meta_path, + ) + ) + continue + + docker_build_id_clean = docker_entry.build_id.removeprefix("bd-") + parts = docker_build_id_clean.split("_") + if len(parts) >= 3 and parts[-1].isdigit() and parts[-2].isdigit(): + parts = parts[:-2] + docker_hash = "_".join([p for p in parts if p]) + if docker_hash and docker_hash in conda_lock: + module.passed.append( + ( + "meta_yml", + "containers_conda_lock_hash", + f"Conda lock_file matches docker {plat} buildId hash", + meta_path, + ) + ) + else: + module.failed.append( + ( + "meta_yml", + "containers_conda_lock_hash", + f"Conda lock_file does not match docker {plat} buildId hash", + meta_path, + ) + ) + return + + +def lint_main_nf_container( + module: NFCoreComponent, fix=False, skip_docker=False, skip_conda=False, skip_singularity=False +): + if module_uses_dockerfile(module): + log.info(f"Module '{module.component_name}' uses a Dockerfile - skipping main.nf container lint") + return + + if skip_docker: + log.debug("Skipping main.nf container linting") + return + + if not module.container_from_main_nf: + log.debug("Skipping main.nf container linting") + module.warned.append( + ("main_nf", "has_container", "Module `main.nf` does not specify a container.", module.main_nf) + ) + return + + main_path = Path(module.component_dir, "main.nf") + meta_path = Path(module.component_dir, "meta.yml") + + meta_yml = module.load_meta_yml() + if meta_yml is None: + return + try: + docker_container_raw = meta_yml.get("containers", {}).get("docker", {}).get("linux/amd64", {}) + docker_container = ContainerEntry.model_validate(docker_container_raw) + except ValidationError as e: + log.debug(f"Docker linux/amd64 image could not be read from {meta_path.absolute()}") + log.debug(e) + return + + if docker_container.name != module.container_from_main_nf: + module.warned.append( + ( + "main_nf", + "main_nf_container", + "Docker image in main.nf does not match the image specified in meta.yml", + main_path, + ) + ) + + if fix: + # TODO: Update main.nf container + # update_main_nf_container(new_image) + pass + + +def lint_conda_lock_files(module: NFCoreComponent): + # TODO + pass diff --git a/nf_core/modules/modules_utils.py b/nf_core/modules/modules_utils.py index 21496fdef3..6a3ed22604 100644 --- a/nf_core/modules/modules_utils.py +++ b/nf_core/modules/modules_utils.py @@ -4,8 +4,9 @@ from urllib.parse import urlparse import requests +from pydantic import BaseModel, ValidationInfo, field_validator, model_validator -from nf_core.utils import NFCORE_CACHE_DIR +from nf_core.utils import CONTAINER_PLATFORMS, CONTAINER_SYSTEMS, NFCORE_CACHE_DIR from ..components.nfcore_component import NFCoreComponent @@ -21,6 +22,99 @@ class ModuleExceptionError(Exception): pass +class ContainerEntry(BaseModel): + name: str + build_id: str = "" + scan_id: str = "" + https: str = "" + + @property + def build_hash(self) -> str: + """Hash part of the Wave build ID (``bd-_``).""" + parts = self.build_id.removeprefix("bd-").split("_") + return parts[0] if parts else "" + + @property + def tag_hash(self) -> str: + """Hash encoded in the image tag (``name:--``, or a bare hex tag).""" + name = self.name + if "://" in name: + name = name.split("://", 1)[1] + if "@" in name: + name = name.split("@", 1)[0] + if ":" not in name: + return "" + tag = name.rsplit(":", 1)[1] + if "--" in tag: + return tag.rsplit("--", 1)[1] + tag_lower = tag.lower() + return tag if len(tag_lower) >= 8 and all(c in "0123456789abcdef" for c in tag_lower) else "" + + +class CondaEntry(BaseModel): + lock_file: str = "" + + +class MetaYmlContainers(BaseModel): + docker: dict[str, ContainerEntry] = {} + singularity: dict[str, ContainerEntry] = {} + conda: dict[str, CondaEntry] = {} + + @field_validator("docker", "singularity", "conda", mode="after") + @classmethod + def check_keys_against_container_platforms(cls, value: dict) -> dict: + # Check if all used keys are valid platforms + for plf_key in value: + if plf_key not in CONTAINER_PLATFORMS: + raise ValueError(f"Invalid platform key: {plf_key}") + + return value + + def dump_for_meta_yml(self) -> dict: + """ + ``model_dump`` shaped for the meta.yml JSON schema: ``name``/``build_id`` are + always emitted (the schema requires them, empty or not), while the optional + fields (``https``, ``scan_id``) are omitted when empty — an empty ``https`` + would violate the schema's ``^https://`` pattern. + """ + dump = self.model_dump() + for platforms in dump.values(): + for entry in platforms.values(): + for key in ("https", "scan_id"): + if not entry.get(key, True): + del entry[key] + return dump + + @model_validator(mode="after") + def check_container_systems_complete(self, info: ValidationInfo) -> "MetaYmlContainers": + """ + Require a non-empty section with an entry for every platform, for each container + system named in ``context={"require_complete": [...]}`` (``True`` means all of + ``CONTAINER_SYSTEMS``, i.e. conda is exempt). Plain construction (e.g. the partial + states built up during container builds) is not affected. + """ + require = (info.context or {}).get("require_complete") + if not require: + return self + for system in CONTAINER_SYSTEMS if require is True else require: + entries = getattr(self, system) + if not entries: + raise ValueError(f"No containers specified for {system}") + for plf in CONTAINER_PLATFORMS: + if plf not in entries: + raise ValueError(f"No {system} entries found for expected platform: {plf}") + return self + + +def module_uses_dockerfile(module: NFCoreComponent) -> bool: + """Return True if the module has a Dockerfile (in its dir or parent) but no environment.yml.""" + env_yml = module.environment_yml + if env_yml is not None and Path(env_yml).exists(): + return False + component_dir = Path(module.component_dir) + return (component_dir / "Dockerfile").exists() or (component_dir.parent / "Dockerfile").exists() + + def repo_full_name_from_remote(remote_url: str) -> str: """ Extracts the path from the remote URL @@ -146,6 +240,21 @@ def load_edam(): return edam_formats +def scan_modules_dir(modules_dir: Path) -> list[str]: + """ + Scan a modules directory for main.nf files and return module names relative to modules_dir. + + Args: + modules_dir: Directory to scan + + Returns: + List of module names relative to modules_dir + """ + if not modules_dir.exists(): + return [] + return [str(main_nf.parent.relative_to(modules_dir)) for main_nf in modules_dir.rglob("main.nf")] + + def filter_modules_by_name(modules: list[NFCoreComponent], module_name: str) -> list[NFCoreComponent]: """ Filter modules by name, supporting exact matches and tool family matching. @@ -163,3 +272,58 @@ def filter_modules_by_name(modules: list[NFCoreComponent], module_name: str) -> return exact_matches # If no exact match, look for modules that start with the given name (subtools) return [m for m in modules if m.component_name.startswith(module_name)] + + +def prompt_module_selection( + modules: list[NFCoreComponent], component_type: str = "modules", action: str = "Select", allow_all: bool = True +) -> str | None: + """ + Prompt user to select a specific module or all modules. + + Args: + modules (list[NFCoreComponent]): List of available modules to choose from + component_type (str): The component type (default: "modules", can also be "subworkflows") + action (str): The action verb to use in the prompt message (e.g., "Lint", "Install", "Update", "Bump versions for") + allow_all (bool): Whether to show "All modules" option (default: True) + + Returns: + str | None: The selected module name, or None if "All modules" was selected + """ + import questionary + + from nf_core.utils import nfcore_question_style + + if not modules: + return None + + component_singular = component_type.rstrip("s") # "modules" -> "module" + + # If allow_all is False, skip the "all or named" question and go straight to module selection + if not allow_all: + question = { + "type": "autocomplete", + "name": "tool_name", + "message": "Tool name:", + "choices": [m.component_name for m in modules], + } + answer = questionary.unsafe_prompt([question], style=nfcore_question_style) + return answer.get("tool_name") + + # Otherwise, show the "all or named" question + questions = [ + { + "type": "list", + "name": f"all_{component_type}", + "message": f"{action} all {component_type} or a single named {component_singular}?", + "choices": [f"All {component_type}", f"Named {component_singular}"], + }, + { + "type": "autocomplete", + "name": "tool_name", + "message": "Tool name:", + "when": lambda x: x[f"all_{component_type}"] == f"Named {component_singular}", + "choices": [m.component_name for m in modules], + }, + ] + answers = questionary.unsafe_prompt(questions, style=nfcore_question_style) + return answers.get("tool_name") diff --git a/nf_core/pipelines/download/docker.py b/nf_core/pipelines/download/docker.py index 40bf7d22e3..1b567f5cd9 100644 --- a/nf_core/pipelines/download/docker.py +++ b/nf_core/pipelines/download/docker.py @@ -12,7 +12,8 @@ import nf_core.utils from nf_core.pipelines.download.container_fetcher import ContainerFetcher, ContainerProgress -from nf_core.pipelines.download.utils import ContainerRegistryUrls, copy_container_load_scripts +from nf_core.pipelines.download.utils import copy_container_load_scripts +from nf_core.utils import ContainerRegistryUrls log = logging.getLogger(__name__) stderr = rich.console.Console( diff --git a/nf_core/pipelines/download/download.py b/nf_core/pipelines/download/download.py index fbd051f65d..1c999cbd47 100644 --- a/nf_core/pipelines/download/download.py +++ b/nf_core/pipelines/download/download.py @@ -23,7 +23,7 @@ from nf_core.pipelines.download.container_fetcher import ContainerFetcher from nf_core.pipelines.download.docker import DockerFetcher from nf_core.pipelines.download.singularity import SINGULARITY_CACHE_DIR_ENV_VAR, SingularityFetcher -from nf_core.pipelines.download.utils import DownloadError, intermediate_dir_with_cd +from nf_core.pipelines.download.utils import DownloadError from nf_core.pipelines.download.workflow_repo import WorkflowRepo from nf_core.utils import ( NF_INSPECT_MIN_NF_VERSION, @@ -32,6 +32,7 @@ gh_api, pretty_nf_version, run_cmd, + set_wd_tempdir, ) log = logging.getLogger(__name__) @@ -677,7 +678,7 @@ def find_container_images( working_dir = Path().absolute() def run_nextflow_inspect(params_file: Path | None = None) -> dict[str, Any]: - with intermediate_dir_with_cd(working_dir): + with set_wd_tempdir(working_dir): executable = "nextflow" params_file_arg = f' -params-file "{params_file}"' if params_file else "" cmd_params = ( diff --git a/nf_core/pipelines/download/singularity.py b/nf_core/pipelines/download/singularity.py index c389e73dc8..5c15ef3c56 100644 --- a/nf_core/pipelines/download/singularity.py +++ b/nf_core/pipelines/download/singularity.py @@ -18,11 +18,11 @@ import nf_core.utils from nf_core.pipelines.download.container_fetcher import ContainerFetcher, ContainerProgress from nf_core.pipelines.download.utils import ( - ContainerRegistryUrls, DownloadError, intermediate_file, intermediate_file_no_creation, ) +from nf_core.utils import ContainerRegistryUrls log = logging.getLogger(__name__) stderr = rich.console.Console( diff --git a/nf_core/pipelines/download/utils.py b/nf_core/pipelines/download/utils.py index bde3845c09..3d61adacd7 100644 --- a/nf_core/pipelines/download/utils.py +++ b/nf_core/pipelines/download/utils.py @@ -1,22 +1,14 @@ import contextlib import importlib.resources import logging -import os import shutil import tempfile from collections.abc import Generator -from enum import Enum from pathlib import Path log = logging.getLogger(__name__) -class ContainerRegistryUrls(Enum): - SEQERA_DOCKER = "community.wave.seqera.io/library" - SEQERA_SINGULARITY = "community-cr-prod.seqera.io/docker/registry/v2" - GALAXY_SINGULARITY = "depot.galaxyproject.org/singularity" - - def copy_container_load_scripts(container_system: str, dest_dir: Path, make_exec: bool = True) -> tuple[str, Path]: container_load_scripts_subpackage = "nf_core.pipelines.download.load_scripts" script_name = f"{container_system}-load.sh" @@ -84,21 +76,3 @@ def intermediate_file_no_creation(output_path: Path) -> Generator[Path, None, No except: tmp.cleanup() raise - - -@contextlib.contextmanager -def intermediate_dir_with_cd(original_dir: Path, base_dir: Path = Path()): - """ - Context manager to provide and change into a tempdir and ensure its removal and return to the - original_dir upon exceptions. - """ - - if not original_dir.is_dir(): - raise DownloadError(f"Unable to setup temporary dir, original_dir does not exist: {original_dir}") - - tmp = tempfile.TemporaryDirectory(dir=base_dir) - try: - os.chdir(tmp.name) - yield tmp - finally: - os.chdir(original_dir) diff --git a/nf_core/pipelines/lint/__init__.py b/nf_core/pipelines/lint/__init__.py index d31930e735..f964509149 100644 --- a/nf_core/pipelines/lint/__init__.py +++ b/nf_core/pipelines/lint/__init__.py @@ -258,6 +258,7 @@ def _lint_pipeline(self) -> None: rich.progress.BarColumn(bar_width=None), "[magenta]{task.completed} of {task.total}[reset] » [bold yellow]{task.fields[test_name]}", transient=True, + console=console, disable=self.hide_progress or os.environ.get("HIDE_PROGRESS", None) is not None, ) with self.progress_bar: diff --git a/nf_core/subworkflows/lint/__init__.py b/nf_core/subworkflows/lint/__init__.py index 4cc4f774c2..22ceb96ab1 100644 --- a/nf_core/subworkflows/lint/__init__.py +++ b/nf_core/subworkflows/lint/__init__.py @@ -9,7 +9,6 @@ import logging import os -import questionary import rich import ruamel.yaml @@ -102,24 +101,11 @@ def lint( # TODO: consider unifying modules and subworkflows lint() function and add it to the ComponentLint class # Prompt for subworkflow or all if subworkflow is None and not (local or all_subworkflows): - questions = [ - { - "type": "list", - "name": "all_subworkflows", - "message": "Lint all subworkflows or a single named subworkflow?", - "choices": ["All subworkflows", "Named subworkflow"], - }, - { - "type": "autocomplete", - "name": "subworkflow_name", - "message": "Subworkflow name:", - "when": lambda x: x["all_subworkflows"] == "Named subworkflow", - "choices": [m.component_name for m in self.all_remote_components], - }, - ] - answers = questionary.unsafe_prompt(questions, style=nf_core.utils.nfcore_question_style) - all_subworkflows = answers["all_subworkflows"] == "All subworkflows" - subworkflow = answers.get("subworkflow_name") + from nf_core.modules.modules_utils import prompt_module_selection + + subworkflow = prompt_module_selection( + self.all_remote_components, component_type="subworkflows", action="Lint" + ) # Only lint the given module if subworkflow: @@ -245,13 +231,14 @@ def update_meta_yml_file(self, swf): """ Update the meta.yml file with the correct inputs and outputs """ + from nf_core.components.components_utils import read_meta_yml + yaml = ruamel.yaml.YAML() yaml.preserve_quotes = True yaml.indent(mapping=2, sequence=2, offset=0) # Read meta.yml - with open(swf.meta_yml) as fh: - meta_yaml = yaml.load(fh) + meta_yaml = read_meta_yml(swf.meta_yml) meta_yaml_corrected = meta_yaml.copy() # Obtain inputs and outputs from main.nf swf.get_inputs_from_main_nf() diff --git a/nf_core/subworkflows/lint/meta_yml.py b/nf_core/subworkflows/lint/meta_yml.py index bfc3330e9d..92c4641d4b 100644 --- a/nf_core/subworkflows/lint/meta_yml.py +++ b/nf_core/subworkflows/lint/meta_yml.py @@ -3,7 +3,6 @@ from pathlib import Path import jsonschema.validators -import ruamel.yaml import nf_core.components.components_utils from nf_core.components.lint import LintExceptionError @@ -64,9 +63,9 @@ def meta_yml(subworkflow_lint_object, subworkflow, allow_missing: bool = False): raise LintExceptionError("Subworkflow does not have a `meta.yml` file") try: - with open(subworkflow.meta_yml) as fh: - yaml = ruamel.yaml.YAML(typ="safe") - meta_yaml = yaml.load(fh) + from nf_core.components.components_utils import read_meta_yml + + meta_yaml = read_meta_yml(subworkflow.meta_yml) subworkflow.passed.append( ("meta_yml", "meta_yml_exists", "Subworkflow `meta.yml` exists", subworkflow.meta_yml) ) diff --git a/nf_core/utils.py b/nf_core/utils.py index f8b7add797..98db9aba31 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -18,9 +18,12 @@ import shlex import subprocess import sys +import tempfile import time from collections.abc import Callable, Generator from contextlib import contextmanager, suppress +from enum import Enum +from functools import lru_cache from pathlib import Path from typing import TYPE_CHECKING, Any, Literal @@ -104,6 +107,16 @@ def is_interactive() -> bool: ) +CONTAINER_SYSTEMS = ["docker", "singularity"] +CONTAINER_PLATFORMS = ["linux/amd64", "linux/arm64"] + + +class ContainerRegistryUrls(Enum): + SEQERA_DOCKER = "community.wave.seqera.io/library" + SEQERA_SINGULARITY = "community-cr-prod.seqera.io/docker/registry/v2" + GALAXY_SINGULARITY = "depot.galaxyproject.org/singularity" + + def unquote(s: str) -> str: """ Remove paired quotes (single or double) from start and end of string. @@ -122,7 +135,9 @@ def unquote(s: str) -> str: """ import ruamel.yaml.scalarstring - if isinstance(s, ruamel.yaml.scalarstring.DoubleQuotedScalarString): + if isinstance( + s, (ruamel.yaml.scalarstring.DoubleQuotedScalarString, ruamel.yaml.scalarstring.SingleQuotedScalarString) + ): return s try: @@ -315,8 +330,9 @@ def pretty_nf_version(version: tuple[int, int, int, bool]) -> str: return f"{version[0]}.{version[1]:02}.{version[2]}" + ("-edge" if version[3] else "") +@lru_cache(maxsize=1) def get_nf_version() -> tuple[int, int, int, bool] | None: - """Get the version of Nextflow installed on the system.""" + """Get the version of Nextflow installed on the system. Cached for the lifetime of the process.""" try: cmd_out = run_cmd("nextflow", "-v") if cmd_out is None: @@ -371,16 +387,14 @@ def check_nextflow_version(minimal_nf_version: tuple[int, int, int, bool], silen return nf_version >= minimal_nf_version -_NF_PROCESS_NAME_RE = re.compile(r"^\s*process\s+(\w+)\s*\{", re.MULTILINE) - - def read_module_name(main_nf: Path) -> str | None: """Return the process name declared in a Nextflow ``main.nf`` file, or ``None``.""" + nf_process_name_regex = re.compile(r"^\s*process\s+(\w+)\s*\{", re.MULTILINE) try: - match = _NF_PROCESS_NAME_RE.search(main_nf.read_text()) - return match.group(1) if match else None + match = nf_process_name_regex.search(main_nf.read_text()) except OSError: return None + return match.group(1) if match else None def fetch_wf_config(wf_path: Path, cache_config: bool = True) -> dict: @@ -490,20 +504,26 @@ def run_cmd(executable: str, cmd: str) -> tuple[bytes, bytes] | None: log.debug(f"Running command: {full_cmd}") try: proc = subprocess.run(shlex.split(full_cmd), capture_output=True, check=False) - if proc.returncode != 0: - if executable == "nf-test": - return (proc.stdout, proc.stderr) - raise subprocess.CalledProcessError(proc.returncode, proc.args, output=proc.stdout, stderr=proc.stderr) - return (proc.stdout, proc.stderr) - except subprocess.CalledProcessError as e: - raise RuntimeError(f"Command '{full_cmd}' failed: {e}") from e except OSError as e: if e.errno == errno.ENOENT: raise RuntimeError( f"It looks like {executable} is not installed. Please ensure it is available in your PATH." ) from e - else: - return None + return None + + if proc.returncode != 0: + if executable == "nf-test": + return (proc.stdout, proc.stderr) + output = ( + proc.stderr.decode("utf-8", errors="replace").strip() + if proc.stderr + else proc.stdout.decode("utf-8", errors="replace").strip() + if proc.stdout + else "" + ) + raise RuntimeError(f"Command '{full_cmd}' failed with exit code {proc.returncode}\n{output}") + + return (proc.stdout, proc.stderr) def setup_nfcore_dir() -> bool: @@ -1685,6 +1705,19 @@ def set_wd(path: Path) -> Generator[None, None, None]: os.chdir(start_wd) +@contextmanager +def set_wd_tempdir(base_dir: Path | None = None) -> Generator[Path, None, None]: + """ + Context manager to create a tempdir and change into it, ensuring its removal and a return to + the original working directory on exit (including exceptions). + + Args: + base_dir: Directory in which to create the tempdir. Defaults to the system temp location. + """ + with tempfile.TemporaryDirectory(dir=base_dir) as tmp, set_wd(Path(tmp)): + yield Path(tmp) + + def get_wf_files(wf_path: Path): """Return a list of all files in a directory (ignores .gitigore files)""" diff --git a/tests/components/test_components_utils.py b/tests/components/test_components_utils.py index 754612a9ea..802e1a7351 100644 --- a/tests/components/test_components_utils.py +++ b/tests/components/test_components_utils.py @@ -1,5 +1,7 @@ import importlib import os +import tempfile +from pathlib import Path from unittest import mock import responses @@ -125,3 +127,20 @@ def test_environment_variables_override(self): ) finally: importlib.reload(nf_core.components.constants) + + def test_get_meta_returns_dict(self): + """Test that read_meta_yml returns the meta.yml content""" + tmp_dir = Path(tempfile.mkdtemp()) + meta_yml = tmp_dir / "meta.yml" + meta_yml.write_text( + """ +name: test +description: test +version: 1.0.0 +""" + ) + assert nf_core.components.components_utils.read_meta_yml(meta_yml) == { + "name": "test", + "description": "test", + "version": "1.0.0", + } diff --git a/tests/modules/lint/test_environment_yml.py b/tests/modules/lint/test_environment_yml.py index 21a44226b3..8d1261725a 100644 --- a/tests/modules/lint/test_environment_yml.py +++ b/tests/modules/lint/test_environment_yml.py @@ -1,4 +1,5 @@ import io +from unittest.mock import patch import pytest import ruamel.yaml @@ -6,7 +7,7 @@ import nf_core.modules.lint from nf_core.components.lint import ComponentLint from nf_core.components.nfcore_component import NFCoreComponent -from nf_core.modules.lint.environment_yml import environment_yml +from nf_core.modules.lint.environment_yml import lint_environment_yml as environment_yml from ...test_modules import TestModules @@ -24,6 +25,7 @@ class DummyModule(NFCoreComponent): def __init__(self, path): self.environment_yml = path self.component_dir = path.parent + self.base_dir = path.parent self.component_name = "dummy" self.passed = [] self.failed = [] @@ -194,6 +196,101 @@ def test_environment_yml_missing_dependencies(tmp_path): assert_yaml_result(test_file, expected) +def test_bioconda_version_valid(tmp_path): + """Test that a valid, already-latest bioconda version passes both bioconda checks.""" + content = "dependencies:\n - bioconda::samtools=1.21\n" + _test_file, module, lint = setup_test_environment(tmp_path, content) + fake_response = {"versions": ["1.21"], "latest_version": "1.21"} + + with patch("nf_core.utils.anaconda_package", return_value=fake_response): + environment_yml(lint, module) + + assert any(x[1] == "bioconda_version" for x in module.passed) + assert any(x[1] == "bioconda_latest" for x in module.passed) + assert not any(x[1] == "bioconda_version" for x in module.failed) + + +def test_bioconda_version_lookup_error(tmp_path): + """Test that a LookupError from anaconda_package records a bioconda_version warning.""" + content = "dependencies:\n - bioconda::samtools=1.21\n" + _test_file, module, lint = setup_test_environment(tmp_path, content) + + with patch("nf_core.utils.anaconda_package", side_effect=LookupError("not found")): + environment_yml(lint, module) + + assert any(x[1] == "bioconda_version" for x in module.warned) + assert not any(x[1] == "bioconda_version" for x in module.failed) + + +def test_bioconda_version_value_error(tmp_path): + """Test that a ValueError from anaconda_package records a bioconda_version failure.""" + content = "dependencies:\n - bioconda::samtools=1.21\n" + _test_file, module, lint = setup_test_environment(tmp_path, content) + + with patch("nf_core.utils.anaconda_package", side_effect=ValueError("invalid")): + environment_yml(lint, module) + + assert any(x[1] == "bioconda_version" for x in module.failed) + assert not any(x[1] == "bioconda_version" for x in module.warned) + + +def test_bioconda_version_unknown(tmp_path): + """Test that a version absent from the available list records a bioconda_version failure.""" + content = "dependencies:\n - bioconda::samtools=1.18\n" + _test_file, module, lint = setup_test_environment(tmp_path, content) + fake_response = {"versions": ["1.20", "1.21"], "latest_version": "1.21"} + + with patch("nf_core.utils.anaconda_package", return_value=fake_response): + environment_yml(lint, module) + + assert any(x[1] == "bioconda_version" for x in module.failed) + + +def test_bioconda_latest_no_fix(tmp_path): + """Test that an outdated version warns on bioconda_latest when fix_version=False.""" + content = "dependencies:\n - bioconda::samtools=1.18\n" + _test_file, module, lint = setup_test_environment(tmp_path, content) + fake_response = {"versions": ["1.18", "1.21"], "latest_version": "1.21"} + + with patch("nf_core.utils.anaconda_package", return_value=fake_response): + environment_yml(lint, module) # fix_version defaults to False + + assert any(x[1] == "bioconda_latest" for x in module.warned) + assert not any(x[1] == "bioconda_latest" for x in module.passed) + + +def test_fix_version_fix_fails(tmp_path): + """Test that a failed _fix_module_version call records a bioconda_latest warning.""" + content = "dependencies:\n - bioconda::samtools=1.18\n" + _test_file, module, lint = setup_test_environment(tmp_path, content) + fake_response = {"versions": ["1.18", "1.21"], "latest_version": "1.21"} + + with ( + patch("nf_core.utils.anaconda_package", return_value=fake_response), + patch("nf_core.modules.lint.environment_yml._fix_module_version", return_value=False), + ): + environment_yml(lint, module, fix_version=True) + + assert any(x[1] == "bioconda_latest" for x in module.warned) + assert not any(x[1] == "bioconda_latest" for x in module.passed) + + +def test_environment_yml_missing_not_referenced(tmp_path): + """Test that a missing environment.yml passes when main.nf does not reference it.""" + (tmp_path / "main.nf").write_text("process TEST {\n script: 'echo hello'\n}\n") + (tmp_path / "modules").mkdir(exist_ok=True) + (tmp_path / "modules" / "environment-schema.json").write_text("{}") + + missing_path = tmp_path / "environment.yml" + module = DummyModule(missing_path) + lint = DummyLint(tmp_path) + + environment_yml(lint, module) + + assert any(x[1] == "environment_yml_exists" for x in module.passed) + assert not any(x[1] == "environment_yml_exists" for x in module.failed) + + # Integration tests using the full ModuleLint class @pytest.mark.integration class TestModulesEnvironmentYmlIntegration(TestModules): @@ -326,3 +423,35 @@ def test_modules_environment_yml_file_default_channel_fails(self): assert len(module_lint.passed) > 0 assert len(module_lint.warned) >= 0 assert module_lint.failed[0].lint_test == "environment_yml_valid" + + +def test_fix_version_updates_environment_yml(tmp_path): + """Test that fix_version rewrites the version in environment.yml, not main.nf.""" + content = "dependencies:\n - bioconda::samtools=1.18\n" + test_file, module, lint = setup_test_environment(tmp_path, content) + + fake_response = {"versions": ["1.18", "1.21"], "latest_version": "1.21"} + + with patch("nf_core.utils.anaconda_package", return_value=fake_response): + environment_yml(lint, module, fix_version=True) + + result = test_file.read_text() + assert "=1.21" in result + assert "=1.18" not in result + assert any(x[1] == "bioconda_latest" for x in module.passed) + + +def test_fix_version_does_not_touch_main_nf(tmp_path): + """Test that fix_version leaves main.nf untouched.""" + content = "dependencies:\n - bioconda::samtools=1.18\n" + test_file, module, lint = setup_test_environment(tmp_path, content) + + main_nf = tmp_path / "main.nf" + main_nf.write_text("conda 'bioconda::samtools=1.18'\n") + + fake_response = {"versions": ["1.18", "1.21"], "latest_version": "1.21"} + + with patch("nf_core.utils.anaconda_package", return_value=fake_response): + environment_yml(lint, module, fix_version=True) + + assert main_nf.read_text() == "conda 'bioconda::samtools=1.18'\n" diff --git a/tests/modules/lint/test_lint_utils.py b/tests/modules/lint/test_lint_utils.py index c7cbb13bf7..2b4dbbff7f 100644 --- a/tests/modules/lint/test_lint_utils.py +++ b/tests/modules/lint/test_lint_utils.py @@ -15,6 +15,14 @@ def __init__(self): self.main_nf = "main_nf" self.has_meta = False + # Containers that `get_container_with_inspect` should return, keyed by profile + # (e.g. {"docker": "...", "singularity": "..."}). Tests can populate this to + # drive the `nextflow inspect` based container resolution without a real Nextflow. + self.inspect_containers: dict[str | None, str | None] = {} + + def get_container_with_inspect(self, profile=None): + return self.inspect_containers.get(profile) + class TestModulesLint(TestModules): """Core ModuleLint functionality tests""" diff --git a/tests/modules/lint/test_main_nf.py b/tests/modules/lint/test_main_nf.py index 399edc900f..5d51c2b1e5 100644 --- a/tests/modules/lint/test_main_nf.py +++ b/tests/modules/lint/test_main_nf.py @@ -99,13 +99,13 @@ def test_process_labels(content, passed, warned, failed): "content,passed,warned,failed", [ # Single-line container definition should pass - ('container "quay.io/nf-core/gatk:4.4.0.0" //Biocontainers is missing a package', 2, 0, 0), + ('container "quay.io/nf-core/gatk:4.4.0.0" //Biocontainers is missing a package', 3, 0, 0), # Multi-line container definition should pass ( '''container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/gatk4:4.4.0.0--py36hdfd78af_0': - 'biocontainers/gatk4:4.4.0.0--py36hdfd78af_0' }"''', - 6, + 'quay.io/biocontainers/gatk4:4.4.0.0--py36hdfd78af_0' }"''', + 7, 0, 0, ), @@ -113,8 +113,8 @@ def test_process_labels(content, passed, warned, failed): ( '''container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/gatk4:4.4.0.0--py36hdfd78af_0 ': - 'biocontainers/gatk4:4.4.0.0--py36hdfd78af_0' }"''', - 5, + 'quay.io/biocontainers/gatk4:4.4.0.0--py36hdfd78af_0' }"''', + 6, 0, 1, ), @@ -122,17 +122,17 @@ def test_process_labels(content, passed, warned, failed): ( '''container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? 'https://depot.galaxyproject.org/singularity/gatk4:4.4.0.0--py36hdfd78af_0 ': - "biocontainers/gatk4:4.4.0.0--py36hdfd78af_0" }"''', + "quay.io/biocontainers/gatk4:4.4.0.0--py36hdfd78af_0" }"''', 4, 0, 1, ), # Ternary with ? on next line (new Nextflow format) should pass ( - '''container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + '''container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c2/c262fc09eca59edb5a724080eeceb00fb06396f510aefb229c2d2c6897e63975/data' : 'community.wave.seqera.io/library/coreutils:9.5--ae99c88a9b28c264'}"''', - 6, + 7, 0, 0, ), @@ -144,7 +144,7 @@ def test_container_links(content, passed, warned, failed): for line in content.splitlines(): if line.strip(): - check_container_link_line(mock_lint, line, registry="quay.io") + check_container_link_line(mock_lint, line, registry=("quay.io", "community.wave.seqera.io/library/")) assert len(mock_lint.passed) == passed assert len(mock_lint.warned) == warned @@ -228,7 +228,7 @@ def setUp(self): if not self.mods_install.install("samtools/sort"): self.skipTest("Could not install samtools/sort module") if not self.mods_install.install("bamstats/generalstats"): - self.skipTest("Could not install samtools/sort module") + self.skipTest("Could not install bamstats/generalstats module") def test_main_nf_lint_with_alternative_registry(self): """Test main.nf linting with alternative container registry""" @@ -246,7 +246,10 @@ def test_main_nf_lint_with_alternative_registry(self): # Test with default registry - should pass cleanly module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir) module_lint.lint(print_results=False, module="samtools/sort") - assert len(module_lint.failed) == 0, f"Linting failed with {[x.__dict__ for x in module_lint.failed]}" + + # TODO: set to 0 once samtools/sort module is converted to new container syntax + assert len(module_lint.failed) == 1 + assert module_lint.failed[0].lint_test == "has_meta_containers" assert len(module_lint.passed) > 0 def test_additional_registry_from_nf_core_yml_passes_container_link(self): @@ -329,7 +332,7 @@ def test_topics_and_emits_version_check(self): module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir) module_lint.lint(print_results=False, module="bamstats/generalstats") assert len(module_lint.failed) == 0, f"Linting failed with {[x.__dict__ for x in module_lint.failed]}" - assert len(module_lint.warned) == 0, f"Expected 0 warnings, got {[x.__dict__ for x in module_lint.warned]}" + # assert len(module_lint.warned) == 0, f"Expected 0 warnings, got {[x.__dict__ for x in module_lint.warned]}" assert len(module_lint.passed) > 0 diff --git a/tests/modules/lint/test_meta_yml.py b/tests/modules/lint/test_meta_yml.py index 4bfe262981..a2319af04b 100644 --- a/tests/modules/lint/test_meta_yml.py +++ b/tests/modules/lint/test_meta_yml.py @@ -79,8 +79,8 @@ def test_modules_meta_yml_multiple_versions_channels(self): # Add a second versions channel to the output main_nf_modified = main_nf_original.replace( - "emit: versions", - "emit: versions_bpipe, topic: versions\n tuple val(\"${task.process}\"), val('test2'), eval('echo 1.0'), emit: versions_test, topic: versions", + "topic: versions, emit: versions_bpipe", + "topic: versions, emit: versions_bpipe\n tuple val(\"${task.process}\"), val('test2'), eval('echo 1.0'), emit: versions_test, topic: versions", ) with open(main_nf_path, "w") as fh: @@ -167,15 +167,12 @@ def test_modules_meta_yml_val_topic_gets_string_type(self): with open(main_nf_path) as fh: main_nf_original = fh.read() - # Read the original meta.yml - meta_yml_path = Path(self.nfcore_modules, "modules", "nf-core", "bpipe", "test", "meta.yml") - # Modify main.nf to use val() for version instead of eval() # This simulates a module like fastk that has hardcoded version main_nf_modified = re.sub( r'eval\("bpipe --version"\)', - "val('1.2')", + 'val("1.2")', main_nf_original, ) @@ -183,7 +180,7 @@ def test_modules_meta_yml_val_topic_gets_string_type(self): assert "eval" not in [line for line in main_nf_modified.split("\n") if "versions_bpipe" in line][0], ( "Replacement failed: eval still in versions line" ) - assert "val('1.2')" in main_nf_modified, "Replacement failed: val('1.2') not in main.nf" + assert 'val("1.2")' in main_nf_modified, 'Replacement failed: val("1.2") not in main.nf' with open(main_nf_path, "w") as fh: fh.write(main_nf_modified) @@ -192,12 +189,13 @@ def test_modules_meta_yml_val_topic_gets_string_type(self): module_lint = nf_core.modules.lint.ModuleLint(directory=self.nfcore_modules, fix=True) module_lint.lint(print_results=False, module="bpipe/test") - assert len(module_lint.failed) == 0, f"Expected 0 failed tests, got {len(module_lint.failed)}" - # Read the updated meta.yml + meta_yml_path = Path(self.nfcore_modules, "modules", "nf-core", "bpipe", "test", "meta.yml") with open(meta_yml_path) as fh: meta_yml = yaml.safe_load(fh) + assert len(module_lint.failed) == 0, f"Expected 0 failed tests, got {len(module_lint.failed)}" + # Check that topics.versions exists assert "topics" in meta_yml, "topics should be present in meta.yml" assert "versions" in meta_yml["topics"], "versions should be present in topics" diff --git a/tests/modules/lint/test_module_containers.py b/tests/modules/lint/test_module_containers.py new file mode 100644 index 0000000000..36dbb024a5 --- /dev/null +++ b/tests/modules/lint/test_module_containers.py @@ -0,0 +1,71 @@ +import logging +from pathlib import Path +from unittest import mock + +from nf_core.modules.lint.module_containers import lint_main_nf_container, lint_meta_yml_containers + + +def _make_component(component_dir: Path, *, has_dockerfile: bool = False, has_env_yml: bool = False): + """Return a mock NFCoreComponent with a real filesystem layout.""" + if has_dockerfile: + (component_dir / "Dockerfile").write_text("FROM ubuntu:22.04\n") + env_yml_path = component_dir / "environment.yml" + if has_env_yml: + env_yml_path.write_text("name: test\n") + + comp = mock.Mock() + comp.component_dir = component_dir + comp.component_name = "test/module" + comp.environment_yml = env_yml_path if has_env_yml else None + comp.passed = [] + comp.warned = [] + comp.failed = [] + return comp + + +# --------------------------------------------------------------------------- +# lint_meta_yml_containers – Dockerfile skip +# --------------------------------------------------------------------------- + + +def test_lint_meta_yml_containers_skips_dockerfile_module(tmp_path, caplog): + comp = _make_component(tmp_path, has_dockerfile=True) + with caplog.at_level(logging.DEBUG, logger="nf_core.modules.lint.module_containers"): + lint_meta_yml_containers(comp) + assert comp.passed == [] + assert comp.warned == [] + assert comp.failed == [] + assert "Dockerfile" in caplog.text + + +def test_lint_meta_yml_containers_skips_all_skip_flags_ignored_for_dockerfile(tmp_path): + """All skip flags should be irrelevant; the Dockerfile path returns unconditionally.""" + comp = _make_component(tmp_path, has_dockerfile=True) + lint_meta_yml_containers(comp, skip_docker=True, skip_conda=True, skip_singularity=True) + assert comp.passed == [] + assert comp.warned == [] + assert comp.failed == [] + + +# --------------------------------------------------------------------------- +# lint_main_nf_container – Dockerfile skip +# --------------------------------------------------------------------------- + + +def test_lint_main_nf_container_skips_dockerfile_module(tmp_path, caplog): + comp = _make_component(tmp_path, has_dockerfile=True) + with caplog.at_level(logging.DEBUG, logger="nf_core.modules.lint.module_containers"): + lint_main_nf_container(comp) + assert comp.passed == [] + assert comp.warned == [] + assert comp.failed == [] + assert "Dockerfile" in caplog.text + + +def test_lint_main_nf_container_dockerfile_skip_flag_ignored(tmp_path): + """skip_docker=True is a separate code path; Dockerfile modules return even earlier.""" + comp = _make_component(tmp_path, has_dockerfile=True) + lint_main_nf_container(comp, skip_docker=True) + assert comp.passed == [] + assert comp.warned == [] + assert comp.failed == [] diff --git a/tests/modules/lint/test_module_lint_integration.py b/tests/modules/lint/test_module_lint_integration.py index 8a77a969dd..cda1d82a91 100644 --- a/tests/modules/lint/test_module_lint_integration.py +++ b/tests/modules/lint/test_module_lint_integration.py @@ -11,8 +11,9 @@ def test_modules_lint_trimgalore(self): self.mods_install.install("trimgalore") module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir) module_lint.lint(print_results=False, module="trimgalore") - assert len(module_lint.failed) == 0, f"Linting failed with {[x.__dict__ for x in module_lint.failed]}" - assert len(module_lint.passed) > 0 + # TODO: set to 0 once trimgalore module is converted to new container syntax + assert len(module_lint.failed) == 1 + assert module_lint.failed[0].lint_test == "has_meta_containers" assert len(module_lint.warned) >= 0 def test_modules_lint_trinity(self): @@ -29,7 +30,9 @@ def test_modules_lint_tabix_tabix(self): self.mods_install.install("tabix/tabix") module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir) module_lint.lint(print_results=False, module="tabix/tabix") - assert len(module_lint.failed) == 0, f"Linting failed with {[x.__dict__ for x in module_lint.failed]}" + # TODO: set to 0 once tabix/tabix module is converted to new container syntax + assert len(module_lint.failed) == 1 + assert module_lint.failed[0].lint_test == "has_meta_containers" assert len(module_lint.passed) > 0 assert len(module_lint.warned) >= 0 diff --git a/tests/modules/lint/test_module_lint_remotes.py b/tests/modules/lint/test_module_lint_remotes.py index 6b8429d8c7..0a6afac88f 100644 --- a/tests/modules/lint/test_module_lint_remotes.py +++ b/tests/modules/lint/test_module_lint_remotes.py @@ -27,7 +27,7 @@ def test_modules_lint_gitlab_modules(self): self.mods_install_gitlab_nftest.install("multiqc") module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir, remote_url=GITLAB_URL) module_lint.lint(print_results=False, all_modules=True) - assert len(module_lint.failed) == 3 + assert len(module_lint.failed) == 4 assert len(module_lint.passed) > 0 assert len(module_lint.warned) >= 0 diff --git a/tests/modules/test_containers.py b/tests/modules/test_containers.py new file mode 100644 index 0000000000..7a9220d870 --- /dev/null +++ b/tests/modules/test_containers.py @@ -0,0 +1,355 @@ +import logging +from pathlib import Path +from unittest import mock + +import pytest +import yaml + +from nf_core.modules.containers import ModuleContainers +from nf_core.modules.modules_utils import CondaEntry, ContainerEntry, MetaYmlContainers +from nf_core.utils import CONTAINER_PLATFORMS, CONTAINER_SYSTEMS + +from ..test_modules import TestModules + + +class TestModuleContainers(TestModules): + """Tests for the ModuleContainers class""" + + def setUp(self): + super().setUp() + self.environment_yml = self.bpipe_test_module_path / "environment.yml" + self.module_containers = ModuleContainers("bpipe/test", directory=self.nfcore_modules) + + def _write_meta(self, meta: dict) -> None: + (self.bpipe_test_module_path / "meta.yml").write_text(yaml.safe_dump(meta), encoding="utf-8") + + def _containers_by_system(self, prefix: str = "testC") -> MetaYmlContainers: + return MetaYmlContainers( + docker={p: ContainerEntry(name=f"{prefix}-docker-{p}") for p in CONTAINER_PLATFORMS}, + singularity={p: ContainerEntry(name=f"{prefix}-singularity-{p}") for p in CONTAINER_PLATFORMS}, + conda={p: CondaEntry(lock_file=f"/path/to/{prefix}-{p}.txt") for p in CONTAINER_PLATFORMS}, + ) + + def test_init_sets_paths(self): + """Test that ModuleContainers initializes paths correctly""" + assert self.module_containers.directory == Path(self.nfcore_modules) + assert self.module_containers.module_directory == self.bpipe_test_module_path + assert self.module_containers.environment_yml == self.bpipe_test_module_path / "environment.yml" + assert self.module_containers.meta_yml == self.bpipe_test_module_path / "meta.yml" + + @mock.patch("nf_core.modules.containers.requests.get") + @mock.patch.object(ModuleContainers, "request_image_inspect") + @mock.patch("nf_core.modules.containers.run_cmd") + def test_create_builds_containers(self, mock_run_cmd, mock_request_image_inspect, mock_requests_get): + def fake_run_cmd(executable: str, args_str: str): + assert executable == "wave" + system = "singularity" if "--singularity" in args_str else "docker" + image = "community.wave.seqera.io/library/bpipe_test:0.1.0--abc123" + build_id = f"bd-abc123-{system}" + meta = { + "buildId": build_id, + "cached": True, + "containerImage": image, + "freeze": True, + "mirror": False, + "requestId": f"req-abc123-{system}", + "scanId": f"sc-abc123-{system}" if system == "docker" else None, + "succeeded": True, + "targetImage": image, + } + meta = {k: v for k, v in meta.items() if v is not None} + return (yaml.safe_dump(meta).encode(), b"") + + def fake_request_image_inspect(image: str): + return { + "container": { + "manifest": { + "layers": [ + { + "mediaType": "application/vnd.sif", + "digest": "sha256:abcde12345", + } + ] + } + } + } + + mock_response = mock.MagicMock() + mock_response.status_code = 200 + mock_response.text = "# conda lock file content" + mock_requests_get.return_value = mock_response + + mock_run_cmd.side_effect = fake_run_cmd + mock_request_image_inspect.side_effect = fake_request_image_inspect + + containers, success = self.module_containers.create() + assert self.module_containers.containers == containers + assert success + + for system in CONTAINER_SYSTEMS: + for platform in CONTAINER_PLATFORMS: + entry = getattr(containers, system)[platform] + assert entry.name == "community.wave.seqera.io/library/bpipe_test:0.1.0--abc123" + assert entry.build_id == f"bd-abc123-{system}" + if system == "docker": + assert entry.scan_id == f"sc-abc123-{system}" + platform_safe = platform.replace("/", "_") + build_id = f"bd-abc123-{system}" + expected_lock_path = str( + self.bpipe_test_module_path / ".conda-lock" / f"{platform_safe}-{build_id}.txt" + ) + assert containers.conda[platform].lock_file == expected_lock_path + else: + assert not entry.scan_id + + @mock.patch.object(ModuleContainers, "request_container") + def test_create_skips_conda_lock_when_build_id_missing(self, mock_request_container): + mock_request_container.return_value = ContainerEntry(name="bpipe_test-img") + containers, success = self.module_containers.create() + assert not containers.conda + + @mock.patch("nf_core.modules.containers.run_cmd") + def test_request_container_docker_success(self, mock_run_cmd): + platform = CONTAINER_PLATFORMS[0] + meta = {"targetImage": "testC:latest", "buildId": "build-1", "scanId": "scan-1", "succeeded": True} + mock_run_cmd.return_value = (yaml.safe_dump(meta).encode(), b"") + + container = ModuleContainers.request_container("docker", platform, self.environment_yml) + assert container.name == "testC:latest" + assert container.build_id == "build-1" + assert container.scan_id == "scan-1" + + args_str = mock_run_cmd.call_args[0][1] + assert "--await" in args_str + assert "--platform" in args_str + assert platform in args_str + assert "--singularity" not in args_str + + @mock.patch.object(ModuleContainers, "request_image_inspect") + @mock.patch("nf_core.modules.containers.run_cmd") + def test_request_container_singularity_adds_https(self, mock_run_cmd, mock_request_image_inspect): + platform = CONTAINER_PLATFORMS[0] + meta = {"containerImage": "testC:sif", "buildId": "build-2", "succeeded": True} + mock_run_cmd.return_value = (yaml.safe_dump(meta).encode(), b"") + mock_request_image_inspect.return_value = { + "container": { + "manifest": { + "layers": [ + { + "mediaType": "application/vnd.sif", + "digest": "sha256:abcde12345", + } + ] + } + } + } + + container = ModuleContainers.request_container("singularity", platform, self.environment_yml) + assert container.name == "testC:sif" + expected_url = "https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ab/abcde12345/data" + assert container.https == expected_url + mock_request_image_inspect.assert_called_once_with("testC:sif") + + @mock.patch("nf_core.modules.containers.run_cmd", return_value=None) + def test_request_container_missing_output_raises(self, mock_run_cmd): + with pytest.raises(RuntimeError, match="Wave command did not return any output"): + ModuleContainers.request_container("docker", CONTAINER_PLATFORMS[0], self.environment_yml) + + @mock.patch("nf_core.modules.containers.run_cmd") + def test_request_container_invalid_yaml_raises(self, mock_run_cmd): + mock_run_cmd.return_value = (b"invalid: [", b"") + with pytest.raises(RuntimeError, match="Could not parse wave YAML metadata"): + ModuleContainers.request_container("docker", CONTAINER_PLATFORMS[0], self.environment_yml) + + @mock.patch("nf_core.modules.containers.run_cmd") + def test_request_container_missing_image_raises(self, mock_run_cmd): + meta = {"buildId": "build-4", "succeeded": True} + mock_run_cmd.return_value = (yaml.safe_dump(meta).encode(), b"") + with pytest.raises(RuntimeError, match="did not return an image name"): + ModuleContainers.request_container("docker", CONTAINER_PLATFORMS[0], self.environment_yml) + + @mock.patch("nf_core.modules.containers.run_cmd") + def test_request_image_inspect_success(self, mock_run_cmd): + inspect_payload = {"container": {"manifest": {"layers": []}}} + mock_run_cmd.return_value = (yaml.safe_dump(inspect_payload).encode(), b"") + assert ModuleContainers.request_image_inspect("testC:latest") == inspect_payload + + def test_get_conda_lock_url_quotes(self): + build_id = "abc/def 123" + url = ModuleContainers.get_conda_lock_url(build_id) + assert "abc%2Fdef%20123" in url + assert url.endswith("/condalock") + + @mock.patch("nf_core.modules.containers.requests.get") + def test_get_conda_lock_file(self, mock_requests_get): + """Test that get_conda_lock_file downloads from the correct URL""" + mock_response = mock.MagicMock() + mock_response.status_code = 200 + mock_response.text = "# conda lock file content" + mock_requests_get.return_value = mock_response + + platform = CONTAINER_PLATFORMS[0] + # Partial build state: fill the dicts directly, as create() does + containers = MetaYmlContainers() + containers.docker[platform] = ContainerEntry(name="placeholder", build_id="test-build-123") + containers.conda[platform] = CondaEntry(lock_file="/some/path.txt") + self.module_containers.containers = containers + + result = self.module_containers.get_conda_lock_file(platform) + assert result == "# conda lock file content" + expected_url = "https://wave.seqera.io/v1alpha1/builds/test-build-123/condalock" + mock_requests_get.assert_called_once_with(expected_url) + + def test_list_containers(self): + containers = self._containers_by_system("testC") + with mock.patch.object(self.module_containers, "get_containers_from_meta", return_value=containers): + listed = self.module_containers.list_containers() + expected = [] + for cs in CONTAINER_SYSTEMS: + for p in CONTAINER_PLATFORMS: + expected.append((cs, p, getattr(containers, cs)[p].name)) + for p in CONTAINER_PLATFORMS: + expected.append(("conda", p, containers.conda[p].lock_file)) + assert listed == expected + + def test_get_containers_from_meta_missing_section(self): + self._write_meta({"name": "bpipe/test"}) + self.caplog.set_level(logging.DEBUG, logger="nf_core.modules.containers") + result = self.module_containers.get_containers_from_meta() + assert result is None + assert "Section 'containers' missing from meta.yaml" in self.caplog.text + + def test_get_containers_from_meta_missing_system(self): + singularity = {p: {"name": f"sif-{p}"} for p in CONTAINER_PLATFORMS} + self._write_meta({"name": "bpipe/test", "containers": {"singularity": singularity}}) + self.caplog.set_level(logging.DEBUG, logger="nf_core.modules.containers") + result = self.module_containers.get_containers_from_meta() + assert result is None + assert "No containers specified for docker" in self.caplog.text + + def test_get_containers_from_meta_missing_platform_key(self): + containers = { + "docker": {CONTAINER_PLATFORMS[0]: {"name": "img:1.0"}}, + "singularity": {CONTAINER_PLATFORMS[0]: {"name": "sif:1.0"}}, + } + self._write_meta({"name": "bpipe/test", "containers": containers}) + missing_platform = CONTAINER_PLATFORMS[1] + self.caplog.set_level(logging.DEBUG, logger="nf_core.modules.containers") + result = self.module_containers.get_containers_from_meta() + assert result is None + assert f"No docker entries found for expected platform: {missing_platform}" in self.caplog.text + + def test_get_containers_from_meta_partial_conda_ok(self): + """A conda section missing some platforms (e.g. skipped lock files) must not invalidate the model.""" + containers = { + "docker": {p: {"name": f"img-{p.replace('/', '-')}"} for p in CONTAINER_PLATFORMS}, + "singularity": {p: {"name": f"sif-{p.replace('/', '-')}"} for p in CONTAINER_PLATFORMS}, + "conda": {CONTAINER_PLATFORMS[0]: {"lock_file": "/lock/amd64.txt"}}, + } + self._write_meta({"name": "bpipe/test", "containers": containers}) + result = self.module_containers.get_containers_from_meta() + assert result is not None + assert CONTAINER_PLATFORMS[0] in result.conda + assert CONTAINER_PLATFORMS[1] not in result.conda + + def test_get_containers_from_meta_success(self): + containers = { + "docker": { + platform: {"name": f"docker-image-{platform.replace('/', '-')}:latest"} + for platform in CONTAINER_PLATFORMS + }, + "singularity": { + platform: {"name": f"singularity-image-{platform.replace('/', '-')}:latest"} + for platform in CONTAINER_PLATFORMS + }, + } + self._write_meta({"name": "bpipe/test", "containers": containers}) + result = self.module_containers.get_containers_from_meta() + assert result is not None + assert result == MetaYmlContainers.model_validate(containers) + + def test_update_containers_in_meta_merges(self): + self._write_meta({"name": "bpipe/test", "containers": {"docker": {"linux/amd64": {"name": "old"}}}}) + containers = self._containers_by_system("new") + self.module_containers.containers = containers + + with mock.patch.object(self.module_containers, "create") as mock_create: + self.module_containers.update_containers_in_meta() + mock_create.assert_not_called() + + meta = yaml.safe_load((self.bpipe_test_module_path / "meta.yml").read_text(encoding="utf-8")) + assert meta["containers"] == containers.dump_for_meta_yml() + + +class TestModuleContainersPipeline(TestModules): + """Tests for ModuleContainers against a real pipeline repository""" + + def _create_local_module(self, module_name: str = "testmodule") -> Path: + """Create a minimal local module under pipeline's modules/local/.""" + module_dir = self.pipeline_dir / "modules" / "local" / module_name + module_dir.mkdir(parents=True, exist_ok=True) + (module_dir / "environment.yml").write_text( + f"name: {module_name}\nchannels:\n - defaults\ndependencies:\n - python=3.11\n", + encoding="utf-8", + ) + (module_dir / "meta.yml").write_text(f"name: {module_name}\n", encoding="utf-8") + (module_dir / "main.nf").write_text("", encoding="utf-8") + return module_dir + + def test_init_pipeline_sets_local_module_paths(self): + """ModuleContainers should resolve paths into modules/local/ for a pipeline repo""" + module_dir = self._create_local_module("testmodule") + manager = ModuleContainers("testmodule", directory=self.pipeline_dir) + + assert manager.repo_type == "pipeline" + assert manager.module_directory == module_dir + assert manager.environment_yml == module_dir / "environment.yml" + assert manager.meta_yml == module_dir / "meta.yml" + + def test_update_containers_in_meta_pipeline(self): + """update_containers_in_meta writes containers to the local module's meta.yml""" + module_dir = self._create_local_module("testmodule") + + manager = ModuleContainers("testmodule", directory=self.pipeline_dir) + containers = MetaYmlContainers( + docker={p: ContainerEntry(name=f"docker-{p}") for p in CONTAINER_PLATFORMS}, + singularity={p: ContainerEntry(name=f"sif-{p}") for p in CONTAINER_PLATFORMS}, + conda={p: CondaEntry(lock_file=f"/lock/{p}.txt") for p in CONTAINER_PLATFORMS}, + ) + manager.containers = containers + + with mock.patch.object(manager, "create") as mock_create: + manager.update_containers_in_meta() + mock_create.assert_not_called() + + meta = yaml.safe_load((module_dir / "meta.yml").read_text(encoding="utf-8")) + assert meta["containers"] == containers.dump_for_meta_yml() + + +class TestModuleContainersDockerfile(TestModuleContainersPipeline): + """Tests for ModuleContainers behaviour when a module uses a Dockerfile instead of environment.yml""" + + def setUp(self): + super().setUp() + module_dir = self.pipeline_dir / "modules" / "local" / "dockermod" + module_dir.mkdir(parents=True, exist_ok=True) + (module_dir / "Dockerfile").write_text("FROM ubuntu:22.04\n", encoding="utf-8") + (module_dir / "meta.yml").write_text("name: dockermod\n", encoding="utf-8") + (module_dir / "main.nf").write_text('container "my/image:latest"\n', encoding="utf-8") + self.module_dir = module_dir + self.module_containers = ModuleContainers("dockermod", directory=self.pipeline_dir) + + def test_create_returns_empty_for_dockerfile_module(self): + containers, success = self.module_containers.create() + assert containers == MetaYmlContainers() + assert success + + def test_update_main_nf_container_skips_dockerfile_module(self): + original = (self.module_dir / "main.nf").read_text() + self.module_containers.update_main_nf_container() + assert (self.module_dir / "main.nf").read_text() == original + + def test_update_containers_in_meta_skips_dockerfile_module(self): + original_meta = (self.module_dir / "meta.yml").read_text() + self.module_containers.update_containers_in_meta() + assert (self.module_dir / "meta.yml").read_text() == original_meta diff --git a/tests/modules/test_modules_utils.py b/tests/modules/test_modules_utils.py index dd72236c9f..48996d3d5a 100644 --- a/tests/modules/test_modules_utils.py +++ b/tests/modules/test_modules_utils.py @@ -1,6 +1,11 @@ +from unittest import mock from unittest.mock import patch import nf_core.modules.modules_utils +from nf_core.modules.modules_utils import ( + module_uses_dockerfile, + scan_modules_dir, +) from ..test_modules import TestModules @@ -105,3 +110,74 @@ def test_load_edam(self): assert isinstance(first_key, str) assert isinstance(first_value, tuple) assert len(first_value) == 2 + + def test_scan_modules_dir_returns_module_names(self): + """Test that scan_modules_dir returns module names relative to the scanned directory""" + modules_dir = self.nfcore_modules / "modules" / "nf-core" + result = scan_modules_dir(modules_dir) + assert "bpipe/test" in result + + def test_scan_modules_dir_nonexistent(self): + """Test that scan_modules_dir returns an empty list for a nonexistent directory""" + result = scan_modules_dir(self.nfcore_modules / "does" / "not" / "exist") + assert result == [] + + def test_scan_modules_dir_multiple_modules(self): + """Test that scan_modules_dir returns all modules when multiple are present""" + modules_dir = self.nfcore_modules / "modules" / "nf-core" + extra = modules_dir / "samtools" / "sort" + extra.mkdir(parents=True) + (extra / "main.nf").touch() + try: + result = scan_modules_dir(modules_dir) + assert "bpipe/test" in result + assert "samtools/sort" in result + finally: + import shutil + + shutil.rmtree(modules_dir / "samtools") + + +def test_module_uses_dockerfile_true(tmp_path): + comp = mock.Mock() + comp.component_dir = tmp_path + comp.environment_yml = None + (tmp_path / "Dockerfile").write_text("FROM ubuntu:22.04\n") + assert module_uses_dockerfile(comp) + + +def test_module_uses_dockerfile_false_has_env_yml(tmp_path): + env_yml = tmp_path / "environment.yml" + env_yml.write_text("name: test\n") + comp = mock.Mock() + comp.component_dir = tmp_path + comp.environment_yml = env_yml + (tmp_path / "Dockerfile").write_text("FROM ubuntu:22.04\n") + assert not module_uses_dockerfile(comp) + + +def test_module_uses_dockerfile_false_no_dockerfile(tmp_path): + comp = mock.Mock() + comp.component_dir = tmp_path + comp.environment_yml = None + assert not module_uses_dockerfile(comp) + + +def test_module_uses_dockerfile_nonexistent_env_yml_path(tmp_path): + """environment_yml pointing to a non-existent file is treated as missing.""" + comp = mock.Mock() + comp.component_dir = tmp_path + comp.environment_yml = tmp_path / "environment.yml" + (tmp_path / "Dockerfile").write_text("FROM ubuntu:22.04\n") + assert module_uses_dockerfile(comp) + + +def test_module_uses_dockerfile_in_parent_dir(tmp_path): + """Dockerfile one level up (e.g. spaceranger/Dockerfile) is detected for submodules.""" + submodule_dir = tmp_path / "count" + submodule_dir.mkdir() + (tmp_path / "Dockerfile").write_text("FROM ubuntu:22.04\n") + comp = mock.Mock() + comp.component_dir = submodule_dir + comp.environment_yml = None + assert module_uses_dockerfile(comp) diff --git a/tests/test_modules.py b/tests/test_modules.py index e40d914c01..52603d7326 100644 --- a/tests/test_modules.py +++ b/tests/test_modules.py @@ -14,6 +14,7 @@ import nf_core.modules.modules_repo import nf_core.modules.remove from nf_core import __version__ +from nf_core.modules.modules_utils import CondaEntry, ContainerEntry, MetaYmlContainers from nf_core.pipelines.lint_utils import run_prettier_on_file from nf_core.utils import NFCoreYamlConfig @@ -65,6 +66,20 @@ def create_modules_repo_dummy(tmp_dir): meta_yml = yaml.load(fh) del meta_yml["tools"][0]["bpipe"]["doi"] meta_yml["keywords"] = ["pipelines", "bioinformatics", "run"] + docker = ContainerEntry(name="quay.io/biocontainers/bpipe:0.9.13--hdfd78af_0", build_id="", scan_id="") + sing = ContainerEntry( + name="oras://community.wave.seqera.io/library/bpipe:0.9.13--hdfd78af_0", + build_id="", + https="https://depot.galaxyproject.org/singularity/bpipe:0.9.13--hdfd78af_0", + ) + conda_amd64 = CondaEntry(lock_file="modules/nf-core/bpipe/test/.conda-lock/linux_amd64-bd-dummy_1.txt") + conda_arm64 = CondaEntry(lock_file="modules/nf-core/bpipe/test/.conda-lock/linux_arm64-bd-dummy_1.txt") + containers = MetaYmlContainers( + docker={"linux/amd64": docker, "linux/arm64": docker}, + singularity={"linux/amd64": sing, "linux/arm64": sing}, + conda={"linux/amd64": conda_amd64, "linux/arm64": conda_arm64}, + ) + meta_yml["containers"] = containers.dump_for_meta_yml() with open(str(meta_yml_path), "w") as fh: yaml.dump(meta_yml, fh) run_prettier_on_file(fh.name) From f82c4dcffcec4f7459f5131cdcf6e284ddf56724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 25 Jun 2026 06:24:55 +0200 Subject: [PATCH 074/135] bump to 4.0.3dev (#4348) --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a263340cd2..b5f2bb9544 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ nf_core = ["**/*"] [project] name = "nf-core" -version = "4.0.3" +version = "4.0.3dev" description = "Helper tools for use with nf-core Nextflow pipelines." readme = "README.md" license = "MIT" diff --git a/uv.lock b/uv.lock index 5038d67678..47efc64a9b 100644 --- a/uv.lock +++ b/uv.lock @@ -1615,7 +1615,7 @@ wheels = [ [[package]] name = "nf-core" -version = "4.0.3" +version = "4.0.3dev" source = { editable = "." } dependencies = [ { name = "click" }, From 5e17726aa460a3d6bb8aaecc5098c0f13b5305d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 25 Jun 2026 13:37:05 +0200 Subject: [PATCH 075/135] downgrade has_container failure to warning (#4350) --- nf_core/components/components_utils.py | 3 +++ nf_core/modules/lint/meta_yml.py | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/nf_core/components/components_utils.py b/nf_core/components/components_utils.py index 55238f2e8e..b4cc7bea18 100644 --- a/nf_core/components/components_utils.py +++ b/nf_core/components/components_utils.py @@ -19,6 +19,9 @@ yaml = ruamel.yaml.YAML() yaml.preserve_quotes = True yaml.indent(mapping=2, sequence=2, offset=0) +# Disable line wrapping: long plain-scalar keys (e.g. version `eval` expressions) +# become invalid YAML if ruamel folds them onto a second line. +yaml.width = 4096 def get_repo_info(directory: Path, use_prompt: bool | None = True) -> tuple[Path, str | None, str]: diff --git a/nf_core/modules/lint/meta_yml.py b/nf_core/modules/lint/meta_yml.py index 6ee8025522..d771536a75 100644 --- a/nf_core/modules/lint/meta_yml.py +++ b/nf_core/modules/lint/meta_yml.py @@ -335,11 +335,11 @@ def meta_yml(module_lint_object: ModuleLint, module: NFCoreComponent, allow_miss if container and not module_uses_dockerfile(module): if "containers" not in meta_yaml: if ContainerRegistryUrls.SEQERA_DOCKER.value in container: - module.failed.append( + module.warned.append( ( "meta_yml", "has_meta_containers", - f"Module `meta.yml` does not contain any containers, even though they appear in `main.nf`. Use `nf-core modules lint {module.component_name} --fix` to automatically resolve this.", + "Module `meta.yml` does not contain any containers, even though they appear in `main.nf`.", module.meta_yml, ) ) From 43cea914c6df5725f90819fa6852dab61f557a1d Mon Sep 17 00:00:00 2001 From: znorgaard Date: Fri, 12 Jun 2026 15:26:56 -0700 Subject: [PATCH 076/135] fix: correct always-true lint condition and template doc typos - linting.yml: the non-release lint step used `base_ref != 'master' || base_ref != 'main'`, which is always true (a value can't equal both), so the non-release lint also ran on release PRs to main/master. Use `&&` so it runs only when the base is neither. - CONTRIBUTING.md: fix broken `[Lint](lint)` checklist link -> `#lint-tests` (matches the correct anchor used earlier in the same file); remove a duplicate "the the". - usage.md: remove stray leading space inside the Wave Nextflow-version code span (`` ` 24.03.0-edge` `` -> `` `24.03.0-edge` ``). Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 1 + nf_core/pipeline-template/.github/workflows/linting.yml | 2 +- nf_core/pipeline-template/docs/CONTRIBUTING.md | 4 ++-- nf_core/pipeline-template/docs/usage.md | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e3af72c0f..90fc7b9f30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ - add `process_low_memory` resource label to `base.config` ([#4264](https://github.com/nf-core/tools/pull/4264)) - fix dead link ([#4307](https://github.com/nf-core/tools/pull/4307)) - remove date placeholder from changelog title ([#4333](https://github.com/nf-core/tools/pull/4333)) +- correct always-true `nf-core pipelines lint` condition in the linting workflow and fix doc typos (broken `#lint-tests` anchor, duplicate word, stray code-span space) ([#XXXX](https://github.com/nf-core/tools/pull/XXXX)) #### Version updates diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 05f710dce7..02e176a455 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -46,7 +46,7 @@ jobs: run: uv tool install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} - name: Run nf-core pipelines lint - if: ${{ github.base_ref != 'master' || github.base_ref != 'main' }} + if: ${{ github.base_ref != 'master' && github.base_ref != 'main' }} env: GITHUB_COMMENTS_URL: ${{ github.event.pull_request.comments_url }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/nf_core/pipeline-template/docs/CONTRIBUTING.md b/nf_core/pipeline-template/docs/CONTRIBUTING.md index 866c124543..981b29509e 100644 --- a/nf_core/pipeline-template/docs/CONTRIBUTING.md +++ b/nf_core/pipeline-template/docs/CONTRIBUTING.md @@ -144,7 +144,7 @@ Please also refer to the [pipeline-specific contribution guidelines](#pipeline-s - [ ] Perform local tests to validate that the new code works as expected. - [ ] If applicable, add a new test in the `tests` directory. - [ ] Update `usage.md`, `output.md`, and `citation.md` as appropriate. -- [ ] [Lint](lint) the code with nf-core/tools. +- [ ] [Lint](#lint-tests) the code with nf-core/tools. - [ ] Update any diagrams or pipeline images as necessary. {%- if multiqc %} - [ ] Update MultiQC config `assets/multiqc_config.yml` so relevant suffixes, file name cleanup, and module plots are in the appropriate order. @@ -184,7 +184,7 @@ Specify these with generic `withLabel:` selectors, so they can be shared across nf-core provides a set of standard labels that you should follow where possible, as seen in the [nf-core pipeline template](https://github.com/nf-core/tools/blob/main/nf_core/pipeline-template/conf/base.config). These labels define resource defaults for single-core processes, modules that require a GPU, and different levels of multi-core configurations with increasing memory requirements. -Values assigned within these labels can be dynamically passed to a tool using the the `${task.cpus}` and `${task.memory}` Nextflow variables in the `script:` block of a module (see an example in the [modules repository](https://github.com/nf-core/modules/blob/bd1b6a40f55933d94b8c9ca94ec8c1ea0eaf4b82/modules/nf-core/samtools/bam2fq/main.nf#L30)). +Values assigned within these labels can be dynamically passed to a tool using the `${task.cpus}` and `${task.memory}` Nextflow variables in the `script:` block of a module (see an example in the [modules repository](https://github.com/nf-core/modules/blob/bd1b6a40f55933d94b8c9ca94ec8c1ea0eaf4b82/modules/nf-core/samtools/bam2fq/main.nf#L30)). #### Nextflow version bumping diff --git a/nf_core/pipeline-template/docs/usage.md b/nf_core/pipeline-template/docs/usage.md index a711f0d0a2..ca7e7748fd 100644 --- a/nf_core/pipeline-template/docs/usage.md +++ b/nf_core/pipeline-template/docs/usage.md @@ -165,7 +165,7 @@ If `-profile` is not specified, the pipeline will run locally and expect all sof - `apptainer` - A generic configuration profile to be used with [Apptainer](https://apptainer.org/) - `wave` - - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow ` 24.03.0-edge` or later). + - A generic configuration profile to enable [Wave](https://seqera.io/wave/) containers. Use together with one of the above (requires Nextflow `24.03.0-edge` or later). - `conda` - A generic configuration profile to be used with [Conda](https://conda.io/docs/). Please only use Conda as a last resort i.e. when it's not possible to run the pipeline with Docker, Singularity, Podman, Shifter, Charliecloud, or Apptainer. From 0f26a20d62febaef97222ae6145461a0fd773700 Mon Sep 17 00:00:00 2001 From: znorgaard Date: Fri, 12 Jun 2026 15:36:58 -0700 Subject: [PATCH 077/135] docs: fill in PR number in changelog entry Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90fc7b9f30..5942c75913 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,7 @@ - add `process_low_memory` resource label to `base.config` ([#4264](https://github.com/nf-core/tools/pull/4264)) - fix dead link ([#4307](https://github.com/nf-core/tools/pull/4307)) - remove date placeholder from changelog title ([#4333](https://github.com/nf-core/tools/pull/4333)) -- correct always-true `nf-core pipelines lint` condition in the linting workflow and fix doc typos (broken `#lint-tests` anchor, duplicate word, stray code-span space) ([#XXXX](https://github.com/nf-core/tools/pull/XXXX)) +- correct always-true `nf-core pipelines lint` condition in the linting workflow and fix doc typos (broken `#lint-tests` anchor, duplicate word, stray code-span space) ([#4324](https://github.com/nf-core/tools/pull/4324)) #### Version updates From 7232dd2ecd1a1077a7714be03a38cd63408e8b83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Mon, 29 Jun 2026 14:55:34 +0200 Subject: [PATCH 078/135] improve singularity_tag linting check (add skip, handle exceptions correctly, check against oras) (#4358) Co-authored-by: nf-core-bot --- CHANGELOG.md | 1 + nf_core/modules/lint/main_nf.py | 43 +++++++++++-- tests/modules/lint/test_lint_utils.py | 5 ++ tests/modules/lint/test_main_nf.py | 60 ++++++++++++++++++- .../lint/test_module_lint_integration.py | 8 +-- .../modules/lint/test_module_lint_remotes.py | 5 +- 6 files changed, 106 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e3af72c0f..752ae77db7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - accept `process_low_memory` as a standard module label ([#4264](https://github.com/nf-core/tools/pull/4264)) - improve linting for `modules.json` to add support for only installing subworkflows from a repository and provide more explicit error messages ([#4287](https://github.com/nf-core/tools/pull/4287)) +- improve singularity_tag linting check (add skip, handle exceptions correctly, check against oras) ([#4358](https://github.com/nf-core/tools/pull/4358)) ### Modules diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 1bbd11c1b0..e4b791f70a 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -10,6 +10,7 @@ from nf_core.components.components_differ import ComponentsDiffer from nf_core.components.nfcore_component import NFCoreComponent +from nf_core.modules.lint.meta_yml import _load_skip_nf_test_sets log = logging.getLogger(__name__) @@ -41,6 +42,17 @@ def main_nf( is issued if they do not match. Modules using the newer docker-only format (no singularity container) skip this check. + * ``singularity_tag``: A Singularity container must be resolvable via + ``nextflow inspect -profile singularity``. The check fails if none can be + resolved or if it falls back to a docker container that has an automatic + singularity equivalent, i.e., ``quay.io/biocontainers/`` or + ``community.wave.seqera.io/``. + It is skipped for modules listed under ``singularity`` in ``.github/skip_nf_test.json``. + + * ``oras_singularity_tag``: The resolved Singularity container must not be + served over the ``oras://`` scheme; it should be a plain ``https://`` URL. + The check fails if an ``oras://`` container is used. + * ``main_nf_script_shell``: Exactly one of ``script:``, ``shell:``, or ``exec:`` blocks must be present. @@ -435,16 +447,35 @@ def check_process_section( singularity_container = self.get_container_with_inspect(profile="singularity") # `nextflow inspect -profile singularity` falls back to the docker container when the - # module has no singularity-specific image. A genuine singularity reference is a remote - # URL (`https://…`) or an `oras://…` reference, so anything else is the docker fallback - # and must not be treated as a singularity container. - if singularity_container is not None and not singularity_container.startswith(("https:", "oras:")): + # module has no singularity-specific image. A bare biocontainers/Seqera docker image is + # such a fallback (a genuine singularity image would be an `https://` or `oras://` URL), + # so it must not be treated as a singularity container. + if singularity_container is not None and singularity_container.startswith( + ("quay.io/biocontainers/", "community.wave.seqera.io/") + ): singularity_container = None - if singularity_container is not None: + # Modules listed under "singularity" in .github/skip_nf_test.json have no singularity + # container on purpose, so the singularity_tag check is skipped for them. + skip_singularity = str(Path(self.component_dir).resolve()) in _load_skip_nf_test_sets(str(self.base_dir)).get( + "singularity", frozenset() + ) + + if skip_singularity: + log.debug(f"Skipping singularity_tag check for {self.component_name} (skipped in skip_nf_test.json)") + elif singularity_container is not None: self.passed.append( ("main_nf", "singularity_tag", f"Found singularity container: {singularity_container}", self.main_nf) ) + if singularity_container.startswith("oras://"): + self.failed.append( + ("main_nf", "oras_singularity_tag", "Singularity container should not use oras:// scheme", self.main_nf) + ) + else: + self.passed.append( + ("main_nf", "oras_singularity_tag", "Singularity container uses valid scheme", self.main_nf) + ) + else: self.failed.append(("main_nf", "singularity_tag", "Unable to resolve singularity container", self.main_nf)) if docker_container is not None: @@ -666,7 +697,7 @@ def check_container_link_line(self, raw_line, registry): ( "main_nf", "container_links", - f"Container prefix is not correct. Please add one of the allowed registry prefixes: {', '.join(registry) if isinstance(registry, tuple) else registry}", + f"Container prefix is not correct. Please add one of the allowed registry prefixes: {', '.join(registry)}", self.main_nf, ) ) diff --git a/tests/modules/lint/test_lint_utils.py b/tests/modules/lint/test_lint_utils.py index 2b4dbbff7f..ed9b3398a9 100644 --- a/tests/modules/lint/test_lint_utils.py +++ b/tests/modules/lint/test_lint_utils.py @@ -20,6 +20,11 @@ def __init__(self): # drive the `nextflow inspect` based container resolution without a real Nextflow. self.inspect_containers: dict[str | None, str | None] = {} + self.component_name = "" + self.process_name = "" + self.component_dir = None + self.base_dir = None + def get_container_with_inspect(self, profile=None): return self.inspect_containers.get(profile) diff --git a/tests/modules/lint/test_main_nf.py b/tests/modules/lint/test_main_nf.py index 5d51c2b1e5..0893987d67 100644 --- a/tests/modules/lint/test_main_nf.py +++ b/tests/modules/lint/test_main_nf.py @@ -210,6 +210,62 @@ def test_check_process_section_additional_registries(container_line, additional_ assert not prefix_passed, f"Container prefix should not pass; passed={mock_lint.passed}" +@pytest.mark.parametrize( + "singularity_container,singularity_tag,oras_singularity_tag", + [ + # `nextflow inspect -profile singularity` fell back to a bare docker image (a + # biocontainers / seqera prefix, no https:/oras: URL) -> nulled -> singularity_tag + # fails and the oras check is not emitted. Both prefixes in the production + # startswith() tuple are covered. + ("quay.io/biocontainers/gatk4:4.4.0.0--py36hdfd78af_0", "fail", "absent"), + ("community.wave.seqera.io/library/gatk4:4.4.0.0--abc123", "fail", "absent"), + # Genuine https:// singularity URL -> both checks pass + ("https://depot.galaxyproject.org/singularity/gatk4:4.4.0.0--py36hdfd78af_0", "pass", "pass"), + # Allowed docker container fallback + ("quay.io/nf-core/bclconvert:4.5.4", "pass", "pass"), + ("nvcr.io/nvidia/clara/clara-parabricks:4.6.0-1", "pass", "pass"), + # oras:// resolves a container (singularity_tag passes) but the scheme is invalid + ("oras://community.wave.seqera.io/library/gatk4:4.4.0.0--abc123", "pass", "fail"), + ], +) +def test_check_process_section_singularity_container( + singularity_container, singularity_tag, oras_singularity_tag, tmp_path +): + """A biocontainers/seqera docker image must have a genuine https:// singularity equivalent. + When `nextflow inspect -profile singularity` falls back to the docker container the + singularity_tag check fails, and an oras:// container fails the oras_singularity_tag check. + The outcome depends only on the resolved singularity container, so a fixed docker container + is used.""" + docker_container = "quay.io/biocontainers/gatk4:4.4.0.0--py36hdfd78af_0" + mock_lint = MockModuleLint() + mock_lint.component_name = "tool/subtool" + mock_lint.process_name = "TOOL_SUBTOOL" + mock_lint.component_dir = tmp_path + mock_lint.base_dir = tmp_path + mock_lint.inspect_containers = {"docker": docker_container, "singularity": singularity_container} + + check_process_section( + mock_lint, + [f"container '{docker_container}'"], + ("quay.io", "community.wave.seqera.io/library/"), + False, + None, + ) + + def assert_outcome(lint_test, expected): + passed = any(r[1] == lint_test for r in mock_lint.passed) + failed = any(r[1] == lint_test for r in mock_lint.failed) + if expected == "pass": + assert passed and not failed, f"Expected {lint_test} to pass; passed={passed}, failed={failed}" + elif expected == "fail": + assert failed and not passed, f"Expected {lint_test} to fail; passed={passed}, failed={failed}" + else: # absent + assert not passed and not failed, f"Expected {lint_test} to be absent; passed={passed}, failed={failed}" + + assert_outcome("singularity_tag", singularity_tag) + assert_outcome("oras_singularity_tag", oras_singularity_tag) + + class TestMainNfLinting(TestModules): """ Test main.nf linting functionality. @@ -247,9 +303,7 @@ def test_main_nf_lint_with_alternative_registry(self): module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir) module_lint.lint(print_results=False, module="samtools/sort") - # TODO: set to 0 once samtools/sort module is converted to new container syntax - assert len(module_lint.failed) == 1 - assert module_lint.failed[0].lint_test == "has_meta_containers" + assert len(module_lint.failed) == 0 assert len(module_lint.passed) > 0 def test_additional_registry_from_nf_core_yml_passes_container_link(self): diff --git a/tests/modules/lint/test_module_lint_integration.py b/tests/modules/lint/test_module_lint_integration.py index cda1d82a91..6b891076c1 100644 --- a/tests/modules/lint/test_module_lint_integration.py +++ b/tests/modules/lint/test_module_lint_integration.py @@ -11,9 +11,7 @@ def test_modules_lint_trimgalore(self): self.mods_install.install("trimgalore") module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir) module_lint.lint(print_results=False, module="trimgalore") - # TODO: set to 0 once trimgalore module is converted to new container syntax - assert len(module_lint.failed) == 1 - assert module_lint.failed[0].lint_test == "has_meta_containers" + assert len(module_lint.failed) == 0 assert len(module_lint.warned) >= 0 def test_modules_lint_trinity(self): @@ -30,9 +28,7 @@ def test_modules_lint_tabix_tabix(self): self.mods_install.install("tabix/tabix") module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir) module_lint.lint(print_results=False, module="tabix/tabix") - # TODO: set to 0 once tabix/tabix module is converted to new container syntax - assert len(module_lint.failed) == 1 - assert module_lint.failed[0].lint_test == "has_meta_containers" + assert len(module_lint.failed) == 0 assert len(module_lint.passed) > 0 assert len(module_lint.warned) >= 0 diff --git a/tests/modules/lint/test_module_lint_remotes.py b/tests/modules/lint/test_module_lint_remotes.py index 0a6afac88f..3b5c297f2f 100644 --- a/tests/modules/lint/test_module_lint_remotes.py +++ b/tests/modules/lint/test_module_lint_remotes.py @@ -27,7 +27,10 @@ def test_modules_lint_gitlab_modules(self): self.mods_install_gitlab_nftest.install("multiqc") module_lint = nf_core.modules.lint.ModuleLint(directory=self.pipeline_dir, remote_url=GITLAB_URL) module_lint.lint(print_results=False, all_modules=True) - assert len(module_lint.failed) == 4 + assert len(module_lint.failed) == 3 + # check that the failed tests are environment_yml_valid, main_nf_versio_ topic (twice) + for result in module_lint.failed: + assert result.lint_test in ["environment_yml_valid", "main_nf_version_topic"] assert len(module_lint.passed) > 0 assert len(module_lint.warned) >= 0 From 0f3564c701baaf064eee90432acdd58584a2fb36 Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Fri, 26 Jun 2026 11:54:04 +0100 Subject: [PATCH 079/135] Support include statements that use double-quotes --- nf_core/components/nfcore_component.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nf_core/components/nfcore_component.py b/nf_core/components/nfcore_component.py index 0fa3e19351..b5ca2fdfef 100644 --- a/nf_core/components/nfcore_component.py +++ b/nf_core/components/nfcore_component.py @@ -152,7 +152,9 @@ def _get_included_components(self, main_nf: Path | str): #'plugin/nf-validation' component = line.strip().split()[-1].split(self.org)[-1].split("main")[0].strip("/") component = component.replace("'../", "subworkflows/") + # Replace trailing quotes component = component.replace("'", "") + component = component.replace('"', "") included_components.append(component) return included_components From 7de0dd5106798e672612fdac15faa8730c607135 Mon Sep 17 00:00:00 2001 From: Matthieu Muffato Date: Mon, 29 Jun 2026 14:00:20 +0100 Subject: [PATCH 080/135] Update nf_core/components/nfcore_component.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- nf_core/components/nfcore_component.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nf_core/components/nfcore_component.py b/nf_core/components/nfcore_component.py index b5ca2fdfef..e620881aad 100644 --- a/nf_core/components/nfcore_component.py +++ b/nf_core/components/nfcore_component.py @@ -153,8 +153,7 @@ def _get_included_components(self, main_nf: Path | str): component = line.strip().split()[-1].split(self.org)[-1].split("main")[0].strip("/") component = component.replace("'../", "subworkflows/") # Replace trailing quotes - component = component.replace("'", "") - component = component.replace('"', "") + component = component.replace("'", "").replace('"', "") included_components.append(component) return included_components From 3905251f26d47bc188c408d862a897ddb27841bd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 13:13:39 +0000 Subject: [PATCH 081/135] Update GitHub Actions to ad2b381 (#4332) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/branch.yml | 2 +- .github/workflows/changelog.yml | 6 +++--- .github/workflows/create-lint-wf.yml | 2 +- .github/workflows/create-test-lint-wf-template.yml | 2 +- .github/workflows/create-test-wf.yml | 2 +- .github/workflows/deploy-pypi.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/lint-code.yml | 2 +- .github/workflows/nextflow-source-test.yml | 4 ++-- .github/workflows/pytest.yml | 2 +- .github/workflows/sync.yml | 2 +- .github/workflows/update-template-snapshots.yml | 2 +- .github/workflows/update-textual-snapshots.yml | 2 +- .../pipeline-template/.github/actions/nf-test/action.yml | 2 +- nf_core/pipeline-template/.github/workflows/branch.yml | 2 +- .../.github/workflows/download_pipeline.yml | 2 +- nf_core/pipeline-template/.github/workflows/fix_linting.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 4 ++-- .../.github/workflows/template-version-comment.yml | 2 +- 19 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index 240dc2dae0..addbc7bcbd 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -18,7 +18,7 @@ jobs: # If the above check failed, post a comment on the PR explaining the failure - name: Post PR comment if: failure() - uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0 # v3 + uses: mshick/add-pr-comment@ec328af66588ab8f77cdeb2c264f14aba45bbf59 # v3 with: message: | ## This PR is against the `main` branch :x: diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 355e3fc9ff..4847d9063d 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -31,7 +31,7 @@ jobs: PR_NUMBER="${{ github.event.issue.number }}" gh pr checkout $PR_NUMBER - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" @@ -60,12 +60,12 @@ jobs: echo "changed=$file_changed" >> $GITHUB_OUTPUT - name: Set up Python 3.14 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" - name: Run pre-commit rules with prek - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 + uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 continue-on-error: true with: extra-args: --config .pre-commit-config.yaml --all-files diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 33ab1652b3..a344acff45 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -47,7 +47,7 @@ jobs: # Set up nf-core/tools - name: Set up Python 3.14 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index 47048ba41d..698ee79f53 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -59,7 +59,7 @@ jobs: uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Set up Python 3.14 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index 667821f695..e394ddd041 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -45,7 +45,7 @@ jobs: name: Check out source-code repository - name: Set up Python 3.14 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index 0e76048c38..f843e0b321 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -17,7 +17,7 @@ jobs: name: Check out source-code repository - name: Set up Python 3.14 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 285c517c4e..f04cfdf678 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -33,7 +33,7 @@ jobs: # Install and run prek - name: Run prek id: prek - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 + uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 with: extra-args: --config .pre-commit-config.yaml --all-files continue-on-error: true diff --git a/.github/workflows/lint-code.yml b/.github/workflows/lint-code.yml index 37f2e68d44..d7efa84e9b 100644 --- a/.github/workflows/lint-code.yml +++ b/.github/workflows/lint-code.yml @@ -22,6 +22,6 @@ jobs: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 - name: Run prek - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 + uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 with: extra-args: --config .pre-commit-config.yaml --all-files diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index a02fae87db..d53cb46728 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -20,7 +20,7 @@ jobs: path: nextflow - name: Set up Java - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5 + uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5 with: distribution: "temurin" architecture: x64 @@ -45,7 +45,7 @@ jobs: # Set up nf-core/tools - name: Set up Python 3.14 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 1c6009cf00..c31e0dfb43 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -76,7 +76,7 @@ jobs: name: Check out source-code repository - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: ${{ matrix.python-version }} token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 5d4ff98ba0..42a4bbc98b 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -77,7 +77,7 @@ jobs: fetch-depth: "0" - name: Set up Python 3.14 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index 910e93785b..11f9f5e915 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -56,7 +56,7 @@ jobs: # Install dependencies and run pytest - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index bbb7534ab4..e441f4f37c 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -37,7 +37,7 @@ jobs: # Install dependencies and run pytest - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" diff --git a/nf_core/pipeline-template/.github/actions/nf-test/action.yml b/nf_core/pipeline-template/.github/actions/nf-test/action.yml index 17137be3ab..90397426f6 100644 --- a/nf_core/pipeline-template/.github/actions/nf-test/action.yml +++ b/nf_core/pipeline-template/.github/actions/nf-test/action.yml @@ -25,7 +25,7 @@ runs: version: "{% raw %}${{ env.NXF_VERSION }}" - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" diff --git a/nf_core/pipeline-template/.github/workflows/branch.yml b/nf_core/pipeline-template/.github/workflows/branch.yml index 27468bc072..7677c6f9e5 100644 --- a/nf_core/pipeline-template/.github/workflows/branch.yml +++ b/nf_core/pipeline-template/.github/workflows/branch.yml @@ -21,7 +21,7 @@ jobs: # NOTE - this doesn't currently work if the PR is coming from a fork, due to limitations in GitHub actions secrets - name: Post PR comment if: failure() - uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0 # v3 + uses: mshick/add-pr-comment@ec328af66588ab8f77cdeb2c264f14aba45bbf59 # v3 with: message: | ## This PR is against the `${{github.event.pull_request.base.ref}}` branch :x: diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index b2dad9611b..9d78212009 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -47,7 +47,7 @@ jobs: - name: Disk space cleanup uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" architecture: "x64" diff --git a/nf_core/pipeline-template/.github/workflows/fix_linting.yml b/nf_core/pipeline-template/.github/workflows/fix_linting.yml index 17314baca5..1cdbc24762 100644 --- a/nf_core/pipeline-template/.github/workflows/fix_linting.yml +++ b/nf_core/pipeline-template/.github/workflows/fix_linting.yml @@ -37,7 +37,7 @@ jobs: # Install and run prek - name: Run prek id: prek - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 + uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 continue-on-error: true # indication that the linting has finished diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 05f710dce7..4186ad6982 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -17,7 +17,7 @@ jobs: uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 - name: Run prek - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2 + uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 nf-core: runs-on: ubuntu-latest @@ -28,7 +28,7 @@ jobs: - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 - - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.14" architecture: "x64" diff --git a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml index a3333571e1..36ab701eb5 100644 --- a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml +++ b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml @@ -29,7 +29,7 @@ jobs: run: echo "OUTPUT=$(pip list --outdated | grep nf-core)" >> ${GITHUB_ENV} - name: Post nf-core template version comment - uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0 # v3 + uses: mshick/add-pr-comment@ec328af66588ab8f77cdeb2c264f14aba45bbf59 # v3 if: | contains(env.OUTPUT, 'nf-core') with: From fd52c20a9cd73a5f242c9fbae4f43d6e64e576ba Mon Sep 17 00:00:00 2001 From: Maxime U Garcia Date: Mon, 29 Jun 2026 15:35:03 +0200 Subject: [PATCH 082/135] Template: Fix publishDir configuration in modules.config for multiqc (#4347) Co-authored-by: nf-core-bot Co-authored-by: mashehu --- CHANGELOG.md | 1 + nf_core/pipeline-template/conf/modules.config | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 752ae77db7..c24613366d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - add `process_low_memory` resource label to `base.config` ([#4264](https://github.com/nf-core/tools/pull/4264)) - fix dead link ([#4307](https://github.com/nf-core/tools/pull/4307)) - remove date placeholder from changelog title ([#4333](https://github.com/nf-core/tools/pull/4333)) +- Fix publishDir configuration in modules.config for multiqc ([#4347](https://github.com/nf-core/tools/pull/4347)) #### Version updates diff --git a/nf_core/pipeline-template/conf/modules.config b/nf_core/pipeline-template/conf/modules.config index 1614e2b1a9..2e49e26edd 100644 --- a/nf_core/pipeline-template/conf/modules.config +++ b/nf_core/pipeline-template/conf/modules.config @@ -31,8 +31,7 @@ process { ext.args = { params.multiqc_title ? "--title \"$params.multiqc_title\"" : '' } publishDir = [ path: { "${params.outdir}/multiqc" }, - mode: params.publish_dir_mode, - saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + mode: params.publish_dir_mode ] } {%- endif %} From 8cc943ac0575925a78a792c514e3c6d7a441c69e Mon Sep 17 00:00:00 2001 From: Josua Carl <53010862+JosuaCarl@users.noreply.github.com> Date: Tue, 30 Jun 2026 14:59:33 +0200 Subject: [PATCH 083/135] Added "apptainer" as an option for containerization engine in downloads (#4352) * Added apptainer as an option for containerization engine in downloads * Added apptainer download test * Fixed singularity tests by renaming methods * Added changes to CHANGELOG.md --------- Co-authored-by: JosuaCarl-Agents --- CHANGELOG.md | 4 + nf_core/__main__.py | 2 +- nf_core/pipelines/download/download.py | 23 ++- nf_core/pipelines/download/singularity.py | 142 ++++++++++++------ .../local/passing/mock_dsl2_old/main.nf | 2 +- .../apptainer_containers.json | 11 ++ tests/pipelines/download/test_download.py | 37 +++++ tests/pipelines/download/test_singularity.py | 103 ++++++++++++- 8 files changed, 257 insertions(+), 67 deletions(-) create mode 100644 tests/data/mock_pipeline_containers/per_profile_output/apptainer_containers.json diff --git a/CHANGELOG.md b/CHANGELOG.md index c24613366d..72c986a74c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,10 @@ - remove date placeholder from changelog title ([#4333](https://github.com/nf-core/tools/pull/4333)) - Fix publishDir configuration in modules.config for multiqc ([#4347](https://github.com/nf-core/tools/pull/4347)) +### Download + +- Included support for Apptainer in `nf-core pipelines download --container-system apptainer` ([#4352](https://github.com/nf-core/tools/pull/4352)) + #### Version updates ## [v4.0.2 - Bold Boa Patch 2](https://github.com/nf-core/tools/releases/tag/4.0.2) - [2026-04-30] diff --git a/nf_core/__main__.py b/nf_core/__main__.py index ce79e8714a..e05bfa0b43 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -372,7 +372,7 @@ def command_pipelines_lint( @click.option( "-s", "--container-system", - type=click.Choice(["none", "singularity", "docker"]), + type=click.Choice(["none", "singularity", "docker", "apptainer"]), help="Download container images of required software.", ) @click.option( diff --git a/nf_core/pipelines/download/download.py b/nf_core/pipelines/download/download.py index 1c999cbd47..f02c24fbfc 100644 --- a/nf_core/pipelines/download/download.py +++ b/nf_core/pipelines/download/download.py @@ -43,6 +43,8 @@ force_terminal=nf_core.utils.rich_force_colors(), ) +SINGULARITY_SYSTEMS = ["singularity", "apptainer"] + class DownloadWorkflow: """Downloads a nf-core workflow from GitHub to the local file system. @@ -249,7 +251,7 @@ def download_workflow(self) -> None: ] if self.container_system: summary_log.append(f"Container library: '{', '.join(self.container_library)}'") - if self.container_system == "singularity" and os.environ.get(SINGULARITY_CACHE_DIR_ENV_VAR) is not None: + if self.container_system in SINGULARITY_SYSTEMS and os.environ.get(SINGULARITY_CACHE_DIR_ENV_VAR) is not None: summary_log.append( f"Using [blue]{SINGULARITY_CACHE_DIR_ENV_VAR}[/]': {os.environ[SINGULARITY_CACHE_DIR_ENV_VAR]}'" ) @@ -331,7 +333,7 @@ def download_workflow_static(self) -> None: raise DownloadError("Error editing pipeline config file to use local configs!") from e # Collect all required container images - if self.container_system in {"singularity", "docker"}: + if self.container_system in {"singularity", "docker", "apptainer"}: workflow_directory = self.outdir / revision_dirname self.find_container_images(workflow_directory, revision) @@ -367,7 +369,7 @@ def download_workflow_platform(self, location: Path | None = None) -> None: self.workflow_repo.bare_clone(self.output_filename) # extract the required containers - if self.container_system in {"singularity", "docker"}: + if self.container_system in {"singularity", "docker", "apptainer"}: for revision, commit in self.wf_sha.items(): # Checkout the repo in the current revision self.workflow_repo.checkout(commit) @@ -503,7 +505,7 @@ def prompt_container_download(self) -> None: stderr.print("\nIn addition to the pipeline code, this tool can download software containers.") self.container_system = questionary.select( "Download software container images:", - choices=["none", "singularity", "docker"], + choices=["none", "singularity", "docker", "apptainer"], style=nf_core.utils.nfcore_question_style, ).unsafe_ask() @@ -513,7 +515,7 @@ def setup_container_fetcher(self) -> None: """ assert self.outdir is not None # mypy try: - if self.container_system == "singularity": + if self.container_system in SINGULARITY_SYSTEMS: self.container_fetcher = SingularityFetcher( outdir=self.outdir, container_library=self.container_library, @@ -522,6 +524,7 @@ def setup_container_fetcher(self) -> None: container_cache_index=self.container_cache_index, parallel=self.parallel, hide_progress=self.hide_progress, + container_system=self.container_system, ) elif self.container_system == "docker": self.container_fetcher = DockerFetcher( @@ -556,9 +559,9 @@ def prompt_compression_type(self) -> None: stderr.print( "\nIf transferring the downloaded files to another system, it can be convenient to have everything compressed in a single file." ) - if self.container_system == "singularity": + if self.container_system in SINGULARITY_SYSTEMS: stderr.print( - "[bold]This is [italic]not[/] recommended when downloading Singularity images, as it can take a long time and saves very little space." + "[bold]This is [italic]not[/] recommended when downloading Singularity/Apptainer images, as it can take a long time and saves very little space." ) self.compress_type = questionary.select( "Choose compression type:", @@ -646,6 +649,12 @@ def wf_use_local_configs(self, revision_dirname: str) -> None: + 'singularity.cacheDir = "${projectDir}/../singularity-images/"' + "\n///////////////////////////////////////" ) + elif self.container_system == "apptainer" and self.container_cache_utilisation == "copy": + nfconfig += ( + f"\n\n// Added by `nf-core pipelines download` v{nf_core.__version__} //\n" + + 'apptainer.cacheDir = "${projectDir}/../apptainer-images/"' + + "\n///////////////////////////////////////" + ) # Write the file out again log.debug(f"Updating '{nfconfig_fn}'") diff --git a/nf_core/pipelines/download/singularity.py b/nf_core/pipelines/download/singularity.py index 5c15ef3c56..c0ecb5f8f5 100644 --- a/nf_core/pipelines/download/singularity.py +++ b/nf_core/pipelines/download/singularity.py @@ -34,6 +34,30 @@ SINGULARITY_CACHE_DIR_ENV_VAR = "NXF_SINGULARITY_CACHEDIR" SINGULARITY_LIBRARY_DIR_ENV_VAR = "NXF_SINGULARITY_LIBRARYDIR" +APPTAINER_CACHE_DIR_ENV_VAR = "NXF_APPTAINER_CACHEDIR" +APPTAINER_LIBRARY_DIR_ENV_VAR = "NXF_APPTAINER_LIBRARYDIR" + + +def get_container_cache_dir(container_system: str) -> str: + """Returns the matching cache directory environment variable.""" + match container_system: + case "singularity": + return SINGULARITY_CACHE_DIR_ENV_VAR + case "apptainer": + return APPTAINER_CACHE_DIR_ENV_VAR + case _: + raise KeyError(f"Container engine: {container_system} is unknown.") + + +def get_container_library_dir(container_system: str) -> str: + """Returns the matching library directory environment variable.""" + match container_system: + case "singularity": + return SINGULARITY_LIBRARY_DIR_ENV_VAR + case "apptainer": + return APPTAINER_LIBRARY_DIR_ENV_VAR + case _: + raise KeyError(f"Container engine: {container_system} is unknown.") class SingularityProgress(ContainerProgress): @@ -74,21 +98,28 @@ def __init__( container_cache_index=None, parallel: int = 4, hide_progress: bool = False, + container_system: str = "singularity", ): + self.container_system = container_system + self.container_system_name = container_system.capitalize() + self.cache_dir_env_var = get_container_cache_dir(container_system) + self.library_dir_env_var = get_container_library_dir(container_system) # Check if the env variable for the Singularity cache directory is set - has_cache_dir = os.environ.get(SINGULARITY_CACHE_DIR_ENV_VAR) is not None + has_cache_dir = os.environ.get(self.cache_dir_env_var) is not None if not has_cache_dir and stderr.is_interactive: # Prompt for the creation of a Singularity cache directory - has_cache_dir = SingularityFetcher.prompt_singularity_cachedir_creation() + has_cache_dir = SingularityFetcher.prompt_cachedir_creation(container_system) if has_cache_dir and container_cache_utilisation is None: # No choice regarding singularity cache has been made. - container_cache_utilisation = SingularityFetcher.prompt_singularity_cachedir_utilization() + container_cache_utilisation = SingularityFetcher.prompt_cachedir_utilization( + container_system, self.cache_dir_env_var + ) if container_cache_utilisation == "remote": # If we have a remote cache, we need to read it if container_cache_index is None and stderr.is_interactive: - container_cache_index = SingularityFetcher.prompt_singularity_cachedir_remote() + container_cache_index = SingularityFetcher.prompt_cachedir_remote(self.cache_dir_env_var) if container_cache_index is None: # No remote cache specified self.container_cache_index = None @@ -102,30 +133,28 @@ def __init__( ) except (FileNotFoundError, LookupError) as e: log.error( - f"[red]Issue with reading the specified remote ${SINGULARITY_CACHE_DIR_ENV_VAR} index:[/]\n{e}\n" + f"[red]Issue with reading the specified remote ${self.cache_dir_env_var} index:[/]\n{e}\n" ) if stderr.is_interactive and rich.prompt.Confirm.ask( "[blue]Specify a new index file and try again?" ): - container_cache_index = SingularityFetcher.prompt_singularity_cachedir_remote() + container_cache_index = SingularityFetcher.prompt_cachedir_remote(self.cache_dir_env_var) else: - log.info( - f"Proceeding without consideration of the remote ${SINGULARITY_CACHE_DIR_ENV_VAR} index." - ) + log.info(f"Proceeding without consideration of the remote ${self.cache_dir_env_var} index.") self.container_cache_index = None - container_cache_utilisation = "copy" if os.environ.get(SINGULARITY_CACHE_DIR_ENV_VAR) else None + container_cache_utilisation = "copy" if os.environ.get(self.cache_dir_env_var) else None else: log.warning("[red]No remote cache index specified, skipping remote container download.[/]") # Find out what the library directory is - library_dir = Path(path_str) if (path_str := os.environ.get(SINGULARITY_LIBRARY_DIR_ENV_VAR)) else None + library_dir = Path(path_str) if (path_str := os.environ.get(self.library_dir_env_var)) else None if library_dir and not library_dir.is_dir(): # Since the library is read-only, if the directory isn't there, we can forget about it library_dir = None # Find out what the cache directory is - cache_dir = Path(path_str) if (path_str := os.environ.get(SINGULARITY_CACHE_DIR_ENV_VAR)) else None - log.debug(f"{SINGULARITY_CACHE_DIR_ENV_VAR}: {cache_dir}") + cache_dir = Path(path_str) if (path_str := os.environ.get(self.cache_dir_env_var)) else None + log.debug(f"{self.cache_dir_env_var}: {cache_dir}") if container_cache_utilisation in ["amend", "copy"]: if cache_dir: @@ -133,9 +162,11 @@ def __init__( log.debug(f"Cache directory not found, creating: {cache_dir}") cache_dir.mkdir() else: - raise FileNotFoundError(f"Singularity cache is required but no '{SINGULARITY_CACHE_DIR_ENV_VAR}' set!") + raise FileNotFoundError( + f"{self.container_system_name} cache is required but no '{self.cache_dir_env_var}' set!" + ) - container_output_dir = outdir / "singularity-images" + container_output_dir = outdir / f"{container_system}-images" super().__init__( container_output_dir=container_output_dir, container_library=container_library, @@ -155,7 +186,9 @@ def check_and_set_implementation(self) -> None: Raises: OSError: If Singularity/Apptainer is not installed or not in $PATH """ - if shutil.which("singularity"): + if shutil.which(self.container_system): + self.implementation = self.container_system + elif shutil.which("singularity"): self.implementation = "singularity" elif shutil.which("apptainer"): self.implementation = "apptainer" @@ -209,11 +242,11 @@ def get_cache_dir(self) -> Path: Raises: FileNotFoundError: If the cache directory is not set """ - cache_dir = os.environ.get(SINGULARITY_CACHE_DIR_ENV_VAR) + cache_dir = os.environ.get(self.cache_dir_env_var) if cache_dir is not None: return Path(cache_dir) else: - raise FileNotFoundError(f"Singularity cache is required but no '{SINGULARITY_CACHE_DIR_ENV_VAR}' set!") + raise FileNotFoundError(f"Singularity cache is required but no '{self.cache_dir_env_var}' set!") def make_cache_dir(self) -> None: """ @@ -225,33 +258,36 @@ def make_cache_dir(self) -> None: cache_dir.mkdir() @staticmethod - def prompt_singularity_cachedir_creation() -> bool: - """Prompt about using singularity cache directory if not already set""" + def prompt_cachedir_creation(container_system: str = "singularity") -> bool: + """Prompt about using singularity/apptainer cache directory if not already set""" if not nf_core.utils.is_interactive(): return False + # Define cache_dir_env_var + cache_dir_env_var = get_container_cache_dir(container_system) + container_system_name = container_system.capitalize() stderr.print( - f"\nNextflow and nf-core can use an environment variable called [blue]${SINGULARITY_CACHE_DIR_ENV_VAR}[/] that is a path to a directory where remote Singularity images are stored. " + f"\nNextflow and nf-core can use an environment variable called [blue]${cache_dir_env_var}[/] that is a path to a directory where remote {container_system_name} images are stored. " f"This allows downloaded images to be cached in a central location." ) if rich.prompt.Confirm.ask( - f"[blue bold]?[/] [bold]Define [blue not bold]${SINGULARITY_CACHE_DIR_ENV_VAR}[/] for a shared Singularity image download folder?[/]" + f"[blue bold]?[/] [bold]Define [blue not bold]${cache_dir_env_var}[/] for a shared {container_system_name} image download folder?[/]" ): - cachedir_path = SingularityFetcher.prompt_singularity_cachedir_path() + cachedir_path = SingularityFetcher.prompt_cachedir_path(cache_dir_env_var) if cachedir_path is None: - raise DownloadError(f"No {SINGULARITY_CACHE_DIR_ENV_VAR} specified, cannot continue.") + raise DownloadError(f"No {cache_dir_env_var} specified, cannot continue.") - os.environ[SINGULARITY_CACHE_DIR_ENV_VAR] = str(cachedir_path) + os.environ[cache_dir_env_var] = str(cachedir_path) # Optionally, create a permanent entry for the singularity cache directory in the terminal profile. - SingularityFetcher.prompt_singularity_cachedir_shellprofile_append(cachedir_path) + SingularityFetcher.prompt_cachedir_shellprofile_append(cachedir_path, cache_dir_env_var) return True return False @staticmethod - def prompt_singularity_cachedir_path() -> Path | None: - """Prompt for the name of the Singularity cache directory""" + def prompt_cachedir_path(cache_dir_env_var: str = SINGULARITY_CACHE_DIR_ENV_VAR) -> Path | None: + """Prompt for the name of the Singularity / Apptainer cache directory""" if not nf_core.utils.is_interactive(): log.warning("Cannot prompt for Singularity cache directory in a non-interactive session.") return None @@ -264,7 +300,7 @@ def prompt_singularity_cachedir_path() -> Path | None: style=nf_core.utils.nfcore_question_style, ).unsafe_ask() if prompt_cachedir_path == "": - log.error(f"Not using [blue]${SINGULARITY_CACHE_DIR_ENV_VAR}[/]") + log.error(f"Not using [blue]${cache_dir_env_var}[/]") return None cachedir_path = Path(prompt_cachedir_path).expanduser().absolute() if not cachedir_path.is_dir(): @@ -273,9 +309,11 @@ def prompt_singularity_cachedir_path() -> Path | None: return cachedir_path @staticmethod - def prompt_singularity_cachedir_shellprofile_append(cachedir_path: Path) -> None: + def prompt_cachedir_shellprofile_append( + cachedir_path: Path, cache_dir_env_var: str = SINGULARITY_CACHE_DIR_ENV_VAR + ) -> None: """ - Prompt about appending the Singularity cache directory to the shell profile + Prompt about appending the Singularity / Apptainer cache directory to the shell profile Currently support for bash and zsh. ToDo: "sh", "dash", "ash","csh", "tcsh", "ksh", "fish", "cmd", "powershell", "pwsh"? @@ -298,9 +336,9 @@ def prompt_singularity_cachedir_shellprofile_append(cachedir_path: Path) -> None return if shellprofile_path is not None: stderr.print( - f"\nSo that [blue]${SINGULARITY_CACHE_DIR_ENV_VAR}[/] is always defined, you can add it to your [blue not bold]~/{shellprofile_path.name}[/] file ." + f"\nSo that [blue]${cache_dir_env_var}[/] is always defined, you can add it to your [blue not bold]~/{shellprofile_path.name}[/] file ." "This will then be automatically set every time you open a new terminal. We can add the following line to this file for you: \n" - f'[blue]export {SINGULARITY_CACHE_DIR_ENV_VAR}="{cachedir_path}"[/]' + f'[blue]export {cache_dir_env_var}="{cachedir_path}"[/]' ) append_to_file = rich.prompt.Confirm.ask( f"[blue bold]?[/] [bold]Add to [blue not bold]~/{shellprofile_path.name}[/] ?[/]" @@ -310,7 +348,7 @@ def prompt_singularity_cachedir_shellprofile_append(cachedir_path: Path) -> None f.write( "\n\n#######################################\n" f"## Added by `nf-core pipelines download` v{nf_core.__version__} ##\n" - + f'export {SINGULARITY_CACHE_DIR_ENV_VAR}="{cachedir_path}"' + + f'export {cache_dir_env_var}="{cachedir_path}"' + "\n#######################################\n" ) log.info(f"Successfully wrote to [blue]{shellprofile_path}[/]") @@ -319,24 +357,26 @@ def prompt_singularity_cachedir_shellprofile_append(cachedir_path: Path) -> None log.debug(f"No shell profile found for {shell}.") @staticmethod - def prompt_singularity_cachedir_utilization() -> str: - """Ask if we should *only* use singularity cache directory without copying into target""" + def prompt_cachedir_utilization( + container_system: str = "singularity", cache_dir_env_var: str = SINGULARITY_CACHE_DIR_ENV_VAR + ) -> str: + """Ask if we should *only* use singularity/apptainer cache directory without copying into target""" if not nf_core.utils.is_interactive(): return "copy" stderr.print( "\nIf you are working on the same system where you will run Nextflow, you can amend the downloaded images to the ones in the" - f"[blue not bold]${SINGULARITY_CACHE_DIR_ENV_VAR}[/] folder, Nextflow will automatically find them. " + f"[blue not bold]${cache_dir_env_var}[/] folder, Nextflow will automatically find them. " "However if you will transfer the downloaded files to a different system then they should be copied to the target folder." ) return questionary.select( - f"Copy singularity images from {SINGULARITY_CACHE_DIR_ENV_VAR} to the target folder or amend new images to the cache?", + f"Copy {container_system} images from {cache_dir_env_var} to the target folder or amend new images to the cache?", choices=["amend", "copy"], style=nf_core.utils.nfcore_question_style, ).unsafe_ask() @staticmethod - def prompt_singularity_cachedir_remote() -> Path | None: - """Prompt about the index of a remote singularity cache directory""" + def prompt_cachedir_remote(cache_dir_env_var: str = SINGULARITY_CACHE_DIR_ENV_VAR) -> Path | None: + """Prompt about the index of a remote singularity/apptainer cache directory""" if not nf_core.utils.is_interactive(): log.warning("Cannot prompt for remote cache index in a non-interactive session.") return None @@ -349,7 +389,7 @@ def prompt_singularity_cachedir_remote() -> Path | None: style=nf_core.utils.nfcore_question_style, ).unsafe_ask() if prompt_cachedir_index == "": - log.error(f"Will disregard contents of a remote [blue]${SINGULARITY_CACHE_DIR_ENV_VAR}[/]") + log.error(f"Will disregard contents of a remote [blue]${cache_dir_env_var}[/]") return None cachedir_index = Path(prompt_cachedir_index).expanduser().absolute() if not os.access(cachedir_index, os.R_OK): @@ -506,9 +546,9 @@ def update_file_progress(input_params: tuple[str, Path], status: FileDownloader. downloader.download_files_in_parallel(containers_download, parallel_downloads, callback=update_file_progress) - def pull_images(self, containers_pull: Iterable[tuple[str, Path]]) -> None: + def pull_images(self, containers_pull: Iterable[tuple[str, Path]], container_system: str = "singularity") -> None: """ - Pull a set of container images using `singularity pull`. + Pull a set of container images using `singularity/apptainer pull`. Args: containers_pull (Iterable[tuple[str, Path]]): A list of container names and output paths. @@ -560,8 +600,8 @@ def pull_images(self, containers_pull: Iterable[tuple[str, Path]]) -> None: self.progress.update_remote_fetch_task(advance=1) def construct_pull_command(self, output_path: Path, address: str): - singularity_command = [self.implementation, "pull", "--name", str(output_path), address] - return singularity_command + pull_command = [self.implementation, "pull", "--name", str(output_path), address] + return pull_command def get_address(self, container, library) -> tuple[str, bool]: # Sometimes, container still contain an explicit library specification, which @@ -578,9 +618,11 @@ def get_address(self, container, library) -> tuple[str, bool]: return address, absolute_URI - def pull_image(self, container: str, output_path: Path, library: str) -> bool: + def pull_image( + self, container: str, output_path: Path, library: str, container_system: str = "singularity" + ) -> bool: """ - Pull a singularity image using `singularity pull`. + Pull a singularity/apptainer image using `singularity/apptainer pull`. Args: container (str): A pipeline's container name. Usually it is of similar format @@ -603,14 +645,14 @@ def pull_image(self, container: str, output_path: Path, library: str) -> bool: container, start=False, total=False, - progress_type="singularity_pull", + progress_type=f"{container_system}_pull", current_log="", ) as task: self._ensure_output_dir_exists() with intermediate_file_no_creation(output_path) as output_path_tmp: singularity_command = self.construct_pull_command(output_path_tmp, address) - log.debug(f"Building singularity image: {address}") - # Run the singularity pull command + log.debug(f"Building {container_system} image: {address}") + # Run the singularity/apptainer pull command with subprocess.Popen( singularity_command, stdout=subprocess.PIPE, diff --git a/tests/data/mock_pipeline_containers/modules/local/passing/mock_dsl2_old/main.nf b/tests/data/mock_pipeline_containers/modules/local/passing/mock_dsl2_old/main.nf index db08a99b8c..4871eef215 100644 --- a/tests/data/mock_pipeline_containers/modules/local/passing/mock_dsl2_old/main.nf +++ b/tests/data/mock_pipeline_containers/modules/local/passing/mock_dsl2_old/main.nf @@ -2,7 +2,7 @@ process MOCK_DSL2_OLD { label 'process_fake' conda (params.enable_conda ? "bioconda::dsltwoold=0.23.0" : null) - if (workflow.containerEngine == 'singularity' && !params.singularity_pull_docker_container) { + if ((workflow.containerEngine == 'singularity' || workflow.containerEngine == 'apptainer') && !params.singularity_pull_docker_container) { container "https://depot.galaxyproject.org/singularity/dsltwoold:0.23.0--0" } else { container "quay.io/biocontainers/dsltwoold:0.23.0--0" diff --git a/tests/data/mock_pipeline_containers/per_profile_output/apptainer_containers.json b/tests/data/mock_pipeline_containers/per_profile_output/apptainer_containers.json new file mode 100644 index 0000000000..4c6345ae22 --- /dev/null +++ b/tests/data/mock_pipeline_containers/per_profile_output/apptainer_containers.json @@ -0,0 +1,11 @@ +{ + "MOCK_DOCKER_SINGLE_QUAY_IO": "quay.io/biocontainers/singlequay:1.9--pyh9f0ad1d_0", + "MOCK_DSL2_APPTAINER_VAR1": "https://depot.galaxyproject.org/singularity/dsltwoapptainervarone:1.1.0--py38h7be5676_2", + "MOCK_DSL2_APPTAINER_VAR2": "https://depot.galaxyproject.org/singularity/dsltwoapptainervartwo:1.1.0--hdfd78af_0", + "MOCK_DSL2_CURRENT": "biocontainers/dsltwocurrent:1.2.1--pyhdfd78af_0", + "MOCK_DSL2_CURRENT_INVERTED": "biocontainers/dsltwocurrentinv:3.3.2--h1b792b2_1", + "MOCK_DSL2_OLD": "https://depot.galaxyproject.org/singularity/dsltwoold:0.23.0--0", + "MOCK_SEQERA_CONTAINER_HTTP": "community.wave.seqera.io/library/coreutils:9.5--ae99c88a9b28c264", + "MOCK_SEQERA_CONTAINER_ORAS": "community.wave.seqera.io/library/umi-transfer:1.0.0--d30e8812ea280fa1", + "MOCK_SEQERA_CONTAINER_ORAS_MULLED": "community.wave.seqera.io/library/umi-transfer_umicollapse:3298d4f1b49e33bd" +} diff --git a/tests/pipelines/download/test_download.py b/tests/pipelines/download/test_download.py index 8000a4a413..092817b067 100644 --- a/tests/pipelines/download/test_download.py +++ b/tests/pipelines/download/test_download.py @@ -280,6 +280,43 @@ def test_containers_pipeline_singularity(self, tmp_path, mock_fetch_wf_config): f"Containers that should've been found: {ref_container_strs}" ) + # + # Test that `find_container_images` (uses `nextflow inspect`) fetches the correct Apptainer images + # + @pytest.mark.skipif( + shutil.which("nextflow") is None or not check_nextflow_version(NF_INSPECT_MIN_NF_VERSION), + reason="Can't run test that requires nextflow to run if not installed.", + ) + @with_temporary_folder + @mock.patch("nf_core.utils.fetch_wf_config") + def test_containers_pipeline_apptainer(self, tmp_path, mock_fetch_wf_config): + tmp_path = Path(tmp_path) + assert check_nextflow_version(NF_INSPECT_MIN_NF_VERSION) is True + + # Set up test + container_system = "apptainer" + mock_pipeline_dir = TEST_DATA_DIR / "mock_pipeline_containers" + refererence_json_dir = mock_pipeline_dir / "per_profile_output" + # First check that `-profile apptainer` produces the same output as the reference + download_obj = DownloadWorkflow(pipeline="dummy", outdir=tmp_path, container_system=container_system) + mock_fetch_wf_config.return_value = {} + + # Run get containers with `nextflow inspect` + # NF >= 26.04 rejects old-style if/else container directives (mock_dsl2_old uses them) + entrypoint = "main_passing_test.nf" + with self._strict_syntax_ctx(match="downgrade to Nextflow"): + download_obj.find_container_images(mock_pipeline_dir, "dummy-revision", entrypoint=entrypoint) + + if not self.nf_strict_syntax: + found_containers = set(download_obj.containers) + with open(refererence_json_dir / f"{container_system}_containers.json") as fh: + ref_containers = json.load(fh) + ref_container_strs = set(ref_containers.values()) + assert found_containers == ref_container_strs, ( + f"Containers found in pipeline by `nextflow inspect`: {found_containers}\n" + f"Containers that should've been found: {ref_container_strs}" + ) + # # Test that `find_container_images` (uses `nextflow inspect`) fetches the correct Docker images # diff --git a/tests/pipelines/download/test_singularity.py b/tests/pipelines/download/test_singularity.py index 78958dbcb6..c7b56c1a3f 100644 --- a/tests/pipelines/download/test_singularity.py +++ b/tests/pipelines/download/test_singularity.py @@ -20,6 +20,8 @@ SingularityError, SingularityFetcher, SingularityProgress, + get_container_cache_dir, + get_container_library_dir, ) from nf_core.pipelines.download.utils import DownloadError @@ -119,6 +121,91 @@ def __contains__(self, item: str) -> bool: """ return any(record.message == item for record in self._caplog.records if self._caplog) + # + # Tests for the cache and library directory environment variable functions + # + def test_get_container_cache_dir_env_vars(self): + assert get_container_cache_dir("singularity") == "NXF_SINGULARITY_CACHEDIR" + assert get_container_cache_dir("apptainer") == "NXF_APPTAINER_CACHEDIR" + with pytest.raises(KeyError): + get_container_cache_dir("docker") + + def test_get_container_library_dir_env_vars(self): + assert get_container_library_dir("singularity") == "NXF_SINGULARITY_LIBRARYDIR" + assert get_container_library_dir("apptainer") == "NXF_APPTAINER_LIBRARYDIR" + with pytest.raises(KeyError): + get_container_library_dir("docker") + + # + # Tests for constructing SingularityFetcher with different container_system values + # + @with_temporary_folder + @mock.patch("nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation") + def test_apptainer_fetcher_constructor(self, tmp_path, mock_cachedir_prompt): + mock_cachedir_prompt.return_value = False + tmp_path = Path(tmp_path) + fetcher = SingularityFetcher( + outdir=tmp_path, + container_library=[], + registry_set=[], + container_cache_utilisation="none", + container_system="apptainer", + ) + assert fetcher.container_system == "apptainer" + assert fetcher.container_system_name == "Apptainer" + assert fetcher.cache_dir_env_var == "NXF_APPTAINER_CACHEDIR" + assert fetcher.library_dir_env_var == "NXF_APPTAINER_LIBRARYDIR" + assert fetcher._container_output_dir == tmp_path / "apptainer-images" + + @with_temporary_folder + @mock.patch("nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation") + def test_singularity_fetcher_constructor(self, tmp_path, mock_cachedir_prompt): + mock_cachedir_prompt.return_value = False + tmp_path = Path(tmp_path) + fetcher = SingularityFetcher( + outdir=tmp_path, + container_library=[], + registry_set=[], + container_cache_utilisation="none", + ) + assert fetcher.container_system == "singularity" + assert fetcher.container_system_name == "Singularity" + assert fetcher.cache_dir_env_var == "NXF_SINGULARITY_CACHEDIR" + assert fetcher.library_dir_env_var == "NXF_SINGULARITY_LIBRARYDIR" + assert fetcher._container_output_dir == tmp_path / "singularity-images" + + # + # Tests for 'construct_pull_command' with different implementations + # + @mock.patch("nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation") + def test_construct_pull_command_apptainer(self, mock_cachedir_prompt): + mock_cachedir_prompt.return_value = False + fetcher = SingularityFetcher( + outdir=Path("/tmp"), + container_library=[], + registry_set=[], + container_cache_utilisation="none", + container_system="apptainer", + ) + fetcher.implementation = "apptainer" + output_path = Path("/tmp/test.sif") + command = fetcher.construct_pull_command(output_path, "docker://hello-world") + assert command == ["apptainer", "pull", "--name", str(output_path), "docker://hello-world"] + + @mock.patch("nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation") + def test_construct_pull_command_singularity(self, mock_cachedir_prompt): + mock_cachedir_prompt.return_value = False + fetcher = SingularityFetcher( + outdir=Path("/tmp"), + container_library=[], + registry_set=[], + container_cache_utilisation="none", + ) + fetcher.implementation = "singularity" + output_path = Path("/tmp/test.sif") + command = fetcher.construct_pull_command(output_path, "docker://hello-world") + assert command == ["singularity", "pull", "--name", str(output_path), "docker://hello-world"] + # # Tests for 'singularity_pull_image' # @@ -131,7 +218,7 @@ def __contains__(self, item: str) -> bool: @with_temporary_folder @mock.patch("nf_core.pipelines.download.singularity.SingularityProgress") @mock.patch( - "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_singularity_cachedir_creation" + "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation" ) # This is to make sure that we do not prompt for a Singularity cachedir def test_singularity_pull_image_singularity_installed(self, tmp_dir, mock_cachedir_prompt, mock_progress): tmp_dir = Path(tmp_dir) @@ -217,7 +304,7 @@ def test_singularity_pull_image_singularity_installed(self, tmp_dir, mock_cached @mock.patch("nf_core.utils.fetch_wf_config") @mock.patch("nf_core.pipelines.download.singularity.SingularityFetcher.gather_registries") @mock.patch( - "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_singularity_cachedir_creation" + "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation" ) # This is to make sure that we do not prompt for a Singularity cachedir def test_fetch_containers_singularity( self, tmp_path, mock_cachedir_prompt, mock_gather_registries, mock_fetch_wf_config @@ -260,7 +347,7 @@ def test_fetch_containers_singularity( "nf_core.pipelines.download.singularity.SingularityFetcher.check_and_set_implementation" ) # This is to make sure that we do not check for Singularity/Apptainer installation @mock.patch( - "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_singularity_cachedir_creation" + "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation" ) # This is to make sure that we do not prompt for a Singularity cachedir @mock.patch("pathlib.Path.mkdir") @mock.patch("pathlib.Path.symlink_to") @@ -341,7 +428,7 @@ def test_symlink_singularity_images( "nf_core.pipelines.download.singularity.SingularityFetcher.check_and_set_implementation" ) # This is to make sure that we do not check for Singularity/Apptainer installation @mock.patch( - "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_singularity_cachedir_creation" + "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation" ) # This is to make sure that we do not prompt for a Singularity cachedir @mock.patch("pathlib.Path.mkdir") @mock.patch("pathlib.Path.symlink_to") @@ -423,7 +510,7 @@ def test_symlink_singularity_symlink_registries( @with_temporary_folder @mock.patch("nf_core.pipelines.download.singularity.SingularityProgress") @mock.patch( - "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_singularity_cachedir_creation" + "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation" ) # This is to make sure that we do not prompt for a Singularity cachedir def test_singularity_pull_image_successfully(self, tmp_dir, mock_cachedir_prompt, mock_progress): tmp_dir = Path(tmp_dir) @@ -443,7 +530,7 @@ def test_singularity_pull_image_successfully(self, tmp_dir, mock_cachedir_prompt @with_temporary_folder @mock.patch("nf_core.utils.fetch_wf_config") @mock.patch( - "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_singularity_cachedir_creation" + "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation" ) # This is to make sure that we do not prompt for a Singularity cachedir def test_gather_registries_singularity(self, tmp_path, mock_cachedir_prompt, mock_fetch_wf_config): tmp_path = Path(tmp_path) @@ -492,7 +579,7 @@ def test_gather_registries_singularity(self, tmp_path, mock_cachedir_prompt, moc @with_temporary_folder @mock.patch("rich.progress.Progress.add_task") @mock.patch( - "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_singularity_cachedir_creation" + "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation" ) # This is to make sure that we do not prompt for a Singularity cachedir def test_singularity_pull_image_singularity_not_installed(self, tmp_dir, mock_rich_progress, mock_cachedir_prompt): tmp_dir = Path(tmp_dir) @@ -512,7 +599,7 @@ def test_singularity_pull_image_singularity_not_installed(self, tmp_dir, mock_ri @mock.patch("nf_core.pipelines.download.singularity.SingularityFetcher.check_and_set_implementation") @mock.patch( - "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_singularity_cachedir_creation" + "nf_core.pipelines.download.singularity.SingularityFetcher.prompt_cachedir_creation" ) # This is to make sure that we do not prompt for a Singularity cachedir def test_singularity_get_container_filename(self, mock_cachedir_prompt, mock_check_and_set_implementation): registries = [ From a9c375beed37453c23975fdea10138713f17cb4e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2026 13:10:15 +0000 Subject: [PATCH 084/135] Update actions/checkout action to v7 (#4338) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/changelog.yml | 2 +- .github/workflows/create-lint-wf.yml | 2 +- .github/workflows/create-test-lint-wf-template.yml | 4 ++-- .github/workflows/create-test-wf.yml | 2 +- .github/workflows/deploy-pypi.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/lint-code.yml | 2 +- .github/workflows/nextflow-source-test.yml | 4 ++-- .github/workflows/push_dockerhub.yml | 2 +- .github/workflows/pytest.yml | 4 ++-- .github/workflows/sync.yml | 4 ++-- .github/workflows/test_offline_configs.yml | 4 ++-- .github/workflows/update-template-snapshots.yml | 6 +++--- .github/workflows/update-textual-snapshots.yml | 2 +- .../.github/workflows/download_pipeline.yml | 2 +- nf_core/pipeline-template/.github/workflows/fix_linting.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 4 ++-- nf_core/pipeline-template/.github/workflows/nf-test.yml | 4 ++-- .../.github/workflows/template-version-comment.yml | 2 +- 19 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 4847d9063d..ac12956890 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -18,7 +18,7 @@ jobs: reaction: "eyes" stable_branch: "dev" - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index a344acff45..6eab40a3d8 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -42,7 +42,7 @@ jobs: export NXF_WORK=$(pwd) # Get the repo code - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out source-code repository # Set up nf-core/tools diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index 698ee79f53..1ffce179b1 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -32,7 +32,7 @@ jobs: all_features: ${{ steps.create_matrix.outputs.matrix }} steps: - name: checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Create Matrix id: create_matrix run: | @@ -56,7 +56,7 @@ jobs: steps: - name: Check out source-code repository - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Set up Python 3.14 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index e394ddd041..419417149a 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -41,7 +41,7 @@ jobs: cd create-test-wf export NXF_WORK=$(pwd) - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out source-code repository - name: Set up Python 3.14 diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index f843e0b321..6888ed7436 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out source-code repository - name: Set up Python 3.14 diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index f04cfdf678..bf2c286f29 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -19,7 +19,7 @@ jobs: stable_branch: "dev" # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/.github/workflows/lint-code.yml b/.github/workflows/lint-code.yml index d7efa84e9b..8b9714d762 100644 --- a/.github/workflows/lint-code.yml +++ b/.github/workflows/lint-code.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Run prek uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index d53cb46728..78544f16d2 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Check out Nextflow - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: repository: nextflow-io/nextflow path: nextflow @@ -38,7 +38,7 @@ jobs: chmod +x $HOME/.local/bin/nextflow nextflow -version - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out nf-core/tools with: ref: dev diff --git a/.github/workflows/push_dockerhub.yml b/.github/workflows/push_dockerhub.yml index d63d071306..587596700b 100644 --- a/.github/workflows/push_dockerhub.yml +++ b/.github/workflows/push_dockerhub.yml @@ -34,7 +34,7 @@ jobs: swap-storage: true - name: Check out code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Set up QEMU for multi-architecture build uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4 diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index c31e0dfb43..4847ceeeb4 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -40,7 +40,7 @@ jobs: name: Get test file matrix runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out source-code repository - name: List tests @@ -72,7 +72,7 @@ jobs: cd pytest export NXF_WORK=$(pwd) - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out source-code repository - name: Set up Python ${{ matrix.python-version }} diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 42a4bbc98b..96b3569a66 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -62,12 +62,12 @@ jobs: matrix: ${{fromJson(needs.get-pipelines.outputs.matrix)}} fail-fast: false steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out nf-core/tools with: ref: ${{ github.ref_name }} - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out nf-core/${{ matrix.pipeline }} with: repository: nf-core/${{ matrix.pipeline }} diff --git a/.github/workflows/test_offline_configs.yml b/.github/workflows/test_offline_configs.yml index 12634162e6..f0ce39e681 100644 --- a/.github/workflows/test_offline_configs.yml +++ b/.github/workflows/test_offline_configs.yml @@ -53,11 +53,11 @@ jobs: matrix: ${{fromJson(needs.get-pipelines.outputs.matrix)}} fail-fast: false steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out nf-core/tools with: ref: ${{ github.ref_name }} - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 name: Check out nf-core/${{ matrix.pipeline }} with: repository: nf-core/${{ matrix.pipeline }} diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index 11f9f5e915..fc93b0a451 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -22,7 +22,7 @@ jobs: stable_branch: "dev" - name: checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Create Matrix id: create_matrix @@ -43,7 +43,7 @@ jobs: fail-fast: false steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} @@ -145,7 +145,7 @@ jobs: runs-on: ubuntu-latest if: always() && needs.update-snapshots.result != 'skipped' steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index e441f4f37c..3ea27249ac 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -17,7 +17,7 @@ jobs: stable_branch: "dev" # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index 9d78212009..73ffac2441 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -39,7 +39,7 @@ jobs: needs: configure steps: - name: Check out pipeline code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 diff --git a/nf_core/pipeline-template/.github/workflows/fix_linting.yml b/nf_core/pipeline-template/.github/workflows/fix_linting.yml index 1cdbc24762..738038e8f8 100644 --- a/nf_core/pipeline-template/.github/workflows/fix_linting.yml +++ b/nf_core/pipeline-template/.github/workflows/fix_linting.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 4186ad6982..672fb10436 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -11,7 +11,7 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 diff --git a/nf_core/pipeline-template/.github/workflows/nf-test.yml b/nf_core/pipeline-template/.github/workflows/nf-test.yml index 672c1ad17f..5990330917 100644 --- a/nf_core/pipeline-template/.github/workflows/nf-test.yml +++ b/nf_core/pipeline-template/.github/workflows/nf-test.yml @@ -41,7 +41,7 @@ jobs: rm -rf ./* || true rm -rf ./.??* || true ls -la ./ - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: fetch-depth: 0 @@ -87,7 +87,7 @@ jobs: TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }} steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: fetch-depth: 0 diff --git a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml index 36ab701eb5..d87f339566 100644 --- a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml +++ b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: ref: ${{ github.event.pull_request.head.sha }} From 5bb64e1865b1c63b4a45e07f527c956e1acbcabe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:16:36 +0200 Subject: [PATCH 085/135] Update python:3.14-slim Docker digest to b877e50 (#4366) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d3ac94f7dc..2a296e255f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.14-slim@sha256:5b3879b6f3cb77e712644d50262d05a7c146b7312d784a18eff7ff5462e77033 +FROM python:3.14-slim@sha256:b877e50bd90de10af8d82c57a022fc2e0dc731c5320d762a27986facfc3355c1 LABEL authors="phil.ewels@seqera.io,erik.danielsson@scilifelab.se" \ description="Docker image containing requirements for nf-core/tools" From bca0cebaaeb14663f69cf00115b9fd3b9d905cc0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Jul 2026 12:16:58 +0200 Subject: [PATCH 086/135] Update mcr.microsoft.com/devcontainers/miniconda Docker digest to 68c1f6d (#4365) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/build-devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/build-devcontainer/Dockerfile b/.devcontainer/build-devcontainer/Dockerfile index 8e843ab1bf..7104411efd 100644 --- a/.devcontainer/build-devcontainer/Dockerfile +++ b/.devcontainer/build-devcontainer/Dockerfile @@ -1,6 +1,6 @@ # devcontainers/miniconda image based on debian (bookworm) # see tags and images: https://mcr.microsoft.com/en-us/artifact/mar/devcontainers/miniconda/tags -FROM mcr.microsoft.com/devcontainers/miniconda@sha256:1a85cf3e3da9d999f994f74cf501b1d02c9aa73ebfa3552f806dbe4570d7d5b5 AS build +FROM mcr.microsoft.com/devcontainers/miniconda@sha256:68c1f6d7904f2d94ce54a43052155348bdcf1800d9f84e8b7fd367c85e688bf1 AS build # copy this repo at current revision COPY . /root/nfcore-tools/ From ea876792c536b0459b590a1fc0fbfdc52e81c151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 1 Jul 2026 16:22:15 +0200 Subject: [PATCH 087/135] make lint tests names headings in api docs, so we can link to them (#4361) --- docs/api/check_lint_docstrings.py | 44 +++++++- nf_core/components/lint/__init__.py | 2 +- nf_core/modules/lint/environment_yml.py | 48 ++++++--- nf_core/modules/lint/main_nf.py | 102 ++++++++++++------ nf_core/modules/lint/meta_yml.py | 89 ++++++++++----- nf_core/modules/lint/module_changes.py | 7 +- nf_core/modules/lint/module_deprecations.py | 7 +- nf_core/modules/lint/module_tests.py | 56 +++++++--- nf_core/modules/lint/module_todos.py | 7 +- nf_core/modules/lint/module_version.py | 12 ++- nf_core/subworkflows/lint/main_nf.py | 19 +++- nf_core/subworkflows/lint/meta_yml.py | 47 +++++--- .../subworkflows/lint/subworkflow_changes.py | 14 ++- .../lint/subworkflow_if_empty_null.py | 7 +- .../subworkflows/lint/subworkflow_tests.py | 53 ++++++--- .../subworkflows/lint/subworkflow_todos.py | 7 +- .../subworkflows/lint/subworkflow_version.py | 12 ++- 17 files changed, 385 insertions(+), 148 deletions(-) diff --git a/docs/api/check_lint_docstrings.py b/docs/api/check_lint_docstrings.py index b9f27548f4..f7edda9f73 100644 --- a/docs/api/check_lint_docstrings.py +++ b/docs/api/check_lint_docstrings.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ Pre-commit hook: verify that every lint test name used in a result tuple is -mentioned in the docstring of its enclosing function. +documented as a section heading in the docstring of its enclosing function. Applies to nf-core component lint files where results are accumulated as: @@ -9,6 +9,14 @@ component.warned.append(("category", "test_name", "message", path)) component.failed.append(("category", "test_name", "message", path)) +The heading requirement (rather than a plain substring match) exists because +the linter links each result to ``.../#``. That +anchor only resolves on the docs site if ``test_name`` is rendered as a +heading, i.e. the docstring must contain an RST section of the form:: + + test_name + ^^^^^^^^^ + Usage (called by pre-commit with the changed files as arguments): python scripts/check_lint_docstrings.py nf_core/modules/lint/module_tests.py ... @@ -18,6 +26,33 @@ import sys from pathlib import Path +# Punctuation characters reStructuredText accepts as section-title adornments. +_RST_ADORNMENTS = set("=-`:.'\"~^_*+#<>!$%&(),/;?@[\\]{|}") + + +def collect_doc_headings(docstring: str) -> set[str]: + """Return the set of RST section-heading titles found in a docstring. + + A heading is a non-empty title line immediately followed by an underline + line built from a single, repeated adornment character that is at least as + long as the title (matching reStructuredText section syntax). ``docstring`` + is assumed to be dedented (as returned by ``ast.get_docstring``). + """ + headings: set[str] = set() + lines = docstring.splitlines() + for title_line, underline_line in zip(lines, lines[1:], strict=False): + title = title_line.strip() + underline = underline_line.strip() + if ( + title + and underline + and len(underline) >= len(title) + and len(set(underline)) == 1 + and underline[0] in _RST_ADORNMENTS + ): + headings.add(title) + return headings + def collect_test_names(func_node: ast.FunctionDef | ast.AsyncFunctionDef) -> dict[str, list[int]]: """Return {test_name: [line_numbers]} for all result-tuple appends in the function.""" @@ -66,11 +101,14 @@ def check_file(path: Path) -> list[str]: if node.name != module_stem: continue docstring = ast.get_docstring(node) or "" + headings = collect_doc_headings(docstring) test_names = collect_test_names(node) for test_name, lines in sorted(test_names.items()): - if test_name not in docstring: + if test_name not in headings: errors.append( - f"{path}:{lines[0]}: '{test_name}' used in {node.name}() but not documented in its docstring" + f"{path}:{lines[0]}: '{test_name}' is emitted by {node.name}() but is not " + f"documented as a section heading in its docstring (required for the docs " + f"anchor #{test_name})" ) break # only one function per file can match the stem return errors diff --git a/nf_core/components/lint/__init__.py b/nf_core/components/lint/__init__.py index 7b28ddef0b..9b603fe461 100644 --- a/nf_core/components/lint/__init__.py +++ b/nf_core/components/lint/__init__.py @@ -292,7 +292,7 @@ def format_result(test_results: list[LintResult], table: Table) -> Table: tools_version = __version__ if "dev" in __version__: tools_version = "dev" - test_link_message = f"[{lint_result.lint_test}](https://nf-co.re/docs/nf-core-tools/api_reference/{tools_version}/{self.component_type[:-1]}_lint_tests/{lint_result.parent_lint_test}): {lint_result.message}" + test_link_message = f"[{lint_result.lint_test}](https://nf-co.re/docs/nf-core-tools/api_reference/{tools_version}/{self.component_type[:-1]}_lint_tests/{lint_result.parent_lint_test}#{lint_result.lint_test}): {lint_result.message}" table.add_row( module_name, diff --git a/nf_core/modules/lint/environment_yml.py b/nf_core/modules/lint/environment_yml.py index 45b3160433..cd5ede8943 100644 --- a/nf_core/modules/lint/environment_yml.py +++ b/nf_core/modules/lint/environment_yml.py @@ -44,26 +44,44 @@ def lint_environment_yml( The following checks are performed: - * ``environment_yml_exists``: The ``environment.yml`` file must exist, unless the - module has a Dockerfile. If neither ``environment.yml`` nor a Dockerfile is - present, the test fails. + environment_yml_exists + ^^^^^^^^^^^^^^^^^^^^^^^ - * ``environment_yml_dockerfile_conflict``: A module must not have both an - ``environment.yml`` and a Dockerfile; Remove the Dockerfile if present. + The ``environment.yml`` file must exist, unless the + module has a Dockerfile. If neither ``environment.yml`` nor a Dockerfile is + present, the test fails. - * ``environment_yml_valid``: The ``environment.yml`` must be valid according to - the JSON schema defined at https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json. + environment_yml_dockerfile_conflict + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - * ``environment_yml_sorted``: The dependencies listed in ``environment.yml`` - must be sorted alphabetically. If they are not, they will be sorted - automatically. + A module must not have both an + ``environment.yml`` and a Dockerfile; Remove the Dockerfile if present. - * ``bioconda_version``: The version specified for each bioconda package must - be a valid, known version available in the bioconda channel. + environment_yml_valid + ^^^^^^^^^^^^^^^^^^^^^^ - * ``bioconda_latest``: Each bioconda package should be pinned to the latest - available version. A warning is raised (or the version updated if - ``fix_version`` is set) when a newer version exists. + The ``environment.yml`` must be valid according to + the JSON schema defined at https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json. + + environment_yml_sorted + ^^^^^^^^^^^^^^^^^^^^^^^ + + The dependencies listed in ``environment.yml`` + must be sorted alphabetically. If they are not, they will be sorted + automatically. + + bioconda_version + ^^^^^^^^^^^^^^^^ + + The version specified for each bioconda package must + be a valid, known version available in the bioconda channel. + + bioconda_latest + ^^^^^^^^^^^^^^^ + + Each bioconda package should be pinned to the latest + available version. A warning is raised (or the version updated if + ``fix_version`` is set) when a newer version exists. """ env_yml = None has_schema_header = False diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index e4b791f70a..04b669a275 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -25,50 +25,86 @@ def main_nf( The following checks are performed: - * ``main_nf_module_granularity``: The module must represent a single command - as ```` or single subcommand with distinct functionality as - ````. + main_nf_module_granularity + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - * ``main_nf_exists``: The ``main.nf`` file must exist. + The module must represent a single command + as ```` or single subcommand with distinct functionality as + ````. - * ``deprecated_dsl2``: The file must not contain deprecated DSL2 identifiers - (``initOptions``, ``saveFiles``, ``getSoftwareName``, ``getProcessName``, - ``publishDir``). + main_nf_exists + ^^^^^^^^^^^^^^ - * ``main_nf_script_outputs``: The process must have an ``output:`` block. + The ``main.nf`` file must exist. - * ``main_nf_container``: When both a ``singularity`` and a ``docker`` container - are specified, their tags must reference the same software version. A warning - is issued if they do not match. Modules using the newer docker-only format - (no singularity container) skip this check. + deprecated_dsl2 + ^^^^^^^^^^^^^^^ - * ``singularity_tag``: A Singularity container must be resolvable via - ``nextflow inspect -profile singularity``. The check fails if none can be - resolved or if it falls back to a docker container that has an automatic - singularity equivalent, i.e., ``quay.io/biocontainers/`` or - ``community.wave.seqera.io/``. - It is skipped for modules listed under ``singularity`` in ``.github/skip_nf_test.json``. + The file must not contain deprecated DSL2 identifiers + (``initOptions``, ``saveFiles``, ``getSoftwareName``, ``getProcessName``, + ``publishDir``). - * ``oras_singularity_tag``: The resolved Singularity container must not be - served over the ``oras://`` scheme; it should be a plain ``https://`` URL. - The check fails if an ``oras://`` container is used. + main_nf_script_outputs + ^^^^^^^^^^^^^^^^^^^^^^^ - * ``main_nf_script_shell``: Exactly one of ``script:``, ``shell:``, or ``exec:`` - blocks must be present. + The process must have an ``output:`` block. - * ``main_nf_shell_template``: If a ``shell:`` block is used, it must call - a ``template``. + main_nf_container + ^^^^^^^^^^^^^^^^^ - * ``main_nf_meta_output``: If ``meta`` is present in the module inputs, it - must also appear in at least one output channel. + When both a ``singularity`` and a ``docker`` container + are specified, their tags must reference the same software version. A warning + is issued if they do not match. Modules using the newer docker-only format + (no singularity container) skip this check. - * ``main_nf_version_topic``: The module should emit software versions using - a ``topic: versions`` output. A warning is issued if no such topic is found. + singularity_tag + ^^^^^^^^^^^^^^^ - * ``main_nf_version_emit``: The number of ``topic: versions`` outputs must - equal the number of ``emit:`` outputs whose name starts with ``versions``. - A warning is issued if a legacy YAML-based ``versions`` emit is used instead - of a topic output. + A Singularity container must be resolvable via + ``nextflow inspect -profile singularity``. The check fails if none can be + resolved or if it falls back to a docker container that has an automatic + singularity equivalent, i.e., ``quay.io/biocontainers/`` or + ``community.wave.seqera.io/``. + It is skipped for modules listed under ``singularity`` in ``.github/skip_nf_test.json``. + + oras_singularity_tag + ^^^^^^^^^^^^^^^^^^^^^ + + The resolved Singularity container must not be + served over the ``oras://`` scheme; it should be a plain ``https://`` URL. + The check fails if an ``oras://`` container is used. + + main_nf_script_shell + ^^^^^^^^^^^^^^^^^^^^^ + + Exactly one of ``script:``, ``shell:``, or ``exec:`` + blocks must be present. + + main_nf_shell_template + ^^^^^^^^^^^^^^^^^^^^^^^ + + If a ``shell:`` block is used, it must call + a ``template``. + + main_nf_meta_output + ^^^^^^^^^^^^^^^^^^^ + + If ``meta`` is present in the module inputs, it + must also appear in at least one output channel. + + main_nf_version_topic + ^^^^^^^^^^^^^^^^^^^^^^ + + The module should emit software versions using + a ``topic: versions`` output. A warning is issued if no such topic is found. + + main_nf_version_emit + ^^^^^^^^^^^^^^^^^^^^^ + + The number of ``topic: versions`` outputs must + equal the number of ``emit:`` outputs whose name starts with ``versions``. + A warning is issued if a legacy YAML-based ``versions`` emit is used instead + of a topic output. """ diff --git a/nf_core/modules/lint/meta_yml.py b/nf_core/modules/lint/meta_yml.py index d771536a75..6c5a0c36f4 100644 --- a/nf_core/modules/lint/meta_yml.py +++ b/nf_core/modules/lint/meta_yml.py @@ -75,44 +75,77 @@ def meta_yml(module_lint_object: ModuleLint, module: NFCoreComponent, allow_miss The following checks are performed: - * ``meta_yml_exists``: The ``meta.yml`` file must exist. + meta_yml_exists + ^^^^^^^^^^^^^^^ - * ``meta_yml_valid``: The ``meta.yml`` must be valid according to the JSON - schema defined in ``modules/meta-schema.json`` in the nf-core/modules - repository. + The ``meta.yml`` file must exist. - * ``meta_name``: The ``name`` field in ``meta.yml`` must match (case-insensitive) - the process name declared in ``main.nf``. + meta_yml_valid + ^^^^^^^^^^^^^^ - * ``meta_input``: If ``main.nf`` declares inputs, they must be listed under - the ``input:`` key in ``meta.yml``. + The ``meta.yml`` must be valid according to the JSON + schema defined in ``modules/meta-schema.json`` in the nf-core/modules + repository. - * ``correct_meta_inputs``: The inputs listed in ``meta.yml`` must exactly - match those parsed from ``main.nf``. Run ``nf-core modules lint --fix`` - to auto-correct. + meta_name + ^^^^^^^^^ - * ``meta_output``: If ``main.nf`` declares outputs, they must be listed under - the ``output:`` key in ``meta.yml``. + The ``name`` field in ``meta.yml`` must match (case-insensitive) + the process name declared in ``main.nf``. - * ``correct_meta_outputs``: The outputs listed in ``meta.yml`` must exactly - match those parsed from ``main.nf``. Run ``nf-core modules lint --fix`` - to auto-correct. + meta_input + ^^^^^^^^^^ - * ``has_meta_topics``: If ``main.nf`` declares topics, ``meta.yml`` must - also contain a non-empty ``topics:`` block. Run - ``nf-core modules lint --fix`` to auto-correct. + If ``main.nf`` declares inputs, they must be listed under + the ``input:`` key in ``meta.yml``. - * ``correct_meta_topics``: The topics listed in ``meta.yml`` must exactly - match those parsed from ``main.nf``. Run ``nf-core modules lint --fix`` - to auto-correct. + correct_meta_inputs + ^^^^^^^^^^^^^^^^^^^ - * ``has_meta_containers``: If ``main.nf`` declares containers, ``meta.yml`` - must also contain a non-empty ``containers:`` block. Run - ``nf-core modules lint --fix`` to auto-correct. + The inputs listed in ``meta.yml`` must exactly + match those parsed from ``main.nf``. Run ``nf-core modules lint --fix`` + to auto-correct. - * ``correct_meta_containers``: The containers listed in ``meta.yml`` must - exactly match those parsed from ``main.nf``. Run - ``nf-core modules lint --fix`` to auto-correct. + meta_output + ^^^^^^^^^^^ + + If ``main.nf`` declares outputs, they must be listed under + the ``output:`` key in ``meta.yml``. + + correct_meta_outputs + ^^^^^^^^^^^^^^^^^^^^ + + The outputs listed in ``meta.yml`` must exactly + match those parsed from ``main.nf``. Run ``nf-core modules lint --fix`` + to auto-correct. + + has_meta_topics + ^^^^^^^^^^^^^^^ + + If ``main.nf`` declares topics, ``meta.yml`` must + also contain a non-empty ``topics:`` block. Run + ``nf-core modules lint --fix`` to auto-correct. + + correct_meta_topics + ^^^^^^^^^^^^^^^^^^^ + + The topics listed in ``meta.yml`` must exactly + match those parsed from ``main.nf``. Run ``nf-core modules lint --fix`` + to auto-correct. + + has_meta_containers + ^^^^^^^^^^^^^^^^^^^ + + If ``main.nf`` declares containers, ``meta.yml`` + must also contain a non-empty ``containers:`` block. Run + ``nf-core modules lint --fix`` to auto-correct. + + correct_meta_containers + ^^^^^^^^^^^^^^^^^^^^^^^ + + The containers listed in ``meta.yml`` must + exactly match those parsed from ``main.nf``. Run + ``nf-core modules lint --fix`` to auto-correct. If the module has inputs or outputs, they are expected to be formatted as: diff --git a/nf_core/modules/lint/module_changes.py b/nf_core/modules/lint/module_changes.py index de6f3d24c8..07ccdd56f6 100644 --- a/nf_core/modules/lint/module_changes.py +++ b/nf_core/modules/lint/module_changes.py @@ -25,8 +25,11 @@ def module_changes(module_lint_object, module): The following checks are performed: - * ``check_local_copy``: Each module file must be identical to the corresponding - file in the remote repository at the pinned commit SHA. + check_local_copy + ^^^^^^^^^^^^^^^^ + + Each module file must be identical to the corresponding + file in the remote repository at the pinned commit SHA. """ if module.is_patched: # If the module is patched, we need to apply diff --git a/nf_core/modules/lint/module_deprecations.py b/nf_core/modules/lint/module_deprecations.py index e9d1070706..96ee356375 100644 --- a/nf_core/modules/lint/module_deprecations.py +++ b/nf_core/modules/lint/module_deprecations.py @@ -9,8 +9,11 @@ def module_deprecations(_, module): The following checks are performed: - * ``module_deprecations``: Deprecated files (e.g. ``functions.nf``) must not - be present in the module directory. + module_deprecations + ^^^^^^^^^^^^^^^^^^^^ + + Deprecated files (e.g. ``functions.nf``) must not + be present in the module directory. """ module.wf_path = module.component_dir if (module.component_dir / "functions.nf").exists(): diff --git a/nf_core/modules/lint/module_tests.py b/nf_core/modules/lint/module_tests.py index 00031d8b62..aa0388dc3a 100644 --- a/nf_core/modules/lint/module_tests.py +++ b/nf_core/modules/lint/module_tests.py @@ -21,26 +21,54 @@ def module_tests(_, module: NFCoreComponent, allow_missing: bool = False): The following checks are performed: - * ``test_dir_exists``: The nf-test directory ``tests/`` must exist. + test_dir_exists + ^^^^^^^^^^^^^^^ - * ``test_main_nf_exists``: The file ``tests/main.nf.test`` must exist. + The nf-test directory ``tests/`` must exist. - * ``test_snapshot_exists``: If ``snapshot()`` is called in ``main.nf.test``, - the snapshot file ``tests/main.nf.test.snap`` must exist and be valid JSON. + test_main_nf_exists + ^^^^^^^^^^^^^^^^^^^ - * ``test_snap_md5sum``: The snapshot must not contain md5sums for empty files - (``d41d8cd98f00b204e9800998ecf8427e``) or empty compressed files - (``7029066c27ac6f5ef18d660d5741979a``), unless the test name contains ``stub``. + The file ``tests/main.nf.test`` must exist. - * ``test_snap_versions``: The snapshot must contain a ``versions`` key. + test_snapshot_exists + ^^^^^^^^^^^^^^^^^^^^ - * ``test_main_tags``: The ``main.nf.test`` file must declare the required tags: - ``modules``, ``modules_``, the full component name, and (for ``tool/subtool`` - modules) the tool name alone. Tags for any chained components included via - ``include`` statements must also be present. + If ``snapshot()`` is called in ``main.nf.test``, + the snapshot file ``tests/main.nf.test.snap`` must exist and be valid JSON. - * ``test_old_test_dir``: The legacy pytest directory - ``tests/modules//`` must not exist. + test_snap_md5sum + ^^^^^^^^^^^^^^^^ + + The snapshot must not contain md5sums for empty files + (``d41d8cd98f00b204e9800998ecf8427e``) or empty compressed files + (``7029066c27ac6f5ef18d660d5741979a``), unless the test name contains ``stub``. + + test_snap_versions + ^^^^^^^^^^^^^^^^^^ + + The snapshot must contain a ``versions`` key. + + test_main_tags + ^^^^^^^^^^^^^^ + + The ``main.nf.test`` file must declare the required tags: + ``modules``, ``modules_``, the full component name, and (for ``tool/subtool`` + modules) the tool name alone. Tags for any chained components included via + ``include`` statements must also be present. + + test_old_test_dir + ^^^^^^^^^^^^^^^^^ + + The legacy pytest directory + ``tests/modules//`` must not exist. + + test_stub_gzip_syntax + ^^^^^^^^^^^^^^^^^^^^^^ + + Stub blocks with gzip output files must use the proper syntax. Stub files + ending in ``.gz`` must use ``echo "" | gzip > file.gz``. Simply touching or + creating empty ``.gz`` files will break nf-test's gzip parser. """ if module.nftest_testdir is None: diff --git a/nf_core/modules/lint/module_todos.py b/nf_core/modules/lint/module_todos.py index e453e2ad6a..a7331ca2ac 100644 --- a/nf_core/modules/lint/module_todos.py +++ b/nf_core/modules/lint/module_todos.py @@ -25,8 +25,11 @@ def module_todos(_, module): This lint test runs through all files in the module and searches for these lines. If any are found they will throw a warning. - * ``module_todo``: A warning is issued for each TODO comment found in the - module files. + module_todo + ^^^^^^^^^^^ + + A warning is issued for each TODO comment found in the + module files. .. tip:: Note that many GUI code editors have plugins to list all instances of *TODO* in a given project directory. This is a very quick and convenient way to get diff --git a/nf_core/modules/lint/module_version.py b/nf_core/modules/lint/module_version.py index 5caef3f68d..a5a7828d6e 100644 --- a/nf_core/modules/lint/module_version.py +++ b/nf_core/modules/lint/module_version.py @@ -22,10 +22,16 @@ def module_version(module_lint_object: "nf_core.modules.lint.ModuleLint", module The following checks are performed: - * ``git_sha``: The module must have a ``git_sha`` entry in ``modules.json``. + git_sha + ^^^^^^^ - * ``module_version``: The module version must match the latest commit in the - remote repository. A warning is issued if a newer version is available. + The module must have a ``git_sha`` entry in ``modules.json``. + + module_version + ^^^^^^^^^^^^^^ + + The module version must match the latest commit in the + remote repository. A warning is issued if a newer version is available. """ assert module_lint_object.modules_json is not None # mypy assert module.repo_url is not None # mypy diff --git a/nf_core/subworkflows/lint/main_nf.py b/nf_core/subworkflows/lint/main_nf.py index 6d79a47396..9d16312250 100644 --- a/nf_core/subworkflows/lint/main_nf.py +++ b/nf_core/subworkflows/lint/main_nf.py @@ -27,13 +27,22 @@ def main_nf(_, subworkflow: NFCoreComponent) -> tuple[list[str], list[str]]: The following checks are performed: - * ``main_nf_exists``: The ``main.nf`` file must exist. + main_nf_exists + ^^^^^^^^^^^^^^ - * ``main_nf_script_outputs``: The workflow must have an ``emit:`` block. + The ``main.nf`` file must exist. - * ``main_nf_version_emitted``: The subworkflow should emit a software version - channel. A warning is issued if no ``versions`` output is found (can be - ignored if the subworkflow uses topic channels). + main_nf_script_outputs + ^^^^^^^^^^^^^^^^^^^^^^^ + + The workflow must have an ``emit:`` block. + + main_nf_version_emitted + ^^^^^^^^^^^^^^^^^^^^^^^^ + + The subworkflow should emit a software version + channel. A warning is issued if no ``versions`` output is found (can be + ignored if the subworkflow uses topic channels). """ inputs: list[str] = [] diff --git a/nf_core/subworkflows/lint/meta_yml.py b/nf_core/subworkflows/lint/meta_yml.py index 92c4641d4b..480c2d672a 100644 --- a/nf_core/subworkflows/lint/meta_yml.py +++ b/nf_core/subworkflows/lint/meta_yml.py @@ -28,25 +28,46 @@ def meta_yml(subworkflow_lint_object, subworkflow, allow_missing: bool = False): The following checks are performed: - * ``meta_yml_exists``: The ``meta.yml`` file must exist. + meta_yml_exists + ^^^^^^^^^^^^^^^ - * ``meta_yml_valid``: The ``meta.yml`` must be valid according to the JSON - schema defined at https://raw.githubusercontent.com/nf-core/subworkflows/master/modules/environment-schema.json. + The ``meta.yml`` file must exist. - * ``meta_input``: All input channels declared in ``main.nf`` must be listed - under the ``input:`` key in ``meta.yml``. + meta_yml_valid + ^^^^^^^^^^^^^^ - * ``meta_output``: All output channels declared in ``main.nf`` must be listed - under the ``output:`` key in ``meta.yml``. + The ``meta.yml`` must be valid according to the JSON + schema defined at https://raw.githubusercontent.com/nf-core/subworkflows/master/modules/environment-schema.json. - * ``meta_name``: The ``name`` field in ``meta.yml`` must match the workflow - name declared in ``main.nf``. + meta_input + ^^^^^^^^^^ - * ``meta_include``: All modules and subworkflows included in ``main.nf`` must - be listed under the ``components:`` key in ``meta.yml``. + All input channels declared in ``main.nf`` must be listed + under the ``input:`` key in ``meta.yml``. - * ``meta_modules_deprecated``: The deprecated ``modules:`` section must not - be present in ``meta.yml``; use ``components:`` instead. + meta_output + ^^^^^^^^^^^ + + All output channels declared in ``main.nf`` must be listed + under the ``output:`` key in ``meta.yml``. + + meta_name + ^^^^^^^^^ + + The ``name`` field in ``meta.yml`` must match the workflow + name declared in ``main.nf``. + + meta_include + ^^^^^^^^^^^^ + + All modules and subworkflows included in ``main.nf`` must + be listed under the ``components:`` key in ``meta.yml``. + + meta_modules_deprecated + ^^^^^^^^^^^^^^^^^^^^^^^^ + + The deprecated ``modules:`` section must not + be present in ``meta.yml``; use ``components:`` instead. """ # Read the meta.yml file if subworkflow.meta_yml is None: diff --git a/nf_core/subworkflows/lint/subworkflow_changes.py b/nf_core/subworkflows/lint/subworkflow_changes.py index 9152931594..22e992043e 100644 --- a/nf_core/subworkflows/lint/subworkflow_changes.py +++ b/nf_core/subworkflows/lint/subworkflow_changes.py @@ -25,11 +25,17 @@ def subworkflow_changes(subworkflow_lint_object, subworkflow): The following checks are performed: - * ``subworkflow_patch``: If the subworkflow is patched, the patch must apply - cleanly in reverse against the remote version. + subworkflow_patch + ^^^^^^^^^^^^^^^^^ - * ``check_local_copy``: Each subworkflow file must be identical to the - corresponding file in the remote repository at the pinned commit SHA. + If the subworkflow is patched, the patch must apply + cleanly in reverse against the remote version. + + check_local_copy + ^^^^^^^^^^^^^^^^ + + Each subworkflow file must be identical to the + corresponding file in the remote repository at the pinned commit SHA. """ if subworkflow.is_patched: # If the subworkflow is patched, we need to apply diff --git a/nf_core/subworkflows/lint/subworkflow_if_empty_null.py b/nf_core/subworkflows/lint/subworkflow_if_empty_null.py index 5709874329..fe64ea7201 100644 --- a/nf_core/subworkflows/lint/subworkflow_if_empty_null.py +++ b/nf_core/subworkflows/lint/subworkflow_if_empty_null.py @@ -17,8 +17,11 @@ def subworkflow_if_empty_null(_, subworkflow): The following checks are performed: - * ``subworkflow_if_empty_null``: Warns if any ``ifEmpty(null)`` usage is found - in the subworkflow files. + subworkflow_if_empty_null + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Warns if any ``ifEmpty(null)`` usage is found + in the subworkflow files. """ # Main subworkflow directory diff --git a/nf_core/subworkflows/lint/subworkflow_tests.py b/nf_core/subworkflows/lint/subworkflow_tests.py index 189f3c10f0..81219cca71 100644 --- a/nf_core/subworkflows/lint/subworkflow_tests.py +++ b/nf_core/subworkflows/lint/subworkflow_tests.py @@ -21,28 +21,49 @@ def subworkflow_tests(_, subworkflow: NFCoreComponent, allow_missing: bool = Fal The following checks are performed: - * ``test_dir_exists``: The nf-test directory ``tests/`` must exist. + test_dir_exists + ^^^^^^^^^^^^^^^ - * ``test_main_nf_exists``: The file ``tests/main.nf.test`` must exist. + The nf-test directory ``tests/`` must exist. - * ``test_snapshot_exists``: If ``snapshot()`` is called in ``main.nf.test``, - the snapshot file ``tests/main.nf.test.snap`` must exist and be valid JSON. + test_main_nf_exists + ^^^^^^^^^^^^^^^^^^^ - * ``test_snap_md5sum``: The snapshot must not contain md5sums for empty files - (``d41d8cd98f00b204e9800998ecf8427e``) or empty compressed files - (``7029066c27ac6f5ef18d660d5741979a``), unless the test name contains ``stub``. + The file ``tests/main.nf.test`` must exist. - * ``test_snap_versions``: The snapshot should contain a ``versions`` key. - A warning (not a failure) is issued if it is absent, since subworkflows that - use topic channels may not emit versions directly. + test_snapshot_exists + ^^^^^^^^^^^^^^^^^^^^ - * ``test_main_tags``: The ``main.nf.test`` file must declare the required tags: - ``subworkflows``, ``subworkflows/``, ``subworkflows_``, - all components included in the subworkflow's ``main.nf``, and any chained - components referenced via ``include`` statements in the test file. + If ``snapshot()`` is called in ``main.nf.test``, + the snapshot file ``tests/main.nf.test.snap`` must exist and be valid JSON. - * ``test_old_test_dir``: The legacy pytest directory - ``tests/subworkflows//`` must not exist. + test_snap_md5sum + ^^^^^^^^^^^^^^^^ + + The snapshot must not contain md5sums for empty files + (``d41d8cd98f00b204e9800998ecf8427e``) or empty compressed files + (``7029066c27ac6f5ef18d660d5741979a``), unless the test name contains ``stub``. + + test_snap_versions + ^^^^^^^^^^^^^^^^^^ + + The snapshot should contain a ``versions`` key. + A warning (not a failure) is issued if it is absent, since subworkflows that + use topic channels may not emit versions directly. + + test_main_tags + ^^^^^^^^^^^^^^ + + The ``main.nf.test`` file must declare the required tags: + ``subworkflows``, ``subworkflows/``, ``subworkflows_``, + all components included in the subworkflow's ``main.nf``, and any chained + components referenced via ``include`` statements in the test file. + + test_old_test_dir + ^^^^^^^^^^^^^^^^^ + + The legacy pytest directory + ``tests/subworkflows//`` must not exist. """ if subworkflow.nftest_testdir is None: diff --git a/nf_core/subworkflows/lint/subworkflow_todos.py b/nf_core/subworkflows/lint/subworkflow_todos.py index 9483771a59..0c403469d5 100644 --- a/nf_core/subworkflows/lint/subworkflow_todos.py +++ b/nf_core/subworkflows/lint/subworkflow_todos.py @@ -32,8 +32,11 @@ def subworkflow_todos(_, subworkflow): The following checks are performed: - * ``subworkflow_todo``: Warns if any ``TODO nf-core:`` comment lines are found - in the subworkflow files. + subworkflow_todo + ^^^^^^^^^^^^^^^^ + + Warns if any ``TODO nf-core:`` comment lines are found + in the subworkflow files. """ # Main subworkflow directory diff --git a/nf_core/subworkflows/lint/subworkflow_version.py b/nf_core/subworkflows/lint/subworkflow_version.py index b5b3b1d0e0..d364cd1637 100644 --- a/nf_core/subworkflows/lint/subworkflow_version.py +++ b/nf_core/subworkflows/lint/subworkflow_version.py @@ -20,10 +20,16 @@ def subworkflow_version(subworkflow_lint_object, subworkflow): The following checks are performed: - * ``git_sha``: The subworkflow must have a ``git_sha`` entry in ``modules.json``. + git_sha + ^^^^^^^ - * ``subworkflow_version``: The subworkflow version must match the latest commit - in the remote repository. A warning is issued if a newer version is available. + The subworkflow must have a ``git_sha`` entry in ``modules.json``. + + subworkflow_version + ^^^^^^^^^^^^^^^^^^^ + + The subworkflow version must match the latest commit + in the remote repository. A warning is issued if a newer version is available. """ modules_json_path = Path(subworkflow_lint_object.directory, "modules.json") From b85a7e3eec1046d35b5d2bb522a5540f346a2a81 Mon Sep 17 00:00:00 2001 From: sanmaxdev Date: Thu, 2 Jul 2026 05:06:54 +0000 Subject: [PATCH 088/135] fix: allow dots in usernames for non-GitHub git providers The username validation regex was GitHub-specific and rejected usernames containing dots, which are valid on GitLab and other git providers. Updated the regex to accept dots and made the warning message provider-agnostic. Fixes #3655 --- nf_core/components/create.py | 10 +++++----- tests/modules/test_create.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/nf_core/components/create.py b/nf_core/components/create.py index 270cf1355a..d9930481fc 100644 --- a/nf_core/components/create.py +++ b/nf_core/components/create.py @@ -425,11 +425,11 @@ def _get_username(self): except (subprocess.CalledProcessError, FileNotFoundError) as e: log.debug(f"Could not find GitHub username using 'gh' cli command: [red]{e}") - # Regex to valid GitHub username: https://github.com/shinnn/github-username-regex - github_username_regex = re.compile(r"^@[a-zA-Z\d](?:[a-zA-Z\d]|-(?=[a-zA-Z\d])){0,38}$") - while self.author is None or not github_username_regex.match(self.author): - if self.author is not None and not github_username_regex.match(self.author): - log.warning("Does not look like a valid GitHub username (must start with an '@')!") + # Regex to validate username (GitHub, GitLab, and other git providers) + username_regex = re.compile(r"^@[a-zA-Z\d](?:[a-zA-Z\d\.]|-(?=[a-zA-Z\d\.])){0,38}$") + while self.author is None or not username_regex.match(self.author): + if self.author is not None and not username_regex.match(self.author): + log.warning("Does not look like a valid username (must start with an '@')!") self.require_prompts("GitHub username not provided.\nPlease provide the `--author` option") self.author = rich.prompt.Prompt.ask( f"[violet]GitHub Username:[/]{' (@author)' if author_default is None else ''}", diff --git a/tests/modules/test_create.py b/tests/modules/test_create.py index 88789b51f2..c45da93c4a 100644 --- a/tests/modules/test_create.py +++ b/tests/modules/test_create.py @@ -6,6 +6,7 @@ import responses import yaml +import nf_core.components.create import nf_core.modules.create from tests.utils import ( mock_anaconda_api_calls, @@ -16,6 +17,23 @@ from ..test_modules import TestModules +def test_modules_create_accepts_dotted_git_provider_username(): + """Accept dotted usernames used by non-GitHub git providers.""" + component_create = nf_core.components.create.ComponentCreate.__new__(nf_core.components.create.ComponentCreate) + component_create.author = "@first.last" + component_create.require_prompts = mock.Mock() + + with ( + mock.patch("nf_core.components.create.subprocess.check_output", side_effect=FileNotFoundError), + mock.patch("nf_core.components.create.rich.prompt.Prompt.ask") as prompt_ask, + ): + component_create._get_username() + + assert component_create.author == "@first.last" + component_create.require_prompts.assert_not_called() + prompt_ask.assert_not_called() + + class TestModulesCreate(TestModules): def test_modules_create_succeed(self): """Succeed at creating the TrimGalore! module""" From 2ce7ad1fa6f2250c9282c62acd55e00827230b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Thu, 2 Jul 2026 12:01:18 +0200 Subject: [PATCH 089/135] switch from wave cli to api requests (#4353) Co-authored-by: JulianFlesch --- nf_core/modules/containers.py | 324 +++++++++++++++++-------------- tests/modules/test_containers.py | 118 ++++++----- 2 files changed, 252 insertions(+), 190 deletions(-) diff --git a/nf_core/modules/containers.py b/nf_core/modules/containers.py index bf7c1fee6d..132e443499 100644 --- a/nf_core/modules/containers.py +++ b/nf_core/modules/containers.py @@ -1,7 +1,9 @@ +import base64 import logging import os import re -import subprocess +import threading +import time from collections.abc import Callable from concurrent.futures import ThreadPoolExecutor, as_completed from pathlib import Path @@ -9,7 +11,6 @@ import requests import rich.progress -import yaml from pydantic import ValidationError from rich.pretty import pretty_repr @@ -27,11 +28,57 @@ scan_modules_dir, ) from nf_core.pipelines.lint_utils import run_prettier_on_file -from nf_core.utils import CONTAINER_PLATFORMS, CONTAINER_SYSTEMS, ContainerRegistryUrls, run_cmd +from nf_core.utils import CONTAINER_PLATFORMS, CONTAINER_SYSTEMS, ContainerRegistryUrls log = logging.getLogger(__name__) WAVE_URL = "https://wave.seqera.io" +WAVE_API_ALPHA1 = f"{WAVE_URL}/v1alpha1" +WAVE_API_ALPHA2 = f"{WAVE_URL}/v1alpha2" + +# Wave container build `format` field, keyed by nf-core container system. +WAVE_FORMAT = {"docker": "docker", "singularity": "sif"} + + +def wave_send( + method: str, url: str, json_body: dict | None = None, error_context: str = "Wave request" +) -> requests.Response: + """ + Send an authenticated Wave API request and return the raw response. + + Adds bearer auth (and a ``towerAccessToken`` body field for requests with a body) + when TOWER_ACCESS_TOKEN is set, and raises on a non-200 response. This is the + shared transport for all Wave calls; use :func:`wave_request` for JSON endpoints + and read ``.text`` directly for plain-text ones (e.g. the conda lock file). + + Args: + method: ``"get"`` or ``"post"``. + url: Full request URL. + json_body: Optional JSON body (POST requests). + error_context: Prefix used in raised error messages. + """ + if method not in ("get", "post"): + raise ValueError(f"Invalid http method '{method}' passed. Needs to be one of: 'get', 'post'.") + headers = {"Content-Type": "application/json"} + token = os.environ.get("TOWER_ACCESS_TOKEN") + if token: + headers["Authorization"] = f"Bearer {token}" + if json_body is not None: + json_body = {**json_body, "towerAccessToken": token} + + resp = getattr(requests, method)(url, json=json_body, headers=headers) + if resp.status_code != 200: + raise RuntimeError(f"{error_context} failed: HTTP {resp.status_code} {resp.text}") + return resp + + +def wave_request(method: str, url: str, json_body: dict | None = None, error_context: str = "Wave request") -> dict: + """Send a Wave API request and return the parsed JSON response.""" + resp = wave_send(method, url, json_body, error_context) + try: + return resp.json() + except ValueError as e: + raise RuntimeError(f"{error_context}: could not parse JSON response") from e class ModuleContainers: @@ -329,6 +376,10 @@ def callback(build_id: str) -> None: return callback + # Set by the main thread on Ctrl+C so in-flight build waiters abort promptly + # instead of sleeping out their poll interval / full build timeout. + cancel_event = threading.Event() + # Submit all container build tasks with ThreadPoolExecutor(max_workers=threads) as pool: for cs in CONTAINER_SYSTEMS: @@ -340,31 +391,41 @@ def callback(build_id: str) -> None: self.environment_yml, self.verbose, make_on_build_id(cs, platform) if progress_bar else None, + cancel_event, ) build_tasks[fut] = (cs, platform) # Process completed container builds - for fut in as_completed(build_tasks): - cs, platform = build_tasks[fut] - short_platform = platform.split("/")[-1] - build_tid = build_task_ids.get((cs, platform)) - - try: - getattr(containers, cs)[platform] = fut.result() - if progress_bar and build_tid is not None: - progress_bar.update(build_tid, completed=1, status="[green]done[/green]") - except (ValueError, RuntimeError, OSError, AssertionError) as e: - # make it a warning for arm (not required), but fail for other platforms - if platform == "linux/arm64": - log.warning( - f"Failed to build {cs} container for {platform}: {e}. This is only critical if the tool should support arm64." - ) - else: - log.error(f"Failed to build {cs} container for {platform}: {e}") - has_failures = True - if progress_bar and build_tid is not None: - progress_bar.update(build_tid, completed=1, status="[red]failed[/red]") - continue + try: + for fut in as_completed(build_tasks): + cs, platform = build_tasks[fut] + short_platform = platform.split("/")[-1] + build_tid = build_task_ids.get((cs, platform)) + + try: + getattr(containers, cs)[platform] = fut.result() + if progress_bar and build_tid is not None: + progress_bar.update(build_tid, completed=1, status="[green]done[/green]") + except (ValueError, RuntimeError, OSError, AssertionError) as e: + # make it a warning for arm (not required), but fail for other platforms + if platform == "linux/arm64": + log.warning( + f"Failed to build {cs} container for {platform}: {e}. This is only critical if the tool should support arm64." + ) + else: + log.error(f"Failed to build {cs} container for {platform}: {e}") + has_failures = True + if progress_bar and build_tid is not None: + progress_bar.update(build_tid, completed=1, status="[red]failed[/red]") + continue + except KeyboardInterrupt: + # Signal the running build waiters to stop, drop anything not yet started, + # and re-raise so the command aborts instead of blocking on the executor's + # wait-for-all shutdown. + log.warning("Interrupted — cancelling Wave builds...") + cancel_event.set() + pool.shutdown(wait=False, cancel_futures=True) + raise # Remove the per-build spinners now that all builds are done if progress_bar: @@ -403,7 +464,7 @@ def callback(build_id: str) -> None: if progress_bar and task_id is not None: progress_bar.update(task_id, status=f"conda lock {short_platform} done") - except (ValueError, OSError, requests.RequestException) as e: + except (ValueError, RuntimeError, OSError, requests.RequestException) as e: # Wave does not always expose a conda lock for every build (e.g. some # freshly built arm64 images). A missing lock is not fatal: keep the # other platforms' containers and locks instead of failing the module. @@ -432,29 +493,57 @@ def callback(build_id: str) -> None: return containers, not has_failures - @staticmethod - def _extract_yaml_from_wave_output(output: str) -> str: + @classmethod + def _await_build( + cls, + request_id: str, + poll_interval: int = 5, + timeout: int = 1800, + cancel_event: threading.Event | None = None, + ) -> None: """ - Extract YAML content from Wave CLI output in verbose mode. + Wait for a Wave container request to finish by polling its status endpoint. - Wave CLI with --log-level DEBUG outputs multi-line DEBUG logs before the YAML response. - This method finds the first line that looks like YAML (key: value format) and returns - everything from that point onwards. + Replaces the wave CLI ``--await`` flag. Polls ``GET /v1alpha2/container/{id}/status`` + until the request reports ``DONE``, then raises (with the failure ``reason``) if it + did not succeed. Args: - output: Raw stdout from Wave CLI - - Returns: - YAML content with DEBUG lines removed + request_id: The Wave request id returned by the container submit request. + poll_interval: Seconds to wait between status checks. + timeout: Maximum seconds to wait before giving up. + cancel_event: When set (by the main thread on Ctrl+C), abort the wait promptly + instead of sleeping out the poll interval. """ - lines = output.splitlines() - for i, line in enumerate(lines): - # Look for lines that start with a simple word followed by colon (YAML key) - # Expected keys from Wave: buildId, cached, containerImage, duration, freeze, etc. - if "DEBUG" not in line and re.match(r"^[a-zA-Z]\w*:\s", line): - return "\n".join(lines[i:]) - # If no YAML start found, return original output - return output + if not request_id: + raise RuntimeError("Wave did not return a requestId to await") + + status_url = f"{WAVE_API_ALPHA2}/container/{quote(request_id, safe='')}/status" + # Updated from each status response; the API returns a ready-made build log URL. + details_uri = "" + deadline = time.monotonic() + timeout + while True: + if cancel_event is not None and cancel_event.is_set(): + raise RuntimeError(f"Wave build {request_id} await cancelled") + status = wave_request("get", status_url, error_context=f"Wave status check for request {request_id}") + details_uri = status.get("detailsUri") or details_uri + if status.get("status") == "DONE": + if not status.get("succeeded"): + reason = status.get("reason") or "no reason provided" + raise RuntimeError(f"Wave build {request_id} failed: {reason}. Build log: {details_uri}") + log.debug(f"Wave build {request_id} completed in {status.get('duration')}s") + return + if time.monotonic() > deadline: + raise RuntimeError( + f"Wave build {request_id} did not complete within {timeout}s. Build log: {details_uri}" + ) + # Interruptible sleep: Event.wait returns True immediately once cancelled, + # otherwise blocks for poll_interval like time.sleep. + if cancel_event is not None: + if cancel_event.wait(poll_interval): + raise RuntimeError(f"Wave build {request_id} await cancelled") + else: + time.sleep(poll_interval) @classmethod def request_container( @@ -464,103 +553,57 @@ def request_container( conda_file: Path, verbose=False, on_build_id: Callable[[str], None] | None = None, + cancel_event: threading.Event | None = None, ) -> ContainerEntry: assert conda_file.exists() assert container_system in CONTAINER_SYSTEMS assert platform in CONTAINER_PLATFORMS - executable = "wave" - log_level = "DEBUG" if verbose else "INFO" - args = [ - "--conda-file", - str(conda_file.absolute()), - "--freeze", - "--platform", - platform, - "-o", - "yaml", - "--build-template", - "conda/pixi:v1", - "--log-level", - log_level, - ] - if container_system == "singularity": - args.append("--singularity") - args.append("--await") - - if on_build_id is not None: - # Stream stdout line-by-line so we can fire on_build_id as soon as - # "buildId:" appears in the debug output, without waiting for the build to finish. - try: - proc = subprocess.Popen([executable] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - except FileNotFoundError as e: - raise RuntimeError( - f"It looks like {executable} is not installed. Please ensure it is available in your PATH." - ) from e - assert proc.stdout and proc.stderr - stdout_chunks: list[bytes] = [] - build_id_notified = False - for raw_line in proc.stdout: - stdout_chunks.append(raw_line) - if not build_id_notified: - m = re.search(rb"buildId:\s*(\S+)", raw_line) - if m: - on_build_id(m.group(1).decode().strip("\"'")) - build_id_notified = True - stderr_bytes = proc.stderr.read() - proc.wait() - if proc.returncode != 0: - raise RuntimeError( - f"wave command returned non-zero error code '{proc.returncode}':\n" - f"{stderr_bytes.decode()}{b''.join(stdout_chunks).decode()}" - ) - out: tuple[bytes, bytes] | None = (b"".join(stdout_chunks), stderr_bytes) - else: - args_str = " ".join(args) - out = run_cmd(executable, args_str) - - if out is None: - raise RuntimeError("Wave command did not return any output") - - # Log stderr when verbose (Wave outputs debug logs there) - if verbose and out[1]: - stderr_output = out[1].decode().strip() - if stderr_output: - for line in stderr_output.splitlines(): - log.info(line) + # Submit the build via the Wave HTTP API (POST /v1alpha2/container). + # `freeze` with no buildRepository pushes to the public community registry. + payload: dict = { + "packages": { + "type": "CONDA", + "environment": base64.b64encode(conda_file.read_bytes()).decode(), + }, + "containerPlatform": platform, + "freeze": True, + "buildTemplate": "conda/pixi:v1", + "format": WAVE_FORMAT[container_system], + "nameStrategy": "imageSuffix", + } + meta_data = wave_request( + "post", + f"{WAVE_API_ALPHA2}/container", + payload, + error_context=f"Wave build submit ({container_system} {platform})", + ) + log.log( + logging.INFO if verbose else logging.DEBUG, + f"Wave response ({container_system} {platform}):\n{pretty_repr(meta_data)}", + ) - # Parse Wave output - stdout_output = out[0].decode() + build_id = meta_data.get("buildId") or "" + request_id = meta_data.get("requestId") or "" + # Notify as soon as we have a build id, before waiting for the build to finish. + if build_id and on_build_id is not None: + on_build_id(build_id) - # In verbose mode, Wave outputs DEBUG lines before YAML - extract only the YAML part - if verbose: - stdout_output = cls._extract_yaml_from_wave_output(stdout_output) + # A build that is cached (or already reported DONE in the submit response) is + # resolved immediately; otherwise poll the container status endpoint until it + # finishes. + if not meta_data.get("cached") and meta_data.get("status") != "DONE": + cls._await_build(request_id, cancel_event=cancel_event) - try: - meta_data = yaml.safe_load(stdout_output) or {} - log.debug(f"Wave YAML metadata: \n{pretty_repr(meta_data)}") - except (KeyError, AttributeError, yaml.YAMLError) as e: - log.error(f"Failed to parse Wave output. Raw output:\n{stdout_output}") - raise RuntimeError(f"Could not parse wave YAML metadata ({container_system} {platform})") from e - if not meta_data.get("succeeded"): - raise RuntimeError( - f"Wave build ({container_system} {platform}) failed. Reason: {meta_data.get('reason', 'Unknown')}" - + ( - f"\nBuild log: {WAVE_URL}/view/builds/{meta_data.get('buildId')}" - if meta_data.get("buildId") - else "" - ) - ) image = meta_data.get("targetImage") or meta_data.get("containerImage") or "" if not image: raise RuntimeError(f"Wave build ({container_system} {platform}) did not return an image name") - build_id = meta_data.get("buildId", "") or "" scan_id = "" https_url = "" if container_system == "docker": - scan_id = meta_data.get("scanId", "") or "" + scan_id = meta_data.get("scanId") or "" if container_system == "singularity": inspect_out = cls.request_image_inspect(image) @@ -585,29 +628,20 @@ def request_container( @classmethod def request_image_inspect(cls, image: str) -> dict: """ - Request wave container inspect. + Inspect a container image via the Wave HTTP API (POST /v1alpha1/inspect). """ - executable = "wave" - args = ["--inspect", "-o yaml", "-i", image] - - args_str = " ".join(args) - log.debug(f"Wave command to request image inspect for image {image}: `wave {args_str}`") - out = run_cmd(executable, args_str) - - if out is None: - raise RuntimeError("Wave command did not return any output") - - try: - inspect_out = yaml.safe_load(out[0].decode()) or {} - except (KeyError, AttributeError, yaml.YAMLError) as e: - raise RuntimeError(f"Could not parse wave inspect yaml output for image {image}") from e - - return inspect_out + log.debug(f"Requesting Wave image inspect for image {image}") + return wave_request( + "post", + f"{WAVE_API_ALPHA1}/inspect", + {"containerImage": image}, + error_context=f"Wave inspect for image {image}", + ) @staticmethod def get_conda_lock_url(build_id) -> str: build_id_safe = quote(build_id, safe="") - url = f"{WAVE_URL}/v1alpha1/builds/{build_id_safe}/condalock" + url = f"{WAVE_API_ALPHA1}/builds/{build_id_safe}/condalock" return url def get_conda_lock_file(self, platform: str) -> str: @@ -631,10 +665,10 @@ def get_conda_lock_file(self, platform: str) -> str: # Generate the conda lock URL from the build_id conda_lock_url = self.get_conda_lock_url(build_id) - resp = requests.get(conda_lock_url) + # condalock returns plain text; route through the shared transport so the download + # shares Wave auth (and thus the relaxed rate limits) with the other Wave calls. log.debug(f"Downloading conda lock file from {conda_lock_url}") - if resp.status_code != 200: - raise ValueError(f"Failed to download conda lock file from {conda_lock_url}") + resp = wave_send("get", conda_lock_url, error_context=f"Conda lock download for platform {platform}") log.debug(f"Successfully downloaded conda lock file from {conda_lock_url}") return resp.text diff --git a/tests/modules/test_containers.py b/tests/modules/test_containers.py index 7a9220d870..5ba5c27d76 100644 --- a/tests/modules/test_containers.py +++ b/tests/modules/test_containers.py @@ -37,28 +37,35 @@ def test_init_sets_paths(self): assert self.module_containers.environment_yml == self.bpipe_test_module_path / "environment.yml" assert self.module_containers.meta_yml == self.bpipe_test_module_path / "meta.yml" + @staticmethod + def _fake_response(payload: dict | None = None, status_code: int = 200, text: str = "") -> mock.MagicMock: + """Build a fake requests.Response whose .json() returns ``payload``.""" + resp = mock.MagicMock() + resp.status_code = status_code + resp.text = text + resp.json.return_value = payload or {} + return resp + @mock.patch("nf_core.modules.containers.requests.get") @mock.patch.object(ModuleContainers, "request_image_inspect") - @mock.patch("nf_core.modules.containers.run_cmd") - def test_create_builds_containers(self, mock_run_cmd, mock_request_image_inspect, mock_requests_get): - def fake_run_cmd(executable: str, args_str: str): - assert executable == "wave" - system = "singularity" if "--singularity" in args_str else "docker" + @mock.patch("nf_core.modules.containers.requests.post") + def test_create_builds_containers(self, mock_post, mock_request_image_inspect, mock_requests_get): + def fake_post(url, json=None, headers=None): + # `format` is "sif" for singularity, "docker" otherwise + system = "singularity" if json.get("format") == "sif" else "docker" image = "community.wave.seqera.io/library/bpipe_test:0.1.0--abc123" - build_id = f"bd-abc123-{system}" meta = { - "buildId": build_id, - "cached": True, + "buildId": f"bd-abc123-{system}", + "cached": True, # cached -> no status polling needed "containerImage": image, "freeze": True, - "mirror": False, "requestId": f"req-abc123-{system}", - "scanId": f"sc-abc123-{system}" if system == "docker" else None, "succeeded": True, "targetImage": image, } - meta = {k: v for k, v in meta.items() if v is not None} - return (yaml.safe_dump(meta).encode(), b"") + if system == "docker": + meta["scanId"] = f"sc-abc123-{system}" + return self._fake_response(meta) def fake_request_image_inspect(image: str): return { @@ -74,12 +81,10 @@ def fake_request_image_inspect(image: str): } } - mock_response = mock.MagicMock() - mock_response.status_code = 200 - mock_response.text = "# conda lock file content" - mock_requests_get.return_value = mock_response + # requests.get is used to download the conda lock file + mock_requests_get.return_value = self._fake_response(text="# conda lock file content") - mock_run_cmd.side_effect = fake_run_cmd + mock_post.side_effect = fake_post mock_request_image_inspect.side_effect = fake_request_image_inspect containers, success = self.module_containers.create() @@ -108,29 +113,38 @@ def test_create_skips_conda_lock_when_build_id_missing(self, mock_request_contai containers, success = self.module_containers.create() assert not containers.conda - @mock.patch("nf_core.modules.containers.run_cmd") - def test_request_container_docker_success(self, mock_run_cmd): + @mock.patch("nf_core.modules.containers.requests.post") + def test_request_container_docker_success(self, mock_post): platform = CONTAINER_PLATFORMS[0] - meta = {"targetImage": "testC:latest", "buildId": "build-1", "scanId": "scan-1", "succeeded": True} - mock_run_cmd.return_value = (yaml.safe_dump(meta).encode(), b"") + meta = { + "targetImage": "testC:latest", + "buildId": "build-1", + "scanId": "scan-1", + "cached": True, + } + mock_post.return_value = self._fake_response(meta) container = ModuleContainers.request_container("docker", platform, self.environment_yml) assert container.name == "testC:latest" assert container.build_id == "build-1" assert container.scan_id == "scan-1" - args_str = mock_run_cmd.call_args[0][1] - assert "--await" in args_str - assert "--platform" in args_str - assert platform in args_str - assert "--singularity" not in args_str + # Inspect the submitted JSON payload instead of CLI args + url = mock_post.call_args[0][0] + payload = mock_post.call_args[1]["json"] + assert url.endswith("/v1alpha2/container") + assert payload["containerPlatform"] == platform + assert payload["format"] == "docker" + assert payload["freeze"] is True + assert payload["nameStrategy"] == "imageSuffix" + assert payload["packages"]["type"] == "CONDA" @mock.patch.object(ModuleContainers, "request_image_inspect") - @mock.patch("nf_core.modules.containers.run_cmd") - def test_request_container_singularity_adds_https(self, mock_run_cmd, mock_request_image_inspect): + @mock.patch("nf_core.modules.containers.requests.post") + def test_request_container_singularity_adds_https(self, mock_post, mock_request_image_inspect): platform = CONTAINER_PLATFORMS[0] - meta = {"containerImage": "testC:sif", "buildId": "build-2", "succeeded": True} - mock_run_cmd.return_value = (yaml.safe_dump(meta).encode(), b"") + meta = {"containerImage": "testC:sif", "buildId": "build-2", "cached": True} + mock_post.return_value = self._fake_response(meta) mock_request_image_inspect.return_value = { "container": { "manifest": { @@ -146,33 +160,44 @@ def test_request_container_singularity_adds_https(self, mock_run_cmd, mock_reque container = ModuleContainers.request_container("singularity", platform, self.environment_yml) assert container.name == "testC:sif" + assert mock_post.call_args[1]["json"]["format"] == "sif" expected_url = "https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/ab/abcde12345/data" assert container.https == expected_url mock_request_image_inspect.assert_called_once_with("testC:sif") - @mock.patch("nf_core.modules.containers.run_cmd", return_value=None) - def test_request_container_missing_output_raises(self, mock_run_cmd): - with pytest.raises(RuntimeError, match="Wave command did not return any output"): + @mock.patch("nf_core.modules.containers.requests.post") + def test_request_container_submit_error_raises(self, mock_post): + mock_post.return_value = self._fake_response(status_code=400, text="Bad Request") + with pytest.raises(RuntimeError, match="Wave build submit .* failed: HTTP 400"): ModuleContainers.request_container("docker", CONTAINER_PLATFORMS[0], self.environment_yml) - @mock.patch("nf_core.modules.containers.run_cmd") - def test_request_container_invalid_yaml_raises(self, mock_run_cmd): - mock_run_cmd.return_value = (b"invalid: [", b"") - with pytest.raises(RuntimeError, match="Could not parse wave YAML metadata"): + @mock.patch("nf_core.modules.containers.requests.get") + @mock.patch("nf_core.modules.containers.requests.post") + def test_request_container_build_failure_raises(self, mock_post, mock_get): + # Fresh (uncached) build -> polls the container status endpoint, which reports failure + mock_post.return_value = self._fake_response( + {"buildId": "bd-fail", "requestId": "req-fail", "cached": False, "targetImage": "x"} + ) + mock_get.return_value = self._fake_response( + {"status": "DONE", "succeeded": False, "reason": "boom", "detailsUri": "https://wave/log"} + ) + with pytest.raises(RuntimeError, match="Wave build req-fail failed: boom"): ModuleContainers.request_container("docker", CONTAINER_PLATFORMS[0], self.environment_yml) + # Polled the v1alpha2 container status endpoint with the requestId + assert mock_get.call_args[0][0].endswith("/v1alpha2/container/req-fail/status") - @mock.patch("nf_core.modules.containers.run_cmd") - def test_request_container_missing_image_raises(self, mock_run_cmd): - meta = {"buildId": "build-4", "succeeded": True} - mock_run_cmd.return_value = (yaml.safe_dump(meta).encode(), b"") + @mock.patch("nf_core.modules.containers.requests.post") + def test_request_container_missing_image_raises(self, mock_post): + mock_post.return_value = self._fake_response({"buildId": "build-4", "cached": True}) with pytest.raises(RuntimeError, match="did not return an image name"): ModuleContainers.request_container("docker", CONTAINER_PLATFORMS[0], self.environment_yml) - @mock.patch("nf_core.modules.containers.run_cmd") - def test_request_image_inspect_success(self, mock_run_cmd): + @mock.patch("nf_core.modules.containers.requests.post") + def test_request_image_inspect_success(self, mock_post): inspect_payload = {"container": {"manifest": {"layers": []}}} - mock_run_cmd.return_value = (yaml.safe_dump(inspect_payload).encode(), b"") + mock_post.return_value = self._fake_response(inspect_payload) assert ModuleContainers.request_image_inspect("testC:latest") == inspect_payload + assert mock_post.call_args[0][0].endswith("/v1alpha1/inspect") def test_get_conda_lock_url_quotes(self): build_id = "abc/def 123" @@ -198,7 +223,10 @@ def test_get_conda_lock_file(self, mock_requests_get): result = self.module_containers.get_conda_lock_file(platform) assert result == "# conda lock file content" expected_url = "https://wave.seqera.io/v1alpha1/builds/test-build-123/condalock" - mock_requests_get.assert_called_once_with(expected_url) + # The download now goes through wave_send, which passes json/headers too, + # so assert on the URL rather than the full call signature. + mock_requests_get.assert_called_once() + assert mock_requests_get.call_args[0][0] == expected_url def test_list_containers(self): containers = self._containers_by_system("testC") From 2e891151a7a5b1a234044ede9199c5991f6132f2 Mon Sep 17 00:00:00 2001 From: Sangeeth Thilakarathna <46221775+sanmaxdev@users.noreply.github.com> Date: Thu, 2 Jul 2026 16:53:20 +0530 Subject: [PATCH 090/135] Update nf_core/components/create.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- nf_core/components/create.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/components/create.py b/nf_core/components/create.py index d9930481fc..cbe4d11f9f 100644 --- a/nf_core/components/create.py +++ b/nf_core/components/create.py @@ -428,7 +428,7 @@ def _get_username(self): # Regex to validate username (GitHub, GitLab, and other git providers) username_regex = re.compile(r"^@[a-zA-Z\d](?:[a-zA-Z\d\.]|-(?=[a-zA-Z\d\.])){0,38}$") while self.author is None or not username_regex.match(self.author): - if self.author is not None and not username_regex.match(self.author): + if self.author is not None log.warning("Does not look like a valid username (must start with an '@')!") self.require_prompts("GitHub username not provided.\nPlease provide the `--author` option") self.author = rich.prompt.Prompt.ask( From 629aa7ef5e390e7d9d5ccfca534649e249e0cd46 Mon Sep 17 00:00:00 2001 From: sanmaxdev Date: Thu, 2 Jul 2026 23:06:11 +0000 Subject: [PATCH 091/135] fix: address username validation review --- nf_core/components/create.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nf_core/components/create.py b/nf_core/components/create.py index 942db57e6e..bfd0866668 100644 --- a/nf_core/components/create.py +++ b/nf_core/components/create.py @@ -425,10 +425,10 @@ def _get_username(self): except (subprocess.CalledProcessError, FileNotFoundError) as e: log.debug(f"Could not find GitHub username using 'gh' cli command: [red]{e}") - # Regex to validate username (GitHub, GitLab, and other git providers) + # Regex to validate username (GitHub, GitLab, and other git-based code hosting services) username_regex = re.compile(r"^@[a-zA-Z\d](?:[a-zA-Z\d\.]|-(?=[a-zA-Z\d\.])){0,38}$") while self.author is None or not username_regex.match(self.author): - if self.author is not None + if self.author is not None: log.warning("Does not look like a valid username (must start with an '@')!") self.require_prompts("GitHub username not provided.\nPlease provide the `--author` option") self.author = rich.prompt.Prompt.ask( From 090b87811f358989811513b2033ae6892c0d6765 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 05:43:24 +0200 Subject: [PATCH 092/135] Update dependency prettier to v3.9.4 (#4364) --- .pre-commit-config.yaml | 2 +- nf_core/.pre-commit-prettier-config.yaml | 2 +- nf_core/pipeline-template/.pre-commit-config.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b6dd518ebc..8cf05e0725 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - id: prettier entry: prettier --experimental-cli --write --ignore-unknown --no-cache additional_dependencies: - - prettier@3.8.4 + - prettier@3.9.4 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: diff --git a/nf_core/.pre-commit-prettier-config.yaml b/nf_core/.pre-commit-prettier-config.yaml index 910d84508d..b8cfe30d9f 100644 --- a/nf_core/.pre-commit-prettier-config.yaml +++ b/nf_core/.pre-commit-prettier-config.yaml @@ -4,4 +4,4 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.8.4 + - prettier@3.9.4 diff --git a/nf_core/pipeline-template/.pre-commit-config.yaml b/nf_core/pipeline-template/.pre-commit-config.yaml index 7bfe2466d0..a6d370f4bd 100644 --- a/nf_core/pipeline-template/.pre-commit-config.yaml +++ b/nf_core/pipeline-template/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.8.4 + - prettier@3.9.4 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: From 7dbf418b81cbadb530e3d4a339ed13d838002907 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 03:50:56 +0000 Subject: [PATCH 093/135] Update docker/setup-qemu-action digest to 96fe6ef (#4368) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/push_dockerhub.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/push_dockerhub.yml b/.github/workflows/push_dockerhub.yml index 587596700b..1233d500bf 100644 --- a/.github/workflows/push_dockerhub.yml +++ b/.github/workflows/push_dockerhub.yml @@ -37,13 +37,13 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Set up QEMU for multi-architecture build - uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4 + uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4 + uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 - name: Log in to Docker Hub - uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4 + uses: docker/login-action@c99871dec2022cc055c062a10cc1a1310835ceb4 # v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASS }} From 15a7893f8579b310f7ff02d3479d4ceb6b6555be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2026 10:27:40 +0200 Subject: [PATCH 094/135] Update docker/login-action digest to af1e73f (#4373) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/create-lint-wf.yml | 2 +- .github/workflows/create-test-lint-wf-template.yml | 2 +- .github/workflows/create-test-wf.yml | 2 +- .github/workflows/deploy-pypi.yml | 2 +- .github/workflows/nextflow-source-test.yml | 2 +- .github/workflows/push_dockerhub.yml | 2 +- .github/workflows/pytest.yml | 2 +- .github/workflows/sync.yml | 2 +- .github/workflows/update-template-snapshots.yml | 2 +- .github/workflows/update-textual-snapshots.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 6eab40a3d8..2d6e74f1a9 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -52,7 +52,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 with: enable-cache: true diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index 1ffce179b1..bffff8f2b4 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -64,7 +64,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 with: enable-cache: true diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index 419417149a..28d7c181b1 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 with: enable-cache: true diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index 6888ed7436..c96abaad91 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -22,7 +22,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 with: enable-cache: true diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index 78544f16d2..7a940a1201 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 with: enable-cache: true diff --git a/.github/workflows/push_dockerhub.yml b/.github/workflows/push_dockerhub.yml index 1233d500bf..7123d82ebb 100644 --- a/.github/workflows/push_dockerhub.yml +++ b/.github/workflows/push_dockerhub.yml @@ -43,7 +43,7 @@ jobs: uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 - name: Log in to Docker Hub - uses: docker/login-action@c99871dec2022cc055c062a10cc1a1310835ceb4 # v4 + uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASS }} diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 4847ceeeb4..99c40610bb 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -82,7 +82,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 with: enable-cache: true diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 96b3569a66..b8b44fa2c0 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -82,7 +82,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 with: enable-cache: true diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index fc93b0a451..ca387d2006 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -61,7 +61,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 with: enable-cache: true diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index 3ea27249ac..114ea52a09 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -42,7 +42,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 with: enable-cache: true diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 672fb10436..be1defd7f3 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -34,7 +34,7 @@ jobs: architecture: "x64" - name: Setup uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 - name: read .nf-core.yml uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 From e1cf743844a6d6e8b1175b3790c8e3146e8e891c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2026 11:06:19 +0000 Subject: [PATCH 095/135] Update github/branch-deploy action to v11.1.5 (#4382) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/changelog.yml | 2 +- .github/workflows/create-lint-wf.yml | 2 +- .github/workflows/create-test-lint-wf-template.yml | 2 +- .github/workflows/create-test-wf.yml | 2 +- .github/workflows/deploy-pypi.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/nextflow-source-test.yml | 2 +- .github/workflows/pytest.yml | 2 +- .github/workflows/sync.yml | 2 +- .github/workflows/update-template-snapshots.yml | 4 ++-- .github/workflows/update-textual-snapshots.yml | 4 ++-- nf_core/pipeline-template/.github/workflows/linting.yml | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index ac12956890..2f67646b60 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -12,7 +12,7 @@ jobs: - name: branch-deploy id: branch-deploy if: github.event_name == 'issue_comment' - uses: github/branch-deploy@ddf8ca48e9cdb2d2c7c71dee428308b19af9313f # v11.1.4 + uses: github/branch-deploy@de4d10ee17c3117a2076aff489ba03fadf225f35 # v11.1.5 with: trigger: "@nf-core-bot changelog" reaction: "eyes" diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 2d6e74f1a9..84643198f4 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -52,7 +52,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 with: enable-cache: true diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index bffff8f2b4..b7ffba3105 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -64,7 +64,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 with: enable-cache: true diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index 28d7c181b1..e2ad32db3f 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 with: enable-cache: true diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index c96abaad91..4ec6e56d8e 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -22,7 +22,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 with: enable-cache: true diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index bf2c286f29..dbb5c125cd 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -12,7 +12,7 @@ jobs: steps: - name: branch-deploy id: branch-deploy - uses: github/branch-deploy@ddf8ca48e9cdb2d2c7c71dee428308b19af9313f # v11.1.4 + uses: github/branch-deploy@de4d10ee17c3117a2076aff489ba03fadf225f35 # v11.1.5 with: trigger: "@nf-core-bot fix linting" reaction: "eyes" diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index 7a940a1201..70ec919f47 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 with: enable-cache: true diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 99c40610bb..c58af2fe48 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -82,7 +82,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Install uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 with: enable-cache: true diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index b8b44fa2c0..fa11f4fba6 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -82,7 +82,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 with: enable-cache: true diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index ca387d2006..e9803e2367 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -15,7 +15,7 @@ jobs: steps: - name: branch-deploy id: branch-deploy - uses: github/branch-deploy@ddf8ca48e9cdb2d2c7c71dee428308b19af9313f # v11.1.4 + uses: github/branch-deploy@de4d10ee17c3117a2076aff489ba03fadf225f35 # v11.1.5 with: trigger: "@nf-core-bot update template snapshots" reaction: "eyes" @@ -61,7 +61,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 with: enable-cache: true diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index 114ea52a09..63ccaa852f 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -10,7 +10,7 @@ jobs: steps: - name: branch-deploy id: branch-deploy - uses: github/branch-deploy@ddf8ca48e9cdb2d2c7c71dee428308b19af9313f # v11.1.4 + uses: github/branch-deploy@de4d10ee17c3117a2076aff489ba03fadf225f35 # v11.1.5 with: trigger: "@nf-core-bot update textual snapshots" reaction: "eyes" @@ -42,7 +42,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 with: enable-cache: true diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 3f194aa7e0..de51d453f6 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -34,7 +34,7 @@ jobs: architecture: "x64" - name: Setup uv - uses: astral-sh/setup-uv@d31148d669074a8d0a63714ba94f3201e7020bc3 # v8.3.0 + uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 - name: read .nf-core.yml uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 From 39e6bfcd098f8bdecb74a0aa9f2ffc4857b30348 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 09:47:21 +0200 Subject: [PATCH 096/135] Update actions/setup-java digest to 0f481fc (#4385) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/nextflow-source-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index 70ec919f47..28f85bb143 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -20,7 +20,7 @@ jobs: path: nextflow - name: Set up Java - uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5 + uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5 with: distribution: "temurin" architecture: x64 From 922d6a59be8e6788c3ae9b9fc2d17a839a7d7db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 8 Jul 2026 12:23:39 +0200 Subject: [PATCH 097/135] switch from dev dependencies from `optional-dependencies` to `dependency-groups` (#4386) --- .devcontainer/setup.sh | 2 +- .github/workflows/create-lint-wf.yml | 2 +- .../create-test-lint-wf-template.yml | 2 +- .github/workflows/pytest.yml | 2 +- .../workflows/update-template-snapshots.yml | 2 +- .../workflows/update-textual-snapshots.yml | 2 +- CONTRIBUTING.md | 2 +- README.md | 2 +- pyproject.toml | 2 +- uv.lock | 917 +++++++++--------- 10 files changed, 472 insertions(+), 463 deletions(-) diff --git a/.devcontainer/setup.sh b/.devcontainer/setup.sh index e19a29c74a..2ffcd8cbc5 100755 --- a/.devcontainer/setup.sh +++ b/.devcontainer/setup.sh @@ -10,7 +10,7 @@ export PS1='\[\e[3;36m\]\w ->\[\e[0m\\] ' nextflow self-update # Install specifically the version of tools from the workspace -uv sync --all-extras +uv sync # Activate the virtual environment automatically on login echo "source $(pwd)/.venv/bin/activate" >> $HOME/.bashrc diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 84643198f4..a95e7b930a 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -57,7 +57,7 @@ jobs: enable-cache: true - name: Install python dependencies - run: uv sync --all-extras + run: uv sync - name: run create-lint-wf uses: ./.github/actions/create-lint-wf diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index b7ffba3105..433f36e477 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -69,7 +69,7 @@ jobs: enable-cache: true - name: Install python dependencies - run: uv sync --all-extras + run: uv sync - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index c58af2fe48..970544be6c 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -87,7 +87,7 @@ jobs: enable-cache: true - name: Install dependencies - run: uv sync --all-extras + run: uv sync - name: Set up Apptainer if: ${{ startsWith(matrix.test, 'pipelines/download/') }} diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index e9803e2367..bbb2192c53 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -66,7 +66,7 @@ jobs: enable-cache: true - name: Install dependencies - run: uv sync --all-extras + run: uv sync - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index 63ccaa852f..abf70edafb 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -47,7 +47,7 @@ jobs: enable-cache: true - name: Install dependencies - run: uv sync --all-extras + run: uv sync - name: Run pytest to update snapshots id: pytest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9405e36577..5b06df0b14 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ If you want to work with developing the nf-core/tools code, you'll need a couple Install using `uv`: ```bash -uv sync --all-extras +uv sync ``` This will install all dependencies (listed in `pyproject.toml`) and install your local fork of nf-core/tools in editable mode. The virtual environment is automatically created in `.venv/` in the project directory. diff --git a/README.md b/README.md index ed6652f7a6..5a8ecc1c23 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ pip install --upgrade --force-reinstall git+https://github.com/nf-core/tools.git If editing, fork and clone the repo, then install as follows: ```bash -uv sync --all-extras +uv sync # Activate the virtual environment source .venv/bin/activate diff --git a/pyproject.toml b/pyproject.toml index b5f2bb9544..52c30709dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,7 +60,7 @@ dependencies = [ "ruamel.yaml", ] -[project.optional-dependencies] +[dependency-groups] dev = [ "mypy>=2.0.0", "myst_parser", diff --git a/uv.lock b/uv.lock index 47efc64a9b..8db081c0be 100644 --- a/uv.lock +++ b/uv.lock @@ -201,40 +201,43 @@ wheels = [ [[package]] name = "ast-serialize" -version = "0.3.0" +version = "0.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/9d/912fefab0e30aee6a3af8a62bbea4a81b29afa4ba2c973d31170620a26de/ast_serialize-0.3.0.tar.gz", hash = "sha256:1bc3ca09a63a021376527c4e938deedd11d11d675ce850e6f9c7487f5889992b", size = 60689, upload-time = "2026-04-30T23:24:48.104Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/57/a54d4de491d6cdd7a4e4b0952cc3ca9f60dcefa7b5fb48d6d492debe1649/ast_serialize-0.3.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:3a867927df59f76a18dc1d874a0b2c079b42c58972dca637905576deb0912e14", size = 1182966, upload-time = "2026-04-30T23:23:57.376Z" }, - { url = "https://files.pythonhosted.org/packages/ee/9e/a5db014bb0f91b209236b57c429389e31290c0093532b8436d577699b2fa/ast_serialize-0.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a6fb063bf040abf8321e7b8113a0554eda445ffc508aa51287f8808886a5ae22", size = 1171316, upload-time = "2026-04-30T23:23:59.63Z" }, - { url = "https://files.pythonhosted.org/packages/15/59/fd55133e478c4326f60a11df02573bf7ccb2ac685810b50f1803d0f68053/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5075cd8482573d743586779e5f9b652a015e37d4e95132d7e5a9bc5c8f483d8f", size = 1232234, upload-time = "2026-04-30T23:24:01.168Z" }, - { url = "https://files.pythonhosted.org/packages/cc/79/0ca1d26357ecb4a697d74d00b73ef3137f24c140424125393a0de820eb09/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:41560b27794f4553b0f77811e9fb325b77db4a2b39018d437e09932275306e66", size = 1233437, upload-time = "2026-04-30T23:24:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/53/3e/7078ec94dd6e124b8e028ac77016a4f13c83fa1c145790f2e68f3816998b/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b967c01ca74909c5d90e0fe4393401e2cc5da5ebd9a6262a19e45ffd3757dec8", size = 1440188, upload-time = "2026-04-30T23:24:04.717Z" }, - { url = "https://files.pythonhosted.org/packages/21/16/cca7195ef55a012f8013c3442afa91d287a0a36dcf88b480b262475135b3/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:424ebb8f46cd993f7cec4009d119312d8433dd90e6b0df0499cd2c91bdcc5af9", size = 1254211, upload-time = "2026-04-30T23:24:06.18Z" }, - { url = "https://files.pythonhosted.org/packages/a0/0f/f3d4dfae67dee6580534361a6343367d34217e7d25cff858bd1d8f03b8ed/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d14b1d566b56e2ee70b11fec1de7e0b94ec7cd83717ec7d189967841a361190e", size = 1255973, upload-time = "2026-04-30T23:24:07.772Z" }, - { url = "https://files.pythonhosted.org/packages/14/41/55fbfe02c42f40fbe3e74eda167d977d555ff720ce1abfa08515236efd88/ast_serialize-0.3.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7ba30b18735f047ec11103d1ab92f4789cf1fea1e0dc89b04a2f5a0632fd79de", size = 1298629, upload-time = "2026-04-30T23:24:09.4Z" }, - { url = "https://files.pythonhosted.org/packages/28/36/7d2501cacc7989fb8504aa9da2a2022a174200a59d4e6639de4367a57fdd/ast_serialize-0.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e6ea0754cb7b0f682ebb005ffb0d18f8d17993490d9c289863cd69cacc4ab8df", size = 1408435, upload-time = "2026-04-30T23:24:11.013Z" }, - { url = "https://files.pythonhosted.org/packages/03/e7/54e3b469c3fa0bf9cd532fa643d1d33b73303f8d70beac3e366b68dd64b7/ast_serialize-0.3.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:a0c5aa1073a5ba7b2abaa4b54abe8b8d75c4d1e2d54a2ff70b0ca6222fea5728", size = 1508174, upload-time = "2026-04-30T23:24:12.635Z" }, - { url = "https://files.pythonhosted.org/packages/b5/2a/9b9621865b02c60539e26d9b114a312b4fa46aa703e33e79317174bfea21/ast_serialize-0.3.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:4e52650d834c1ea7791969a361de2c54c13b2fb4c519ec79445fa8b9021a147d", size = 1502354, upload-time = "2026-04-30T23:24:14.186Z" }, - { url = "https://files.pythonhosted.org/packages/34/dd/f138bc5c43b0c414fdd12eefe15677839323078b6e75301ad7f96cd26d45/ast_serialize-0.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:15bd6af3f136c61dae27805eb6b8f3269e85a545c4c27ffe9e530ead78d2b36d", size = 1450504, upload-time = "2026-04-30T23:24:16.076Z" }, - { url = "https://files.pythonhosted.org/packages/68/cf/97ef9e1c315601db74365955c8edd3292e3055500d6317602815dbdf08ae/ast_serialize-0.3.0-cp314-cp314t-win32.whl", hash = "sha256:d188bfe37b674b49708497683051d4b571366a668799c9b8e8a94513694969d9", size = 1058662, upload-time = "2026-04-30T23:24:17.535Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d6/e2c3483c31580fdb623f92ad38d2f856cde4b9205a3e6bd84760f3de7d82/ast_serialize-0.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:5832c2fdf8f8a6cf682b4cfcf677f5eaf39b4ddbc490f5480cfccdd1e7ce8fa1", size = 1100349, upload-time = "2026-04-30T23:24:18.992Z" }, - { url = "https://files.pythonhosted.org/packages/ab/89/29abcb1fe18a429cda60c6e0bbd1d6e90499339842a2f548d7567542357e/ast_serialize-0.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:670f177188d128fb7f9f15b5ad0e1b553d22c34e3f584dcb83eb8077600437f0", size = 1072895, upload-time = "2026-04-30T23:24:20.706Z" }, - { url = "https://files.pythonhosted.org/packages/bc/93/72abad83966ed6235647c9f956417dc1e17e997696388521910e3d1fa3f4/ast_serialize-0.3.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:2ec2fafa5e4313cc8feed96e436ebe19ac7bc6fa41fbc2827e826c48b9e4c3a9", size = 1190024, upload-time = "2026-04-30T23:24:22.486Z" }, - { url = "https://files.pythonhosted.org/packages/85/4f/eb88584b2f0234e581762011208ca203252bf6c98e59b4769daa571f3576/ast_serialize-0.3.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ef6d3c08b7b4cd29b48410338e134764a00e76d25841eb02c1084e868c888ecc", size = 1178633, upload-time = "2026-04-30T23:24:24.35Z" }, - { url = "https://files.pythonhosted.org/packages/56/51/cf1ec1ff3e616373d0dcbd5fad502e0029dc541f13ab642259762a7d127f/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d841424f41b886e98044abc80769c14a956e6e5ccd5fb5b0d9f5ead72be18a4", size = 1241351, upload-time = "2026-04-30T23:24:25.987Z" }, - { url = "https://files.pythonhosted.org/packages/0d/44/68fcf50478cf1093f2d423f034ae06453122c8b415d8e21a44668eca485d/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d21453734ad39367ede5d37efe4f59f830ce1c09f432fc72a90e368f77a4a3e7", size = 1239582, upload-time = "2026-04-30T23:24:27.808Z" }, - { url = "https://files.pythonhosted.org/packages/9d/c1/a6c9fa284eceb5fc6f21347e968445a051d7ca2c4d34e6a04314646dbcee/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f5e110cdce2a347e1dd987529c88ef54d26f67848dce3eba1b3b2cc2cf085c94", size = 1448853, upload-time = "2026-04-30T23:24:29.534Z" }, - { url = "https://files.pythonhosted.org/packages/23/5f/8ad3829a09e4e8c5328a53ce7d4711d660944e3e164c5f6abcc2c8f27167/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b6e23a98e57560a055f5c4b68700a0fd5ce483d2814c23140b3638c7f5d1e61", size = 1262204, upload-time = "2026-04-30T23:24:31.482Z" }, - { url = "https://files.pythonhosted.org/packages/25/13/44aa28d97f10e25247e8576b5f6b2795d4fa1a80acc88acc942c508d06f7/ast_serialize-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1c9e763d70293d65ce1e1ea8c943140c68d0953f0268c7ee0998f2e07f77dd0", size = 1266458, upload-time = "2026-04-30T23:24:33.088Z" }, - { url = "https://files.pythonhosted.org/packages/d8/58/b3a8be3777cd3744324fd5cec0d80d37cd96fc7cbb0fb010e03dff1e870f/ast_serialize-0.3.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4388a1796c228f1ce5c391426f7d21a0003ad3b47f677dbeded9bd1a85c7209f", size = 1308700, upload-time = "2026-04-30T23:24:34.657Z" }, - { url = "https://files.pythonhosted.org/packages/13/03/f8312d6b57f5471a9dc7946f22b8798a1fc296d38c25766223aacadec42c/ast_serialize-0.3.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5283cdcc0c64c3d8b9b688dc6aaa012d9c0cf1380a7f774a6bae6a1c01b3205a", size = 1416724, upload-time = "2026-04-30T23:24:36.562Z" }, - { url = "https://files.pythonhosted.org/packages/50/5d/13fc3789a7abac00559da2e2e9f386db4612aa1f84fc53d09bf714c37545/ast_serialize-0.3.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:f5ef88cc5842a5d7a6ac09dc0d5fc2c98f5d276c1f076f866d55047ce886785b", size = 1515441, upload-time = "2026-04-30T23:24:38.018Z" }, - { url = "https://files.pythonhosted.org/packages/eb/b9/7ab43fc7a23b1f970281093228f5f79bed6edeed7a3e672bde6d7a832a58/ast_serialize-0.3.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:cc14bf402bdc0978594ecce783793de2c7470cd4f5cd7eb286ca97ed8ff7cba9", size = 1510522, upload-time = "2026-04-30T23:24:39.798Z" }, - { url = "https://files.pythonhosted.org/packages/56/ec/d75fc2b788d319f1fad77c14156896f31afdfc68af85b505e5bdebcb9592/ast_serialize-0.3.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:11eae0cf1b7b3e0678133cc2daa974ea972caf02eb4b3aa062af6fa9acd52c57", size = 1460917, upload-time = "2026-04-30T23:24:41.305Z" }, - { url = "https://files.pythonhosted.org/packages/95/74/f99c81193a2725911e1911ae567ed27c2f2419332c7f3537366f9d238cac/ast_serialize-0.3.0-cp39-abi3-win32.whl", hash = "sha256:2db3dd99de5e6a5a11d7dda73de8750eb6e5baaf25245adf7bdcfe64b6108ae2", size = 1067804, upload-time = "2026-04-30T23:24:43.091Z" }, - { url = "https://files.pythonhosted.org/packages/16/81/76af00c47daa151e89f98ae21fbbcb2840aaa9f5766579c4da76a3c57188/ast_serialize-0.3.0-cp39-abi3-win_amd64.whl", hash = "sha256:a2cd125adccf7969470621905d302750cd25951f22ea430d9a25b7be031e5549", size = 1105561, upload-time = "2026-04-30T23:24:44.578Z" }, - { url = "https://files.pythonhosted.org/packages/bd/46/d3ec57ad500f598d1554bd14ce4df615960549ab2844961bc4e1f5fbd174/ast_serialize-0.3.0-cp39-abi3-win_arm64.whl", hash = "sha256:0dd00da29985f15f50dc35728b7e1e7c84507bccfea1d9914738530f1c72238a", size = 1077165, upload-time = "2026-04-30T23:24:46.377Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/58/ad/0d70a3a2d6e01968d985415259e8ec7ad3f777903f9b1c1f3c8c44642c60/ast_serialize-0.6.0.tar.gz", hash = "sha256:aadd3ffcf4858c9726bf3515f7b199c7eadbe504f96028e4a87172c0da65a8fe", size = 61489, upload-time = "2026-06-30T20:02:55.555Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/12/3e5f575f156555547c250a8b0d1347517a3a20fc7f4492e9703a69d4f45e/ast_serialize-0.6.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:a7520b672827885bafeae7501f684d14d47d17e5f45256f9df547686cca52264", size = 1177640, upload-time = "2026-06-30T20:02:06.708Z" }, + { url = "https://files.pythonhosted.org/packages/a2/a4/921a9e27951627983b0f368859ea00f8330a551dc0bf4c2fdcb11855a98b/ast_serialize-0.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a14191beec7e0c078d2fc1f6edc0aee88bcd4db9f18e1bc9f8052b559c22dddc", size = 1168111, upload-time = "2026-06-30T20:02:08.366Z" }, + { url = "https://files.pythonhosted.org/packages/00/69/950cf404de7b8782cf95e5c1237e25e2aa46177b287f39f9eeddf481fd6f/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32ef62ec34cf6be20ad77d4799556638fbdf187f3ae10698dfb20ef9f2c89516", size = 1227656, upload-time = "2026-06-30T20:02:09.843Z" }, + { url = "https://files.pythonhosted.org/packages/4c/a8/46f8f6a6479d9d2273980957bb091a506c55f5b95d3c029ee58518a78407/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13b7769970a39983b0adf2f38917b1cd3b8946f76df045756c3d741bc689f089", size = 1227706, upload-time = "2026-06-30T20:02:11.367Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b9/9ac415bda0a40e49eab8fea3b2741c19c98bb84d57d62c4cfc6230eb67be/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f7a408601bb3edaefb3bc67a4c01f5235e3253653b6a5729a2ee2382b35341c", size = 1431705, upload-time = "2026-06-30T20:02:12.737Z" }, + { url = "https://files.pythonhosted.org/packages/e5/06/8807115d441444879f7561b5eede5ac18fc80392f11826d61ccf31f503b1/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8670bfa51208a2c0c8d138928e40e998fab158f9200d53bb80c088b5b8eda7b8", size = 1249533, upload-time = "2026-06-30T20:02:14.571Z" }, + { url = "https://files.pythonhosted.org/packages/3e/c0/c2ba82ef9618650357d9421a1fdb27ffec862a7f57e8e2de82a3ccd11e12/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4826809eb8597a8cd59fd924b6d7c285b8969a1e0007e2cb652cab62376270f", size = 1252619, upload-time = "2026-06-30T20:02:16.219Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a7/fa31d52dd4102cede29fb9634e98d214129b2783b4f95528c6dc6a8f6587/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:577a6c189068686869f5f1ddc38363f3ae1808a4753b577266f9202071a7bb66", size = 1242983, upload-time = "2026-06-30T20:02:17.813Z" }, + { url = "https://files.pythonhosted.org/packages/b1/20/ddf742b5ad3c4bafd3466f2265037cfd99bc1b9a5ee46a5d58c90d523242/ast_serialize-0.6.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:085de7f62dc9cc247eb01e965a362707d1d90b1d89a82c5bf78301a60a3c417b", size = 1296148, upload-time = "2026-06-30T20:02:19.146Z" }, + { url = "https://files.pythonhosted.org/packages/24/cb/9f6f217cce8b3b632c5568b478d195a35e79dce4dbe309438cb89ba6ea4f/ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9f8a8b78b13173de6a9ec22111d9be674874cd5bdccda04f14ae5ebc2bef403a", size = 1403826, upload-time = "2026-06-30T20:02:20.696Z" }, + { url = "https://files.pythonhosted.org/packages/2d/f8/9d16d4f0107a183924425cc0e7618d8bf76f96b45afa9ff19f924ed1ad57/ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f2ff3baffc3a29c1f15bc9098aa0c09763410262d5e6cef42116f7356c184554", size = 1502943, upload-time = "2026-06-30T20:02:22.034Z" }, + { url = "https://files.pythonhosted.org/packages/80/dd/bbc1c38756350dddf7e24acae1c9482ef42051c267417e019aecc1ed4075/ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0067b25fce104eaae5b88383de9ab803faeb671831e14ca698b771b356e2600f", size = 1497632, upload-time = "2026-06-30T20:02:23.517Z" }, + { url = "https://files.pythonhosted.org/packages/42/7e/9daffefcf5b97e6bb4c3e0b3c024c1aee9722f23d3cf7cd2ff80d6fb4a40/ast_serialize-0.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c617417f9cbb0cb144f6283c3cbe0d2e0f01beaf9f608f662b21191058a626ec", size = 1448858, upload-time = "2026-06-30T20:02:24.889Z" }, + { url = "https://files.pythonhosted.org/packages/e5/1f/f9baaab81a677ea0af7d2458cac2f94ebcc85958f8a3c15ba9d9e5dab653/ast_serialize-0.6.0-cp314-cp314t-win32.whl", hash = "sha256:5337cb256dcea3df9288205213d1601581536526b8f4da44b6974f1180f3252a", size = 1052600, upload-time = "2026-06-30T20:02:26.263Z" }, + { url = "https://files.pythonhosted.org/packages/9e/1f/41b535866519512d8cf6669cb2cff7823b7672bb6279c0333b4ff89d7d9f/ast_serialize-0.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2d947e45cafc4b09bd7528917fa84c517654a43de173c79785574b7b3068ac24", size = 1095570, upload-time = "2026-06-30T20:02:27.639Z" }, + { url = "https://files.pythonhosted.org/packages/50/64/e472fe3e3a2d33d874b987e8518aedf24562919e3b6161a4fa1797e89c0f/ast_serialize-0.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:6e15ec740436e1a0d62de848641abe5f3a2f89a7f94907d534795ac91bbacf14", size = 1067267, upload-time = "2026-06-30T20:02:28.949Z" }, + { url = "https://files.pythonhosted.org/packages/52/19/ac8348ae8711c9b5ae834634f635780cab62a0f5e6f988882e048b89c2ae/ast_serialize-0.6.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:093cb8bb91b720d8523580498d031791bb1bbaa048599c3d21085d380e11a596", size = 1185367, upload-time = "2026-06-30T20:02:30.427Z" }, + { url = "https://files.pythonhosted.org/packages/c1/f6/ec7ec652c51db77c2f61d8573338e13e4704303265ccc658cb4031d9f354/ast_serialize-0.6.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:e61580a69faf47e3689795367ed211f2a10fd741478cc0f36a0f128793360aad", size = 1178657, upload-time = "2026-06-30T20:02:31.964Z" }, + { url = "https://files.pythonhosted.org/packages/6f/02/613a7534a41d0122f37d1e0c64aa8ac78bfb831f8c92f6db057a311abb3c/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:305802f2ce2a7c4e87835078ea85c58b586ddda8095b92fe2ead9364ae19c80a", size = 1238620, upload-time = "2026-06-30T20:02:33.664Z" }, + { url = "https://files.pythonhosted.org/packages/4d/21/087957bba486242afc52f49b2d9e21c9dad00289356cf9efe67084015a9d/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c7b8b8f0c42f752ea00b2b7d7c090b3f80d9c1c5c75cadf16423790a0cc74081", size = 1236075, upload-time = "2026-06-30T20:02:34.936Z" }, + { url = "https://files.pythonhosted.org/packages/82/04/78128bbb170071c2c72a210a181f1c00e11cc1cec60a8beef747b07f9201/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd5b91b9e6f2356ace3a556963b0cd783b395fbbb0bb17b4defc283415466e77", size = 1441348, upload-time = "2026-06-30T20:02:36.245Z" }, + { url = "https://files.pythonhosted.org/packages/64/64/62fb99d6faf199b4c3e5b08a07136e9a0d7664bb249c6de3670e5b63e9b6/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d6ef91590258ada18909b9caea344dac4de2013906b035473cd674a43f4b790", size = 1258580, upload-time = "2026-06-30T20:02:37.53Z" }, + { url = "https://files.pythonhosted.org/packages/ca/87/b4d6c38e0ccd5e85dc54cecdf933a152c60b28fe5d993a6d8a72fa6d5896/ast_serialize-0.6.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcbed41e9386059fc0261d602445ede0976c2ecec2939688bcbcb9ed0b6f28b7", size = 1261693, upload-time = "2026-06-30T20:02:39.123Z" }, + { url = "https://files.pythonhosted.org/packages/0e/4b/3676ca2191f39bafb75f93f99b2f429ec464586158fece2165f3572805dc/ast_serialize-0.6.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:cdc4e6f930b9090c2f92c9036ad12ffb8e6e44d4a5ba06f1458a05d60f203f7b", size = 1252517, upload-time = "2026-06-30T20:02:40.511Z" }, + { url = "https://files.pythonhosted.org/packages/f3/58/494ef8c4b4acb2f4a265ac934caf45f792a08fe27d6b853de35ad991941a/ast_serialize-0.6.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:897ac47b5637be41c0c07061c8a912fafa967ef1dc73fa115e4bfa70882a093b", size = 1304843, upload-time = "2026-06-30T20:02:41.961Z" }, + { url = "https://files.pythonhosted.org/packages/b1/f2/13736d920ab3d49bbee80ef1a277dd7b7aaf3b3545efd9d2a8114fe05525/ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c4af9a1386166e40ed01464991806f89038a2d89782576c7774876fa77034e32", size = 1413698, upload-time = "2026-06-30T20:02:44.179Z" }, + { url = "https://files.pythonhosted.org/packages/a8/5a/e046f3899e2acba4677d7427b76431443a1aa1a0e583dfb05b55b69d55cf/ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:c901adbd750029b9ac4ad3d6aa56853e0ad4875119fbf52b7b8298afc223828b", size = 1512209, upload-time = "2026-06-30T20:02:45.584Z" }, + { url = "https://files.pythonhosted.org/packages/cc/c7/e42aaca7bb2d22a7c06d5a8c7930086c5a334e93d716e6fa5e6647a4515f/ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:3ae22a366b752ab4496191525b78b097b5b72d531752e3c1dd7e383a8f2c8a1a", size = 1508464, upload-time = "2026-06-30T20:02:46.942Z" }, + { url = "https://files.pythonhosted.org/packages/95/93/5524a3dc6c3f593de3228ed9cbef73afa047625b7000ec21b7f58e6eb4d4/ast_serialize-0.6.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4ed29121da8b3fdc291002801a1de0f76248fa07dce89157a5f277842cf6126e", size = 1457164, upload-time = "2026-06-30T20:02:48.294Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c0/36a6ffb4d653cf621427b4c4928671f53ad800c453474de2b82564a44ad9/ast_serialize-0.6.0-cp39-abi3-pyemscripten_2026_0_wasm32.whl", hash = "sha256:b1dac4e09d341c1300ba69cdcbe62867b32a8c75d90db9bf4d083bec3b039f0b", size = 863014, upload-time = "2026-06-30T20:02:49.742Z" }, + { url = "https://files.pythonhosted.org/packages/09/c7/7d5ad8b49e1278e1c2a1e0274bd7850560b3f09313aa00c13bc8d5544792/ast_serialize-0.6.0-cp39-abi3-win32.whl", hash = "sha256:82c312a7844d2fdeb4d5c48bd3d215bf940dafd4704e1a9bcf252a99010a99b1", size = 1063165, upload-time = "2026-06-30T20:02:50.98Z" }, + { url = "https://files.pythonhosted.org/packages/47/ae/6710c14ecb276031cf10249f6adf5a59e2d3fdb3b5183bd59f70524067ee/ast_serialize-0.6.0-cp39-abi3-win_amd64.whl", hash = "sha256:113b58346f9ceb664352032770caca817d4a3c86f611c6088e6ef65ddaa70f0e", size = 1101444, upload-time = "2026-06-30T20:02:52.554Z" }, + { url = "https://files.pythonhosted.org/packages/66/40/c53deb2cd0c9b0fb636d24d9f40924cf2e65028e6b20b10cd5c1eeb2c730/ast_serialize-0.6.0-cp39-abi3-win_arm64.whl", hash = "sha256:ccd132fe8db56f61fe743b1f644d01b8d65b83248a8da506f3132bda86d6ed5e", size = 1072965, upload-time = "2026-06-30T20:02:54.097Z" }, ] [[package]] @@ -636,62 +639,62 @@ toml = [ [[package]] name = "cryptography" -version = "48.0.0" +version = "47.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/a9/db8f313fdcd85d767d4973515e1db101f9c71f95fced83233de224673757/cryptography-48.0.0.tar.gz", hash = "sha256:5c3932f4436d1cccb036cb0eaef46e6e2db91035166f1ad6505c3c9d5a635920", size = 832984, upload-time = "2026-05-04T22:59:38.133Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/df/3d/01f6dd9190170a5a241e0e98c2d04be3664a9e6f5b9b872cde63aff1c3dd/cryptography-48.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:0c558d2cdffd8f4bbb30fc7134c74d2ca9a476f830bb053074498fbc86f41ed6", size = 8001587, upload-time = "2026-05-04T22:57:36.803Z" }, - { url = "https://files.pythonhosted.org/packages/b2/6e/e90527eef33f309beb811cf7c982c3aeffcce8e3edb178baa4ca3ae4a6fa/cryptography-48.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f5333311663ea94f75dd408665686aaf426563556bb5283554a3539177e03b8c", size = 4690433, upload-time = "2026-05-04T22:57:40.373Z" }, - { url = "https://files.pythonhosted.org/packages/90/04/673510ed51ddff56575f306cf1617d80411ee76831ccd3097599140efdfe/cryptography-48.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7995ef305d7165c3f11ae07f2517e5a4f1d5c18da1376a0a9ed496336b69e5f3", size = 4710620, upload-time = "2026-05-04T22:57:42.935Z" }, - { url = "https://files.pythonhosted.org/packages/14/d5/e9c4ef932c8d800490c34d8bd589d64a31d5890e27ec9e9ad532be893294/cryptography-48.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:40ba1f85eaa6959837b1d51c9767e230e14612eea4ef110ee8854ada22da1bf5", size = 4696283, upload-time = "2026-05-04T22:57:45.294Z" }, - { url = "https://files.pythonhosted.org/packages/0c/29/174b9dfb60b12d59ecfc6cfa04bc88c21b42a54f01b8aae09bb6e51e4c7f/cryptography-48.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:369a6348999f94bbd53435c894377b20ab95f25a9065c283570e70150d8abc3c", size = 5296573, upload-time = "2026-05-04T22:57:47.933Z" }, - { url = "https://files.pythonhosted.org/packages/95/38/0d29a6fd7d0d1373f0c0c88a04ba20e359b257753ac497564cd660fc1d55/cryptography-48.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a0e692c683f4df67815a2d258b324e66f4738bd7a96a218c826dce4f4bd05d8f", size = 4743677, upload-time = "2026-05-04T22:57:50.067Z" }, - { url = "https://files.pythonhosted.org/packages/30/be/eef653013d5c63b6a490529e0316f9ac14a37602965d4903efed1399f32b/cryptography-48.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:18349bbc56f4743c8b12dc32e2bccb2cf83ee8b69a3bba74ef8ae857e26b3d25", size = 4330808, upload-time = "2026-05-04T22:57:52.301Z" }, - { url = "https://files.pythonhosted.org/packages/84/9e/500463e87abb7a0a0f9f256ec21123ecde0a7b5541a15e840ea54551fd81/cryptography-48.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:7e8eac43dfca5c4cccc6dad9a80504436fca53bb9bc3100a2386d730fbe6b602", size = 4695941, upload-time = "2026-05-04T22:57:54.603Z" }, - { url = "https://files.pythonhosted.org/packages/e3/dc/7303087450c2ec9e7fbb750e17c2abfbc658f23cbd0e54009509b7cc4091/cryptography-48.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9ccdac7d40688ecb5a3b4a604b8a88c8002e3442d6c60aead1db2a89a041560c", size = 5252579, upload-time = "2026-05-04T22:57:57.207Z" }, - { url = "https://files.pythonhosted.org/packages/d0/c0/7101d3b7215edcdc90c45da544961fd8ed2d6448f77577460fa75a8443f7/cryptography-48.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:bd72e68b06bb1e96913f97dd4901119bc17f39d4586a5adf2d3e47bc2b9d58b5", size = 4743326, upload-time = "2026-05-04T22:57:59.535Z" }, - { url = "https://files.pythonhosted.org/packages/ac/d8/5b833bad13016f562ab9d063d68199a4bd121d18458e439515601d3357ec/cryptography-48.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:59baa2cb386c4f0b9905bd6eb4c2a79a69a128408fd31d32ca4d7102d4156321", size = 4826672, upload-time = "2026-05-04T22:58:01.996Z" }, - { url = "https://files.pythonhosted.org/packages/98/e1/7074eb8bf3c135558c73fc2bcf0f5633f912e6fb87e868a55c454080ef09/cryptography-48.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9249e3cd978541d665967ac2cb2787fd6a62bddf1e75b3e347a594d7dacf4f74", size = 4972574, upload-time = "2026-05-04T22:58:03.968Z" }, - { url = "https://files.pythonhosted.org/packages/04/70/e5a1b41d325f797f39427aa44ef8baf0be500065ab6d8e10369d850d4a4f/cryptography-48.0.0-cp311-abi3-win32.whl", hash = "sha256:9c459db21422be75e2809370b829a87eb37f74cd785fc4aa9ea1e5f43b47cda4", size = 3294868, upload-time = "2026-05-04T22:58:06.467Z" }, - { url = "https://files.pythonhosted.org/packages/f4/ac/8ac51b4a5fc5932eb7ee5c517ba7dc8cd834f0048962b6b352f00f41ebf9/cryptography-48.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:5b012212e08b8dd5edc78ef54da83dd9892fd9105323b3993eff6bea65dc21d7", size = 3817107, upload-time = "2026-05-04T22:58:08.845Z" }, - { url = "https://files.pythonhosted.org/packages/6b/84/70e3feea9feea87fd7cbe77efb2712ae1e3e6edf10749dc6e95f4e60e455/cryptography-48.0.0-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:3cb07a3ed6431663cd321ea8a000a1314c74211f823e4177fefa2255e057d1ec", size = 7986556, upload-time = "2026-05-04T22:58:11.172Z" }, - { url = "https://files.pythonhosted.org/packages/89/6e/18e07a618bb5442ba10cf4df16e99c071365528aa570dfcb8c02e25a303b/cryptography-48.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8c7378637d7d88016fa6791c159f698b3d3eed28ebf844ac36b9dc04a14dae18", size = 4684776, upload-time = "2026-05-04T22:58:13.712Z" }, - { url = "https://files.pythonhosted.org/packages/be/6a/4ea3b4c6c6759794d5ee2103c304a5076dc4b19ae1f9fe47dba439e159e9/cryptography-48.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc90c0b39b2e3c65ef52c804b72e3c58f8a04ab2a1871272798e5f9572c17d20", size = 4698121, upload-time = "2026-05-04T22:58:16.448Z" }, - { url = "https://files.pythonhosted.org/packages/2f/59/6ff6ad6cae03bb887da2a5860b2c9805f8dac969ef01ce563336c49bd1d1/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:76341972e1eff8b4bea859f09c0d3e64b96ce931b084f9b9b7db8ef364c30eff", size = 4690042, upload-time = "2026-05-04T22:58:18.544Z" }, - { url = "https://files.pythonhosted.org/packages/ca/b4/fc334ed8cfd705aca282fe4d8f5ae64a8e0f74932e9feecb344610cf6e4d/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:55b7718303bf06a5753dcdccf2f3945cf18ad7bffde41b61226e4db31ab89a9c", size = 5282526, upload-time = "2026-05-04T22:58:20.75Z" }, - { url = "https://files.pythonhosted.org/packages/11/08/9f8c5386cc4cd90d8255c7cdd0f5baf459a08502a09de30dc51f553d38dc/cryptography-48.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:a64697c641c7b1b2178e573cbc31c7c6684cd56883a478d75143dbb7118036db", size = 4733116, upload-time = "2026-05-04T22:58:23.627Z" }, - { url = "https://files.pythonhosted.org/packages/b8/77/99307d7574045699f8805aa500fa0fb83422d115b5400a064ddd306d7750/cryptography-48.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:561215ea3879cb1cbbf272867e2efda62476f240fb58c64de6b393ae19246741", size = 4316030, upload-time = "2026-05-04T22:58:25.581Z" }, - { url = "https://files.pythonhosted.org/packages/fd/36/a608b98337af3cb2aff4818e406649d30572b7031918b04c87d979495348/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:ad64688338ed4bc1a6618076ba75fd7194a5f1797ac60b47afe926285adb3166", size = 4689640, upload-time = "2026-05-04T22:58:27.747Z" }, - { url = "https://files.pythonhosted.org/packages/dd/a6/825010a291b4438aecc1f568bc428189fc1175515223632477c07dc0a6df/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:906cbf0670286c6e0044156bc7d4af9cbb0ef6db9f73e52c3ec56ba6bdde5336", size = 5237657, upload-time = "2026-05-04T22:58:29.848Z" }, - { url = "https://files.pythonhosted.org/packages/b9/09/4e76a09b4caa29aad535ddc806f5d4c5d01885bd978bd984fbc6ca032cae/cryptography-48.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:ea8990436d914540a40ab24b6a77c0969695ed52f4a4874c5137ccf7045a7057", size = 4732362, upload-time = "2026-05-04T22:58:32.009Z" }, - { url = "https://files.pythonhosted.org/packages/18/78/444fa04a77d0cb95f417dda20d450e13c56ba8e5220fc892a1658f44f882/cryptography-48.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c18684a7f0cc9a3cb60328f496b8e3372def7c5d2df39ac267878b05565aaaae", size = 4819580, upload-time = "2026-05-04T22:58:34.254Z" }, - { url = "https://files.pythonhosted.org/packages/38/85/ea67067c70a1fd4be2c63d35eeed82658023021affccc7b17705f8527dd2/cryptography-48.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9be5aafa5736574f8f15f262adc81b2a9869e2cfe9014d52a44633905b40d52c", size = 4963283, upload-time = "2026-05-04T22:58:36.376Z" }, - { url = "https://files.pythonhosted.org/packages/75/54/cc6d0f3deac3e81c7f847e8a189a12b6cdd65059b43dad25d4316abd849a/cryptography-48.0.0-cp314-cp314t-win32.whl", hash = "sha256:c17dfe85494deaeddc5ce251aebd1d60bbe6afc8b62071bb0b469431a000124f", size = 3270954, upload-time = "2026-05-04T22:58:38.791Z" }, - { url = "https://files.pythonhosted.org/packages/49/67/cc947e288c0758a4e5473d1dcb743037ab7785541265a969240b8885441a/cryptography-48.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27241b1dc9962e056062a8eef1991d02c3a24569c95975bd2322a8a52c6e5e12", size = 3797313, upload-time = "2026-05-04T22:58:40.746Z" }, - { url = "https://files.pythonhosted.org/packages/f2/63/61d4a4e1c6b6bab6ce1e213cd36a24c415d90e76d78c5eb8577c5541d2e8/cryptography-48.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:58d00498e8933e4a194f3076aee1b4a97dfec1a6da444535755822fe5d8b0b86", size = 7983482, upload-time = "2026-05-04T22:58:43.769Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ac/f5b5995b87770c693e2596559ffafe195b4033a57f14a82268a2842953f3/cryptography-48.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:614d0949f4790582d2cc25553abd09dd723025f0c0e7c67376a1d77196743d6e", size = 4683266, upload-time = "2026-05-04T22:58:46.064Z" }, - { url = "https://files.pythonhosted.org/packages/ec/c6/8b14f67e18338fbc4adb76f66c001f5c3610b3e2d1837f268f47a347dbbb/cryptography-48.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ce4bfae76319a532a2dc68f82cc32f5676ee792a983187dac07183690e5c66f", size = 4696228, upload-time = "2026-05-04T22:58:48.22Z" }, - { url = "https://files.pythonhosted.org/packages/ea/73/f808fbae9514bd91b47875b003f13e284c8c6bdfd904b7944e803937eec1/cryptography-48.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:2eb992bbd4661238c5a397594c83f5b4dc2bc5b848c365c8f991b6780efcc5c7", size = 4689097, upload-time = "2026-05-04T22:58:50.9Z" }, - { url = "https://files.pythonhosted.org/packages/93/01/d86632d7d28db8ae83221995752eeb6639ffb374c2d22955648cf8d52797/cryptography-48.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:22a5cb272895dce158b2cacdfdc3debd299019659f42947dbdac6f32d68fe832", size = 5283582, upload-time = "2026-05-04T22:58:53.017Z" }, - { url = "https://files.pythonhosted.org/packages/02/e1/50edc7a50334807cc4791fc4a0ce7468b4a1416d9138eab358bfc9a3d70b/cryptography-48.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2b4d59804e8408e2fea7d1fbaf218e5ec984325221db76e6a241a9abd6cdd95c", size = 4730479, upload-time = "2026-05-04T22:58:55.611Z" }, - { url = "https://files.pythonhosted.org/packages/6f/af/99a582b1b1641ff5911ac559beb45097cf79efd4ead4657f578ef1af2d47/cryptography-48.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:984a20b0f62a26f48a3396c72e4bc34c66e356d356bf370053066b3b6d54634a", size = 4326481, upload-time = "2026-05-04T22:58:57.607Z" }, - { url = "https://files.pythonhosted.org/packages/90/ee/89aa26a06ef0a7d7611788ffd571a7c50e368cc6a4d5eef8b4884e866edb/cryptography-48.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:5a5ed8fde7a1d09376ca0b40e68cd59c69fe23b1f9768bd5824f54681626032a", size = 4688713, upload-time = "2026-05-04T22:59:00.077Z" }, - { url = "https://files.pythonhosted.org/packages/70/ba/bcb1b0bb7a33d4c7c0c4d4c7874b4a62ae4f56113a5f4baefa362dfb1f0f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:8cd666227ef7af430aa5914a9910e0ddd703e75f039cef0825cd0da71b6b711a", size = 5238165, upload-time = "2026-05-04T22:59:02.317Z" }, - { url = "https://files.pythonhosted.org/packages/c9/70/ca4003b1ce5ca3dc3186ada51908c8a9b9ff7d5cab83cc0d43ee14ec144f/cryptography-48.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9071196d81abc88b3516ac8cdfad32e2b66dd4a5393a8e68a961e9161ddc6239", size = 4729947, upload-time = "2026-05-04T22:59:05.255Z" }, - { url = "https://files.pythonhosted.org/packages/44/a0/4ec7cf774207905aef1a8d11c3750d5a1db805eb380ee4e16df317870128/cryptography-48.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1e2d54c8be6152856a36f0882ab231e70f8ec7f14e93cf87db8a2ed056bf160c", size = 4822059, upload-time = "2026-05-04T22:59:07.802Z" }, - { url = "https://files.pythonhosted.org/packages/1e/75/a2e55f99c16fcac7b5d6c1eb19ad8e00799854d6be5ca845f9259eae1681/cryptography-48.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a5da777e32ffed6f85a7b2b3f7c5cbc88c146bfcd0a1d7baf5fcc6c52ee35dd4", size = 4960575, upload-time = "2026-05-04T22:59:09.851Z" }, - { url = "https://files.pythonhosted.org/packages/b8/23/6e6f32143ab5d8b36ca848a502c4bcd477ae75b9e1677e3530d669062578/cryptography-48.0.0-cp39-abi3-win32.whl", hash = "sha256:77a2ccbbe917f6710e05ba9adaa25fb5075620bf3ea6fb751997875aff4ae4bd", size = 3279117, upload-time = "2026-05-04T22:59:12.019Z" }, - { url = "https://files.pythonhosted.org/packages/9d/9a/0fea98a70cf1749d41d738836f6349d97945f7c89433a259a6c2642eefeb/cryptography-48.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:16cd65b9330583e4619939b3a3843eec1e6e789744bb01e7c7e2e62e33c239c8", size = 3792100, upload-time = "2026-05-04T22:59:14.884Z" }, - { url = "https://files.pythonhosted.org/packages/be/d2/024b5e06be9d44cb021fb0e1a03d34d63989cf56a0fe62f3dfbab695b9b4/cryptography-48.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:84cf79f0dc8b36ac5da873481716e87aef31fcfa0444f9e1d8b4b2cece142855", size = 3950391, upload-time = "2026-05-04T22:59:17.415Z" }, - { url = "https://files.pythonhosted.org/packages/bc/17/3861e17c56fa0fd37491a14a8673fdb77c57fc5693cafe745ea8b06dba75/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:fdfef35d751d510fcef5252703621574364fec16418c4a1e5e1055248401054b", size = 4637126, upload-time = "2026-05-04T22:59:20.197Z" }, - { url = "https://files.pythonhosted.org/packages/f0/0a/7e226dbff530f21480727eb764973a7bff2b912f8e15cd4f129e71b56d1d/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0890f502ddf7d9c6426129c3f49f5c0a39278ed7cd6322c8755ffca6ee675a13", size = 4667270, upload-time = "2026-05-04T22:59:22.647Z" }, - { url = "https://files.pythonhosted.org/packages/3b/f2/5a72274ca9f1b2a8b44a662ee0bf1b435909deb473d6f97bcd035bcdbc71/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:ecde28a596bead48b0cfd2a1b4416c3d43074c2d785e3a398d7ec1fc4d0f7fbb", size = 4636797, upload-time = "2026-05-04T22:59:24.912Z" }, - { url = "https://files.pythonhosted.org/packages/b4/e1/48cedb2fe63626e91ded1edad159e2a4fb8b6906c4425eb7749673077ce7/cryptography-48.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:4defde8685ae324a9eb9d818717e93b4638ef67070ac9bc15b8ca85f63048355", size = 4666800, upload-time = "2026-05-04T22:59:27.474Z" }, - { url = "https://files.pythonhosted.org/packages/a2/ca/7e8365deec19afb2b2c7be7c1c0aa8f99633b54e90c570999acda93260fc/cryptography-48.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:db63bf618e5dea46c07de12e900fe1cdd2541e6dc9dbae772a70b7d4d4765f6a", size = 3739536, upload-time = "2026-05-04T22:59:29.61Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/ef/b2/7ffa7fe8207a8c42147ffe70c3e360b228160c1d85dc3faff16aaa3244c0/cryptography-47.0.0.tar.gz", hash = "sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb", size = 830863, upload-time = "2026-04-24T19:54:57.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/98/40dfe932134bdcae4f6ab5927c87488754bf9eb79297d7e0070b78dd58e9/cryptography-47.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0", size = 7912214, upload-time = "2026-04-24T19:53:03.864Z" }, + { url = "https://files.pythonhosted.org/packages/34/c6/2733531243fba725f58611b918056b277692f1033373dcc8bd01af1c05d4/cryptography-47.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973", size = 4644617, upload-time = "2026-04-24T19:53:06.909Z" }, + { url = "https://files.pythonhosted.org/packages/00/e3/b27be1a670a9b87f855d211cf0e1174a5d721216b7616bd52d8581d912ed/cryptography-47.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8", size = 4668186, upload-time = "2026-04-24T19:53:09.053Z" }, + { url = "https://files.pythonhosted.org/packages/81/b9/8443cfe5d17d482d348cee7048acf502bb89a51b6382f06240fd290d4ca3/cryptography-47.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b", size = 4651244, upload-time = "2026-04-24T19:53:11.217Z" }, + { url = "https://files.pythonhosted.org/packages/5d/5e/13ed0cdd0eb88ba159d6dd5ebfece8cb901dbcf1ae5ac4072e28b55d3153/cryptography-47.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92", size = 5252906, upload-time = "2026-04-24T19:53:13.532Z" }, + { url = "https://files.pythonhosted.org/packages/64/16/ed058e1df0f33d440217cd120d41d5dda9dd215a80b8187f68483185af82/cryptography-47.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7", size = 4701842, upload-time = "2026-04-24T19:53:15.618Z" }, + { url = "https://files.pythonhosted.org/packages/02/e0/3d30986b30fdbd9e969abbdf8ba00ed0618615144341faeb57f395a084fe/cryptography-47.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93", size = 4289313, upload-time = "2026-04-24T19:53:17.755Z" }, + { url = "https://files.pythonhosted.org/packages/df/fd/32db38e3ad0cb331f0691cb4c7a8a6f176f679124dee746b3af6633db4d9/cryptography-47.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac", size = 4650964, upload-time = "2026-04-24T19:53:20.062Z" }, + { url = "https://files.pythonhosted.org/packages/86/53/5395d944dfd48cb1f67917f533c609c34347185ef15eb4308024c876f274/cryptography-47.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f", size = 5207817, upload-time = "2026-04-24T19:53:22.498Z" }, + { url = "https://files.pythonhosted.org/packages/34/4f/e5711b28e1901f7d480a2b1b688b645aa4c77c73f10731ed17e7f7db3f0d/cryptography-47.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8", size = 4701544, upload-time = "2026-04-24T19:53:24.356Z" }, + { url = "https://files.pythonhosted.org/packages/22/22/c8ddc25de3010fc8da447648f5a092c40e7a8fadf01dd6d255d9c0b9373d/cryptography-47.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318", size = 4783536, upload-time = "2026-04-24T19:53:26.665Z" }, + { url = "https://files.pythonhosted.org/packages/66/b6/d4a68f4ea999c6d89e8498579cba1c5fcba4276284de7773b17e4fa69293/cryptography-47.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001", size = 4926106, upload-time = "2026-04-24T19:53:28.686Z" }, + { url = "https://files.pythonhosted.org/packages/54/ed/5f524db1fade9c013aa618e1c99c6ed05e8ffc9ceee6cda22fed22dda3f4/cryptography-47.0.0-cp311-abi3-win32.whl", hash = "sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203", size = 3258581, upload-time = "2026-04-24T19:53:31.058Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dc/1b901990b174786569029f67542b3edf72ac068b6c3c8683c17e6a2f5363/cryptography-47.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa", size = 3775309, upload-time = "2026-04-24T19:53:33.054Z" }, + { url = "https://files.pythonhosted.org/packages/14/88/7aa18ad9c11bc87689affa5ce4368d884b517502d75739d475fc6f4a03c7/cryptography-47.0.0-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0", size = 7904299, upload-time = "2026-04-24T19:53:35.003Z" }, + { url = "https://files.pythonhosted.org/packages/07/55/c18f75724544872f234678fdedc871391722cb34a2aee19faa9f63100bb2/cryptography-47.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7", size = 4631180, upload-time = "2026-04-24T19:53:37.517Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/31a5cc0eaca99cec5bafffe155d407115d96136bb161e8b49e0ef73f09a7/cryptography-47.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1", size = 4653529, upload-time = "2026-04-24T19:53:39.775Z" }, + { url = "https://files.pythonhosted.org/packages/e5/bc/641c0519a495f3bfd0421b48d7cd325c4336578523ccd76ea322b6c29c7a/cryptography-47.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c", size = 4638570, upload-time = "2026-04-24T19:53:42.129Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f2/300327b0a47f6dc94dd8b71b57052aefe178bb51745073d73d80604f11ab/cryptography-47.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829", size = 5238019, upload-time = "2026-04-24T19:53:44.577Z" }, + { url = "https://files.pythonhosted.org/packages/e9/5a/5b5cf994391d4bf9d9c7efd4c66aabe4d95227256627f8fea6cff7dfadbd/cryptography-47.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7", size = 4686832, upload-time = "2026-04-24T19:53:47.015Z" }, + { url = "https://files.pythonhosted.org/packages/dc/2c/ae950e28fd6475c852fc21a44db3e6b5bcc1261d1e370f2b6e42fa800fef/cryptography-47.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923", size = 4269301, upload-time = "2026-04-24T19:53:48.97Z" }, + { url = "https://files.pythonhosted.org/packages/67/fb/6a39782e150ffe5cc1b0018cb6ddc48bf7ca62b498d7539ffc8a758e977d/cryptography-47.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab", size = 4638110, upload-time = "2026-04-24T19:53:51.011Z" }, + { url = "https://files.pythonhosted.org/packages/8e/d7/0b3c71090a76e5c203164a47688b697635ece006dcd2499ab3a4dbd3f0bd/cryptography-47.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736", size = 5194988, upload-time = "2026-04-24T19:53:52.962Z" }, + { url = "https://files.pythonhosted.org/packages/63/33/63a961498a9df51721ab578c5a2622661411fc520e00bd83b0cc64eb20c4/cryptography-47.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7", size = 4686563, upload-time = "2026-04-24T19:53:55.274Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bf/5ee5b145248f92250de86145d1c1d6edebbd57a7fe7caa4dedb5d4cf06a1/cryptography-47.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52", size = 4770094, upload-time = "2026-04-24T19:53:57.753Z" }, + { url = "https://files.pythonhosted.org/packages/92/43/21d220b2da5d517773894dacdcdb5c682c28d3fffce65548cb06e87d5501/cryptography-47.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd", size = 4913811, upload-time = "2026-04-24T19:54:00.236Z" }, + { url = "https://files.pythonhosted.org/packages/31/98/dc4ad376ac5f1a1a7d4a83f7b0c6f2bcad36b5d2d8f30aeb482d3a7d9582/cryptography-47.0.0-cp314-cp314t-win32.whl", hash = "sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63", size = 3237158, upload-time = "2026-04-24T19:54:02.606Z" }, + { url = "https://files.pythonhosted.org/packages/bc/da/97f62d18306b5133468bc3f8cc73a3111e8cdc8cf8d3e69474d6e5fd2d1b/cryptography-47.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b", size = 3758706, upload-time = "2026-04-24T19:54:04.433Z" }, + { url = "https://files.pythonhosted.org/packages/e0/34/a4fae8ae7c3bc227460c9ae43f56abf1b911da0ec29e0ebac53bb0a4b6b7/cryptography-47.0.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4", size = 7904072, upload-time = "2026-04-24T19:54:06.411Z" }, + { url = "https://files.pythonhosted.org/packages/01/64/d7b1e54fdb69f22d24a64bb3e88dc718b31c7fb10ef0b9691a3cf7eeea6e/cryptography-47.0.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27", size = 4635767, upload-time = "2026-04-24T19:54:08.519Z" }, + { url = "https://files.pythonhosted.org/packages/8b/7b/cca826391fb2a94efdcdfe4631eb69306ee1cff0b22f664a412c90713877/cryptography-47.0.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10", size = 4654350, upload-time = "2026-04-24T19:54:10.795Z" }, + { url = "https://files.pythonhosted.org/packages/4c/65/4b57bcc823f42a991627c51c2f68c9fd6eb1393c1756aac876cba2accae2/cryptography-47.0.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b", size = 4643394, upload-time = "2026-04-24T19:54:13.275Z" }, + { url = "https://files.pythonhosted.org/packages/f4/c4/2c5fbeea70adbbca2bbae865e1d605d6a4a7f8dbd9d33eaf69645087f06c/cryptography-47.0.0-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74", size = 5225777, upload-time = "2026-04-24T19:54:15.18Z" }, + { url = "https://files.pythonhosted.org/packages/7e/b8/ac57107ef32749d2b244e36069bb688792a363aaaa3acc9e3cf84c130315/cryptography-47.0.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515", size = 4688771, upload-time = "2026-04-24T19:54:17.835Z" }, + { url = "https://files.pythonhosted.org/packages/56/fc/9f1de22ff8be99d991f240a46863c52d475404c408886c5a38d2b5c3bb26/cryptography-47.0.0-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc", size = 4270753, upload-time = "2026-04-24T19:54:19.963Z" }, + { url = "https://files.pythonhosted.org/packages/00/68/d70c852797aa68e8e48d12e5a87170c43f67bb4a59403627259dd57d15de/cryptography-47.0.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca", size = 4642911, upload-time = "2026-04-24T19:54:21.818Z" }, + { url = "https://files.pythonhosted.org/packages/a5/51/661cbee74f594c5d97ff82d34f10d5551c085ca4668645f4606ebd22bd5d/cryptography-47.0.0-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76", size = 5181411, upload-time = "2026-04-24T19:54:24.376Z" }, + { url = "https://files.pythonhosted.org/packages/94/87/f2b6c374a82cf076cfa1416992ac8e8ec94d79facc37aec87c1a5cb72352/cryptography-47.0.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe", size = 4688262, upload-time = "2026-04-24T19:54:26.946Z" }, + { url = "https://files.pythonhosted.org/packages/14/e2/8b7462f4acf21ec509616f0245018bb197194ab0b65c2ea21a0bdd53c0eb/cryptography-47.0.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31", size = 4775506, upload-time = "2026-04-24T19:54:28.926Z" }, + { url = "https://files.pythonhosted.org/packages/70/75/158e494e4c08dc05e039da5bb48553826bd26c23930cf8d3cd5f21fa8921/cryptography-47.0.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7", size = 4912060, upload-time = "2026-04-24T19:54:30.869Z" }, + { url = "https://files.pythonhosted.org/packages/06/bd/0a9d3edbf5eadbac926d7b9b3cd0c4be584eeeae4a003d24d9eda4affbbd/cryptography-47.0.0-cp38-abi3-win32.whl", hash = "sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310", size = 3248487, upload-time = "2026-04-24T19:54:33.494Z" }, + { url = "https://files.pythonhosted.org/packages/60/80/5681af756d0da3a599b7bdb586fac5a1540f1bcefd2717a20e611ddade45/cryptography-47.0.0-cp38-abi3-win_amd64.whl", hash = "sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769", size = 3755737, upload-time = "2026-04-24T19:54:35.408Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a0/928c9ce0d120a40a81aa99e3ba383e87337b9ac9ef9f6db02e4d7822424d/cryptography-47.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7", size = 3909893, upload-time = "2026-04-24T19:54:38.334Z" }, + { url = "https://files.pythonhosted.org/packages/81/75/d691e284750df5d9569f2b1ce4a00a71e1d79566da83b2b3e5549c84917f/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe", size = 4587867, upload-time = "2026-04-24T19:54:40.619Z" }, + { url = "https://files.pythonhosted.org/packages/07/d6/1b90f1a4e453009730b4545286f0b39bb348d805c11181fc31544e4f9a65/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475", size = 4627192, upload-time = "2026-04-24T19:54:42.849Z" }, + { url = "https://files.pythonhosted.org/packages/dc/53/cb358a80e9e359529f496870dd08c102aa8a4b5b9f9064f00f0d6ed5b527/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50", size = 4587486, upload-time = "2026-04-24T19:54:44.908Z" }, + { url = "https://files.pythonhosted.org/packages/8b/57/aaa3d53876467a226f9a7a82fd14dd48058ad2de1948493442dfa16e2ffd/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab", size = 4626327, upload-time = "2026-04-24T19:54:47.813Z" }, + { url = "https://files.pythonhosted.org/packages/ab/9c/51f28c3550276bcf35660703ba0ab829a90b88be8cd98a71ef23c2413913/cryptography-47.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8", size = 3698916, upload-time = "2026-04-24T19:54:49.782Z" }, ] [[package]] @@ -741,7 +744,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -901,14 +904,14 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.50" +version = "3.1.49" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/f6/354ae6491228b5eb40e10d89c4d13c651fe1cf7556e35ebdded50cff57ce/gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc", size = 219798, upload-time = "2026-05-06T04:01:26.571Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/63/210aaa302d6a0a78daa67c5c15bbac2cad361722841278b0209b6da20855/gitpython-3.1.49.tar.gz", hash = "sha256:42f9399c9eb33fc581014bedd76049dfbaf6375aa2a5754575966387280315e1", size = 219367, upload-time = "2026-04-29T00:31:20.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9", size = 212507, upload-time = "2026-05-06T04:01:23.799Z" }, + { url = "https://files.pythonhosted.org/packages/fd/6f/b842bfa6f21d6f87c57f9abf7194225e55279d96d869775e19e9f7236fc5/gitpython-3.1.49-py3-none-any.whl", hash = "sha256:024b0422d7f84d15cd794844e029ffebd4c5d42a7eb9b936b458697ef550a02c", size = 212190, upload-time = "2026-04-29T00:31:18.412Z" }, ] [[package]] @@ -1041,87 +1044,89 @@ wheels = [ [[package]] name = "librt" -version = "0.10.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/39/cb/c1945e506893b5b8577fb45a60c80e3ffe4a82092a04a6f29b0b951d9a24/librt-0.10.0.tar.gz", hash = "sha256:1aba1e8aa4e3307a7be68a74149545fde7451964dc0235a8bec5704a17bdda42", size = 191799, upload-time = "2026-05-05T16:31:23.535Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/18/827e5c1262a88c2602e86f99aee0f288ffea3280dbd2ff448858ef9dc6e9/librt-0.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7dc99f9642100b86e5f6bb14cdc9970009e31a9ef7d64df6704b7018451524a3", size = 76461, upload-time = "2026-05-05T16:29:00.422Z" }, - { url = "https://files.pythonhosted.org/packages/ee/90/54254e30287f5a5abec6fef22d976987476e966be5fdff51fe8c2d5d73d1/librt-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8298cedfcfaff3790000bd057aaaa3df1b0ab54cf7b48eeab16184cbb1bc66b9", size = 79740, upload-time = "2026-05-05T16:29:01.926Z" }, - { url = "https://files.pythonhosted.org/packages/4c/20/e93264b52113669d98d3b63ff94d4ce0c4dd49ae0503f1788440a884e5f0/librt-0.10.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee7dbe312dbf76468255b79a7ba311236fde620f2f7055fc09d421e31340314e", size = 243472, upload-time = "2026-05-05T16:29:03.373Z" }, - { url = "https://files.pythonhosted.org/packages/35/ad/34a5141178e8b18a4cfa45d1a0d523c84397e2abd5d06fea2d846da687e8/librt-0.10.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:56ed90c48c19249012dadfd79a1bc13bd5168ea60a70722d330a3a600c0b1852", size = 232073, upload-time = "2026-05-05T16:29:04.815Z" }, - { url = "https://files.pythonhosted.org/packages/97/1f/67240e910cd9f9ab1498c1470738345fc29dce5dc9719db1e0e09d1e861f/librt-0.10.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d74ca0f4b2b09c117f913d4df01f6b934dff8a271096b35167d5264a31649f0", size = 256956, upload-time = "2026-05-05T16:29:06.516Z" }, - { url = "https://files.pythonhosted.org/packages/22/50/3a2b3482c27d607f6e8216d913c6bc592b9a2141d96990309452340a78e3/librt-0.10.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8eb2daa9375f93c0e55ff5e44a4bbe98f39e5fe52e1abf9c97acb67743b61bf8", size = 250593, upload-time = "2026-05-05T16:29:08.324Z" }, - { url = "https://files.pythonhosted.org/packages/e7/1c/07dba133d79f93322fa17514062f1a2a50d6bdfb7baec4acf78193d7fad1/librt-0.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7b09b90e634e6dff57978cd358070046071e2b120501f10787aeb35425f504f6", size = 263582, upload-time = "2026-05-05T16:29:09.866Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ac/033f2c6d6ab0b48f15f02e5bf065521b11a51922806017f8b6274df30d69/librt-0.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2cf22fd379d60c739b800d4295ed34045f8b04aa8df9c12bd2f8f43f7fe672b7", size = 259307, upload-time = "2026-05-05T16:29:11.675Z" }, - { url = "https://files.pythonhosted.org/packages/6e/10/679046cd75d5a52c0104c890d8f69574ef4e619c683e59c15584d03a2457/librt-0.10.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:74c798793fcf29a84d442278ebe0bb1fff79fe58ac4106eeff7019cbba861423", size = 257342, upload-time = "2026-05-05T16:29:13.14Z" }, - { url = "https://files.pythonhosted.org/packages/1e/d5/dbaac9c0884f78a53dda22b9ec92bb788e1400e762ed7623fa96928c8da5/librt-0.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dc4f1573401e8dbe6c26511fe027620b0fb30ae9a7ab814e02e510626b8b5f9c", size = 280141, upload-time = "2026-05-05T16:29:14.922Z" }, - { url = "https://files.pythonhosted.org/packages/cc/81/71f18cf8eb340d9fda011498870910f6a8697aeb50833005d3d8107653fd/librt-0.10.0-cp310-cp310-win32.whl", hash = "sha256:e1428275f5fe3d4db6822e58d8b005a5b28ffca55e8433ebc051247fbe46429f", size = 62257, upload-time = "2026-05-05T16:29:16.226Z" }, - { url = "https://files.pythonhosted.org/packages/df/52/6bcebc2f870c4836bcb372be885fae7f17a1d25037d3a8250ef79fbe0124/librt-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:0708e9408f585b0f065081680583a577652099680ccf820c7538904322b679c3", size = 70321, upload-time = "2026-05-05T16:29:17.41Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a3/1472717d2325adacc8d335ba2e4078015c09d75b599f3cf48e967b3d306e/librt-0.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01b4500ca3a625450c032a9142a8e843923ce263fa8a92ad1b38927cabe2fe72", size = 76045, upload-time = "2026-05-05T16:29:18.731Z" }, - { url = "https://files.pythonhosted.org/packages/a6/31/bfe32355d4b369aef3d7aa442df663bb5558c2ffa2de286cb2956346bc24/librt-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b7e42d1b3e300d20bfc87e72ffd62f0a92a2cb3c35f7bf90df90c9d2a49f74c", size = 79466, upload-time = "2026-05-05T16:29:20.052Z" }, - { url = "https://files.pythonhosted.org/packages/e9/f1/83f8a2c715ba2cac9b7387a5a5cea25f717f7184320cfe48b36bed9c58e9/librt-0.10.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8ef7b8c61ce3a1b597cd3e15348ff1574325165c2e7ce09a718154cde2a7950", size = 242283, upload-time = "2026-05-05T16:29:21.596Z" }, - { url = "https://files.pythonhosted.org/packages/cc/94/c3a4ce94857f0004a542f86662806383611858f522722db58efaec0a1472/librt-0.10.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:e73c84f72d1fa0d6eaa7a1930b436ba8d2c90c58d77bfabb09995a69ad35f6c0", size = 230735, upload-time = "2026-05-05T16:29:23.335Z" }, - { url = "https://files.pythonhosted.org/packages/d1/41/e962bb26c7728eb7b3a69e490d0c800fd9968a6970e390c1f18ddb56093d/librt-0.10.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9728cb98713bd862fb8f4fd6a642d1896c86058a41d77c70f3d5cee75e725275", size = 256606, upload-time = "2026-05-05T16:29:24.91Z" }, - { url = "https://files.pythonhosted.org/packages/66/3a/4e46a707b1ecc993fd691071623b9beab89703a63bd21cc7807e06c28209/librt-0.10.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:648b7e941d20acd72f9652115e0e53facd98156d61f9ebf7a812bdef8bdccea9", size = 249739, upload-time = "2026-05-05T16:29:26.648Z" }, - { url = "https://files.pythonhosted.org/packages/b2/f5/dc5b7eb294656ad23d4ff4cf8514208d54fe1026b909d726a0dc026689c9/librt-0.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c3e33747c068e86a9007c20fdb777eb5ba8d3d19136d7812f88e69a713041b6f", size = 261414, upload-time = "2026-05-05T16:29:28.702Z" }, - { url = "https://files.pythonhosted.org/packages/58/e4/990ed8d12c7f114ac8f8ccd47f7d9bd9704ef61acfcb1df4a05047da7710/librt-0.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d509c745bf7e77d1107cf05e6abb249dc03fad13eb39f2286a49deedaeb2bcd7", size = 256614, upload-time = "2026-05-05T16:29:30.357Z" }, - { url = "https://files.pythonhosted.org/packages/60/eb/52d2726c7fb22818507dc3cc166c8f36dd4a4b68a7be67f12006ac8777c1/librt-0.10.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:786ad5a15e99d0e0e74f3adbeecc198a5ac58f340be07e984723d1e0074838de", size = 255144, upload-time = "2026-05-05T16:29:32.106Z" }, - { url = "https://files.pythonhosted.org/packages/bc/df/bd5591a78f7531fce4b6eb9962aadc6adc9560a01570442a884b6e554abe/librt-0.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:075582d877a97ee3d8e77bda3689dbe617b14f6469224a2d80b4b6c38e3951aa", size = 279121, upload-time = "2026-05-05T16:29:33.688Z" }, - { url = "https://files.pythonhosted.org/packages/fd/df/7c2b838dfc89a1762dd156d8b0c39848a7a2845d725a50be5a6e021fb8ba/librt-0.10.0-cp311-cp311-win32.whl", hash = "sha256:75ecdc3f5a90065aa2af2e574706c5495adc392520762dcf10b1aa716f0b8090", size = 62593, upload-time = "2026-05-05T16:29:35.152Z" }, - { url = "https://files.pythonhosted.org/packages/91/19/22ff572981049a9d436a083dbea1572d0f5dc068b7353637d2dd9977c8f1/librt-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:b6f6084884131d8a52cb9d7095ff2aa52c1e786d9fdaefab1fb4515415e9e083", size = 70914, upload-time = "2026-05-05T16:29:36.407Z" }, - { url = "https://files.pythonhosted.org/packages/12/22/1697cc64f4a5c7e9bce55e99c6d234a346beaedaefcd1e2ca90dd285f98c/librt-0.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:0140bd62151160047e89b2730cb6f8506cdac5127baa1afb9231e4dd3fe7f681", size = 61176, upload-time = "2026-05-05T16:29:37.62Z" }, - { url = "https://files.pythonhosted.org/packages/12/8e/cbb5b6f6e45e65c10a42449a69eaccc44d73e6a081ea752fbc5221c6dc1c/librt-0.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b4b58a44b407e91f633dafee008de9ddea6aa2a555ed94929c099260910bd0ba", size = 77327, upload-time = "2026-05-05T16:29:38.919Z" }, - { url = "https://files.pythonhosted.org/packages/e9/3d/8233cbee8e99e6a8992f02bfc2dec8d787509566a511d1fde2574ee7473f/librt-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:950b79b11762531bdf45a9df909d2f9a2a8445c70c88665c01d14c8511a27dc5", size = 79971, upload-time = "2026-05-05T16:29:40.96Z" }, - { url = "https://files.pythonhosted.org/packages/87/6f/5264b298cef2b72fc97d2dde56c66181eda35204bf5dcd1ed0c3d0a0a782/librt-0.10.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4538453f51be197633b425912c150e25b0667252d3741c53e8368176d98d9d37", size = 246559, upload-time = "2026-05-05T16:29:42.701Z" }, - { url = "https://files.pythonhosted.org/packages/07/7b/19b1b859cc60d5f99276cc2b3144d91556c6d1b1e4ebb50359696bebf7a8/librt-0.10.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:70b955f091beac93e994a0b7ec616934f63b3ea5c3d6d7af847562f935aceca7", size = 235216, upload-time = "2026-05-05T16:29:44.193Z" }, - { url = "https://files.pythonhosted.org/packages/6e/56/a2f40717142a8af46289f57874ef914353d8faccd5e4f8e594ab1e16e8c7/librt-0.10.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:483e685e06b6163728ba6c85d74315176be7190f432ec2a41226e5e14355d5f0", size = 263108, upload-time = "2026-05-05T16:29:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/67/ca/15c625c3bdc0167c01e04ef8878317e9713f3bfa788438342f7a94c7b22c/librt-0.10.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ac53d946a009d1a38c44a60812708c9458fb2a239a5f630d8e625571386650f", size = 255280, upload-time = "2026-05-05T16:29:48.087Z" }, - { url = "https://files.pythonhosted.org/packages/ed/c5/ba301d571d9e05844e2435b73aba30bee77bb75ce155c9affcfd2173dd03/librt-0.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc8771c9fcf0ea894ca41fdc2abd83572c2fbda221f232d86e718614e57ff513", size = 268829, upload-time = "2026-05-05T16:29:49.628Z" }, - { url = "https://files.pythonhosted.org/packages/8b/60/af70e135bc1f1fe15dd3894b1e4bbefc7ecdf911749a925a39eb86ceb2a1/librt-0.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:70805dbc5257892ac572f86290a61e3c8d90224ecce1a8b2d1f7ed51965417f4", size = 262051, upload-time = "2026-05-05T16:29:51.244Z" }, - { url = "https://files.pythonhosted.org/packages/83/c2/c8236eb8b421bac5a172ba208f965abaa89805da2a3fa112bdf1764caf8f/librt-0.10.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d3b4f300f7bcba6e2ff73fb8bef1898479e9772bfa2682998c636391633ec826", size = 264347, upload-time = "2026-05-05T16:29:53.013Z" }, - { url = "https://files.pythonhosted.org/packages/d6/f5/15b6d32bc25dacd4a60886a683d8128d6219910c122202b995a40dd4f8d2/librt-0.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:943bc943f92f4fb3408fae62485c6a3ad68ce4f2ee205643a39641525c19a276", size = 286482, upload-time = "2026-05-05T16:29:54.675Z" }, - { url = "https://files.pythonhosted.org/packages/fb/8e/b1b959bacd323eb4360579db992513e1406d1c6ef7edb57b5511fd0666fd/librt-0.10.0-cp312-cp312-win32.whl", hash = "sha256:6065c1a758fba1010b41401013903d3d5d2750eab425ddedd584abac31d0630e", size = 62955, upload-time = "2026-05-05T16:29:56.39Z" }, - { url = "https://files.pythonhosted.org/packages/9e/4c/d4cd6e4b9fc24098e63cc85537d1b6689682aee96809c38f08072067cc2b/librt-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:d788ecbe208ab352dab0e105cc06057bf9a2fc7e58cabb0d751ad9e30062b9e2", size = 71191, upload-time = "2026-05-05T16:29:57.682Z" }, - { url = "https://files.pythonhosted.org/packages/2b/19/8641da1f63d24b92354a492f893c022d6b3a0df44e70c8eff49364613983/librt-0.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:6003d1f295bdba02656dc81308208fc060d0a51d8c0d0a6db70f7f3c57b9ba0a", size = 61432, upload-time = "2026-05-05T16:29:58.971Z" }, - { url = "https://files.pythonhosted.org/packages/e5/29/681a75c82f4cc90d29e4b257a3299b79fe13fe927a04c57b8109d70b6957/librt-0.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f0ede79d682e73f91c1b599a76d78b7464b9b5d213754cedb13372d9df36e596", size = 77299, upload-time = "2026-05-05T16:30:00.209Z" }, - { url = "https://files.pythonhosted.org/packages/62/24/0c7ca445a55d04be79cac19819437fd094782347fa116f6681844fa6143e/librt-0.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e0ba0b131fdb336c8b9c948e397f4a7e649d0f783b529f07b647bf4961df392e", size = 79930, upload-time = "2026-05-05T16:30:01.555Z" }, - { url = "https://files.pythonhosted.org/packages/fe/1f/1e2b8f6443ef9e9a81e89486ca70e22f3684f93db003ce6eaefc3d0839b9/librt-0.10.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2728117da2afb96fb957768725ee43dc9a2d73b031e02da424b818a3cdd3a275", size = 246195, upload-time = "2026-05-05T16:30:03.261Z" }, - { url = "https://files.pythonhosted.org/packages/74/61/9dc9e03de0439ad84c1c240aac8b747f12c90cb797ea6042f7bdb8d3410f/librt-0.10.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:723ba80594c49cdf0584196fc430752262605dc9449902fc9bd3d9b79976cb77", size = 234951, upload-time = "2026-05-05T16:30:04.881Z" }, - { url = "https://files.pythonhosted.org/packages/55/f4/635223117d7590875bca441275065a3bf491203ad4208bd1cc3ffd90c5a1/librt-0.10.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7292edaaca294a61a978c53a3c7d6130d099b0dfbc8f0a65916cdc6b891b9852", size = 262768, upload-time = "2026-05-05T16:30:06.638Z" }, - { url = "https://files.pythonhosted.org/packages/e5/66/b04152d0cd8b6ca2b428a8bd3230343230c35ed304a932f35b5375f2f828/librt-0.10.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:89fe9d539f2c10a1666633eeeac507ce95dd06d9ecc58de3c6390dba156a3d3a", size = 255075, upload-time = "2026-05-05T16:30:08.216Z" }, - { url = "https://files.pythonhosted.org/packages/35/1e/25bac4c7f2ca36f0e612cade186970683cf79153d96beccc3a11a9e19b97/librt-0.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4efa7b9587503fa5b67f40593302b9c8836d211d222ff9f7cafe67be5f8f0b10", size = 268559, upload-time = "2026-05-05T16:30:10.1Z" }, - { url = "https://files.pythonhosted.org/packages/18/54/4601faab35b6632a13200faa146ca62bfd111ffbe2568be430d65c89493a/librt-0.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:22dc982ef59df0136df36092ccbdbb570ced8aafb33e49585739b2f1de1c13b6", size = 261753, upload-time = "2026-05-05T16:30:11.912Z" }, - { url = "https://files.pythonhosted.org/packages/1b/cf/39f4023509e94fade8b074666fa3292db9cb6b34ea5dcbe7af53df9fca1d/librt-0.10.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:6f2e5f3606253a84cea719c94a3bb1c54487b5d617d0254d46e0920d8a06be3f", size = 264055, upload-time = "2026-05-05T16:30:13.465Z" }, - { url = "https://files.pythonhosted.org/packages/8e/00/40247209fc46a8e308a91412d5206aedf8efb667ee89eb625820106a5c2f/librt-0.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:40884bfaa1e29f6b6a9be255007d8f359bfc9e61d68bdef8ed3158bfcbc95df9", size = 286190, upload-time = "2026-05-05T16:30:15.073Z" }, - { url = "https://files.pythonhosted.org/packages/d8/6e/5566beb94431a985abe1787af5ef86e087750172ff9d0bbf20f93e88132d/librt-0.10.0-cp313-cp313-win32.whl", hash = "sha256:3cd34cd8254eba756660bff6c2da91278248184301054fe3e4feb073bdd49b14", size = 62949, upload-time = "2026-05-05T16:30:16.503Z" }, - { url = "https://files.pythonhosted.org/packages/d0/c2/3ea3301d6c8dff51d39dbe8ed75db3dc92896947d4afb5eeadf821c1e67f/librt-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:7baac5313e2d8dce1386f97777a8d03ab28f5fe1e780b3b9ac2ee7544551fedc", size = 71152, upload-time = "2026-05-05T16:30:17.766Z" }, - { url = "https://files.pythonhosted.org/packages/3c/de/5d49cb92cadcbc77d3abc27b93fd6030ed8437487dde2eae38cab5e6704d/librt-0.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:afc5b4406c8e2515698d922a5c7823a009312835ea58196671fff40e35cb8166", size = 61336, upload-time = "2026-05-05T16:30:19.021Z" }, - { url = "https://files.pythonhosted.org/packages/6a/64/7165e08108cc185a13a9c069f0685e6ef92e70e07fddf7edf5e7348c6316/librt-0.10.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f09588a30e6a22ec624090d72a3ab1a6d4d5485c3ed739603e76aa3c16efa688", size = 76794, upload-time = "2026-05-05T16:30:20.392Z" }, - { url = "https://files.pythonhosted.org/packages/ae/ef/bf8613febf651b90c5222ee79dea5ae58d4cc2b544df69d3033424448934/librt-0.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:131ade118d12bd7a0adc4e655474a553f1b76cf78385868885944d21d51e45e0", size = 79662, upload-time = "2026-05-05T16:30:22.025Z" }, - { url = "https://files.pythonhosted.org/packages/b6/67/9eddd165c1d8397bdf99b38bf12b5a55b3def5035b49eedb49f2775d1430/librt-0.10.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8b9ab28e40d011c373a189eae900c916e66d6fbecf7983e9e4883089ee085ef", size = 242390, upload-time = "2026-05-05T16:30:23.51Z" }, - { url = "https://files.pythonhosted.org/packages/10/d1/d95da80334501866cd37004ab5d7483220d05862fab4b5405394f0264f0d/librt-0.10.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:67c39bb30da73bae1f293d1ed8bc2f8f6642649dd0928d3600aeff3041ac23d6", size = 232603, upload-time = "2026-05-05T16:30:25.198Z" }, - { url = "https://files.pythonhosted.org/packages/0c/fa/e6d64d28718bc1be4e1736fcb037ca1c4dfca927e7167df75a7d5215665e/librt-0.10.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8c3273c6b774614f093c8927c2bf1b077d0fefde988fe98f46a333734e5597ab", size = 259187, upload-time = "2026-05-05T16:30:26.772Z" }, - { url = "https://files.pythonhosted.org/packages/72/3f/3fdb77e7f937dad59cfd76b720be7e7643400ec76b2da35befab8d66ba30/librt-0.10.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9dd7c1b86a4baa583ab5db977484b93a2c474e69e96ef3e9538387ea54229cb9", size = 251846, upload-time = "2026-05-05T16:30:28.56Z" }, - { url = "https://files.pythonhosted.org/packages/18/ca/f4d49133dd86a6f55d79eca30bf412fa722f511a9abe67f62f57aa64e66a/librt-0.10.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a77385c5a202e831149f7ad03be9e67cf80e957e52c614e83dcb822c95222eb8", size = 264936, upload-time = "2026-05-05T16:30:30.491Z" }, - { url = "https://files.pythonhosted.org/packages/de/66/a8df2fbadc1f6c1827a096d11c40175bd526133480bd3bc88ec64a03d257/librt-0.10.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c6a5eafa74b5655bad59886138ed68426f098a6beb8cb95a71f2cc3cd8bb33fe", size = 258699, upload-time = "2026-05-05T16:30:32.002Z" }, - { url = "https://files.pythonhosted.org/packages/bb/73/1e3c83613fe05451bb969e27b68a573d177f08d5f63533cc29fec0989658/librt-0.10.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1fc93d0439204c50ab4d1512611ce2c206f1b369b419f69c7c27c761561e3291", size = 259825, upload-time = "2026-05-05T16:30:35.077Z" }, - { url = "https://files.pythonhosted.org/packages/09/24/5e2f926ee9d3ef348d9339526d7062abb5c44d8419e3179528c01d78c102/librt-0.10.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:79e713c178bc7a744adfbee6b4619a288eecc0c914da2a9313a20255abe2f0cf", size = 282548, upload-time = "2026-05-05T16:30:36.639Z" }, - { url = "https://files.pythonhosted.org/packages/fc/7d/3e89ed6ad0162561fa8bef9df3195e24263104c955713cd0237d3711fad2/librt-0.10.0-cp314-cp314-win32.whl", hash = "sha256:2eba9d955a68c41d9f326be3da42f163ec3518b7ab20f1c826224e7bed71e0bf", size = 58970, upload-time = "2026-05-05T16:30:38.183Z" }, - { url = "https://files.pythonhosted.org/packages/76/25/579e731c94a7086a268bfa3e7a4945cd47836bebd3cbf3faeafd2e7eaef9/librt-0.10.0-cp314-cp314-win_amd64.whl", hash = "sha256:cbfaf7f5145e9917f5d18bffa298eff6a19d74e7b8b11dabdca95785befe8dbf", size = 67260, upload-time = "2026-05-05T16:30:39.804Z" }, - { url = "https://files.pythonhosted.org/packages/6e/f8/235822b7ae0b2334f12ee18bcf2476d07924077a5efeea57dbe927704be2/librt-0.10.0-cp314-cp314-win_arm64.whl", hash = "sha256:8d6d385d1969849a6b1397114df22714b6ded917bada98668e3e974dc663477e", size = 57156, upload-time = "2026-05-05T16:30:41.412Z" }, - { url = "https://files.pythonhosted.org/packages/9f/e3/9b919cbf1e8eb770bf91bb7df28125e0f1daf4587169afefd95402636e9a/librt-0.10.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:6c3a82d3bd32631ef5c79922dfc028520c9ad840255979ab4d908271818039ee", size = 79150, upload-time = "2026-05-05T16:30:42.761Z" }, - { url = "https://files.pythonhosted.org/packages/6a/f5/72a944aa3bc3498169a168087eff58ca48b58bf1b704e59d091fd30739f3/librt-0.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d64cc66005dc324c9bb1fa3fc2841f529002f6eb15966d55e46d430f56955a6a", size = 82304, upload-time = "2026-05-05T16:30:44.082Z" }, - { url = "https://files.pythonhosted.org/packages/9c/e3/fcc290a33e295019759472dfa794d204e43504b276ac65eab7fd9da20ea3/librt-0.10.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9bb562cd28c88cd2c6a9a6c78f99dc39348d6b16c94adc25de0e574acf1176e9", size = 272556, upload-time = "2026-05-05T16:30:45.497Z" }, - { url = "https://files.pythonhosted.org/packages/fd/54/546975e4c997573885e7f040a05012f8838e06fb12b0c3c1fbb76254e9d7/librt-0.10.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b809aa2854d019c28773b03605df22adc675ee4f3f4402d673581313e8906119", size = 256941, upload-time = "2026-05-05T16:30:47.059Z" }, - { url = "https://files.pythonhosted.org/packages/70/8c/f1d03401571b331653acddbd4e8cd955c06d945241dd08b25192fac0d04b/librt-0.10.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc15acabdd519bd4176fdadc2119e5e3093485d86f89138daf47e5b4cedb983a", size = 285855, upload-time = "2026-05-05T16:30:48.86Z" }, - { url = "https://files.pythonhosted.org/packages/0c/08/62cf80ff046c339faf56718b3a940244d4beb70f1c6407289b5830ec11e9/librt-0.10.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b1b2d835307d08ddadd94568e2369648ec9173bd3eea6d7f52a1abe717c81f98", size = 275321, upload-time = "2026-05-05T16:30:50.63Z" }, - { url = "https://files.pythonhosted.org/packages/d9/ea/da5918d4070362e9a4d2ee9cd34f9dc84902daad8fd4275f8504a727ff4e/librt-0.10.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d261c6a2f93335a5167887fb0223e8b98ffce20ee3fde242e8e58a37ece6d0e5", size = 293993, upload-time = "2026-05-05T16:30:52.577Z" }, - { url = "https://files.pythonhosted.org/packages/c9/8d/68b6086bed1fcdc314c640ea04e31e52d18052e08059fa595409d66a51a9/librt-0.10.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e2ffd44963f8e7f68995504d90f9881d64e94dc1d8e310039b9526108fc0c0f7", size = 284254, upload-time = "2026-05-05T16:30:55.086Z" }, - { url = "https://files.pythonhosted.org/packages/06/c8/b810f1d84ec34a5a7ed93d7b510ab04164d75fbdf23088d5c3fbe6b08357/librt-0.10.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5f285f6455ed495791c4d8630e5af732960adea93cac4c893d15619f2eae53e8", size = 284925, upload-time = "2026-05-05T16:30:56.728Z" }, - { url = "https://files.pythonhosted.org/packages/5a/00/3c82d4158c5a2c62528b8fccce65a8c9ad700e480e86f9389387435089a5/librt-0.10.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f6034ff52e663d34c7b82ef2aa2f94ad7c1d939e2368e63b06844bc4d127d2e1", size = 307830, upload-time = "2026-05-05T16:30:58.377Z" }, - { url = "https://files.pythonhosted.org/packages/99/3a/9c635ac3e8a00383ff689161d3eac8a30b3b2ddc711b40471e6b8983ea29/librt-0.10.0-cp314-cp314t-win32.whl", hash = "sha256:657860fd877fba6a241ea088ef99f63ca819945d3c715265da670bad56c37ebe", size = 60147, upload-time = "2026-05-05T16:31:00.293Z" }, - { url = "https://files.pythonhosted.org/packages/dc/e8/6f65f3e565d4ac212cddddd552eacc8035ffdf941ca0ad6fe945a211d41f/librt-0.10.0-cp314-cp314t-win_amd64.whl", hash = "sha256:56ded2d66010203a0cb5af063b609e3f079531a0e5e576d618dece859fd2e1af", size = 68649, upload-time = "2026-05-05T16:31:01.778Z" }, - { url = "https://files.pythonhosted.org/packages/51/78/a0705a67cacd81e5fa01a5035b3adbdfbb43a7b8d4bd27e2b282ae61baf2/librt-0.10.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1ee63f30abf18ed4830fdbaf87b2b6f4bba1e198d46085c314edde4045e56715", size = 58247, upload-time = "2026-05-05T16:31:03.191Z" }, +version = "0.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c6/e0/dbd0f2a68a1c1a1991eb7921ff6014465d56608cdc9a9fb468a616210a37/librt-0.12.0.tar.gz", hash = "sha256:cb26faedbd09c6130e9c1b64d8000efec5076ffd18d606c6cd1cf02730e6d8b0", size = 203841, upload-time = "2026-06-30T16:14:29.671Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/66/c9d88366893b4b0df6b5375c27ebc9f14c43419d9e244b493be20e85bc74/librt-0.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fe3547407bbce45c09885591f90168325c5a31a6795b9a13f6b9ff3d25093d93", size = 144398, upload-time = "2026-06-30T16:12:03.947Z" }, + { url = "https://files.pythonhosted.org/packages/bd/f2/9be1c6da204701163ec3aaedbf893d2f656b363d8fa302af536ce6471eb4/librt-0.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5925eca673207204a3adca040a91bdd3738fc7ba48da647ccd55732692a35736", size = 148924, upload-time = "2026-06-30T16:12:05.583Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f3/256824ee27649c6e0a693db25d391f97b43b52364f8efb466014a564bbc7/librt-0.12.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f9ef097a7711465a204454c69658bbb6b2a6be9bdef0eeeba9a042016d00688", size = 479654, upload-time = "2026-06-30T16:12:07.175Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3f/f4adbb3f293a04bd3dc2eb91d814f5b1e221e6b4522585696ba6901a0b9a/librt-0.12.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:57abc8b65edf1a8e80e5472c81c108a7527202e5febfda9e00a684dbaeae534e", size = 472318, upload-time = "2026-06-30T16:12:08.758Z" }, + { url = "https://files.pythonhosted.org/packages/9d/b5/362c93f7b43d4ef84a3d5f156c8d4eeddb22badcf5529a1281c387abbbd7/librt-0.12.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e6f53732a8ae5012a3b6ae092da2933be74ec4169d16038f4af87a0019afea", size = 501555, upload-time = "2026-06-30T16:12:10.623Z" }, + { url = "https://files.pythonhosted.org/packages/24/1d/2d6abf059c3a4b88a6668e7bb81af332b14463028ac8f2b08a1212eb1ebc/librt-0.12.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:edb5f06cdb38d6ef9fd7ae06d62962d65c881b5f965d5e8a6c53e59c15ae4338", size = 494118, upload-time = "2026-06-30T16:12:12.503Z" }, + { url = "https://files.pythonhosted.org/packages/39/c1/f91f3094be2c76361d88aca613d8b7586d15b6026714d59d2e3dc0e35f44/librt-0.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1473ef42263dfee7553a5c460f11730a4409acf0d52629b284eb1e6b13eb460a", size = 516318, upload-time = "2026-06-30T16:12:14.192Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e2/5211af94252458cbed7a6250163dff9c5a84aec29609121c828375a3b319/librt-0.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1d6f69a06295fb6ad8dcf92b4b2d15d211842005e86eedce64d88e0633592f58", size = 522294, upload-time = "2026-06-30T16:12:15.879Z" }, + { url = "https://files.pythonhosted.org/packages/90/9b/de31f5b9fdf7fa3699c4bbbecf82ebd52013d5d6b500b70b07b0ebacbd51/librt-0.12.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:3275d0270cd07ca9c2e140ae4da34e24a0350e98c6e3815dce96ead67cf0487d", size = 502494, upload-time = "2026-06-30T16:12:17.394Z" }, + { url = "https://files.pythonhosted.org/packages/b1/48/22c18dff89f3900dddb3e470e6f7febcda37ff3667b73097a848c9a608b2/librt-0.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a4834462ec68613024d063c7efe9b188e350d40fda9ba937372039883d2a8051", size = 543422, upload-time = "2026-06-30T16:12:19.006Z" }, + { url = "https://files.pythonhosted.org/packages/52/7b/74691b4b55944227245fffef063714e3ab9707ab1111eb0068512b428c7c/librt-0.12.0-cp310-cp310-win32.whl", hash = "sha256:bcf9b55ac089e8cf201d2146833e1097812c15dcea61911e84d6a2904cf78893", size = 97642, upload-time = "2026-06-30T16:12:20.386Z" }, + { url = "https://files.pythonhosted.org/packages/c5/dc/7f8fa369a1f7cc9b090fecd373659ada0e9bab1ae4a3ac9f163eabd04977/librt-0.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:c0a122002f7e0d5c93e84465c4b3fe86621402b7b92f1e2bc0784ebe67793112", size = 117583, upload-time = "2026-06-30T16:12:21.829Z" }, + { url = "https://files.pythonhosted.org/packages/9e/ab/628490f42d1eba82f3c7e5821aa62013e6df7f525b7a9e92c048f8d1cc1c/librt-0.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f13c1e8563102c2b17581cf37fcb2c6dae7ad485ccea93ae46258998c25f9a1", size = 143821, upload-time = "2026-06-30T16:12:23.248Z" }, + { url = "https://files.pythonhosted.org/packages/38/5f/793e8b6f4b6ac16e7d7198478c0af3670606fbb535c768d5f3e954781423/librt-0.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d1ddff067610a122387024c4df527493b909d41e54a6e5b2d0e6c1041d6dfa09", size = 148442, upload-time = "2026-06-30T16:12:24.582Z" }, + { url = "https://files.pythonhosted.org/packages/ad/92/c780fe37a9e0982f3bd8fd9a631d6b95d09a5a7201c6c50366ce843b7e42/librt-0.12.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8dc7ebb5f3eec062398e9d0ef1938acd21b589e74286c4a8906d0183318d91b", size = 478276, upload-time = "2026-06-30T16:12:26.101Z" }, + { url = "https://files.pythonhosted.org/packages/41/bb/226d444bc20d7dff4a19ec6c1ff2c13a76385eebddb59c9c00c923b67536/librt-0.12.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:198de569ea9d5f6f33808f1c00cc3db9de62bf4d6deafa3b052bd08255083038", size = 472337, upload-time = "2026-06-30T16:12:27.83Z" }, + { url = "https://files.pythonhosted.org/packages/12/79/98ac0840ee90a75d4e1155c79062860b12ccca508587ff2119fc086965f2/librt-0.12.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e958678a8bca56016aedc891b391c0e0813ea382a874b54a2c1b313c1d232720", size = 502087, upload-time = "2026-06-30T16:12:29.443Z" }, + { url = "https://files.pythonhosted.org/packages/6f/72/a6b1a0d080606a7f5f646b79a1496f21d709f8563877759ace9ce5adad73/librt-0.12.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575a6eca68c8437ed4a8e0f534e31d74b562ba1049a0ee4b5f09e114bcc21be1", size = 493202, upload-time = "2026-06-30T16:12:31.077Z" }, + { url = "https://files.pythonhosted.org/packages/69/cf/e1b036b45f2fc272205ee18bf272b47e8d684bf1a75af26db440c7504359/librt-0.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:86f241c50dc9e9a3f0db6dbb37a607c8205aa87b920802dabbd50b70d40f6939", size = 514139, upload-time = "2026-06-30T16:12:33.032Z" }, + { url = "https://files.pythonhosted.org/packages/40/34/b193b3e6985469a2f8afa86c90012329c86480b6ff4f2e4bd7b5b937e134/librt-0.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:113417b934fbf38220a9c7fe94578cefbe7dbb047adcb75aa197905af2b13724", size = 519486, upload-time = "2026-06-30T16:12:34.996Z" }, + { url = "https://files.pythonhosted.org/packages/31/9e/7de4947b1695f247c813f833e3c1e7b77b52e52a7dba2c35411cf806b58e/librt-0.12.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:762f17c0eb6b5d74e269126996cea8a89e35ab6464c5151619163abcd8623ae2", size = 499609, upload-time = "2026-06-30T16:12:36.663Z" }, + { url = "https://files.pythonhosted.org/packages/59/11/f3730e04e758b1fbf215359062ad2d5b6bd0b0ab5ac46b1c140628795be7/librt-0.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6aa93b3bd7f7588c628f6e9bf66485d3467fd9a1ccdb8975b770178f39f35697", size = 542205, upload-time = "2026-06-30T16:12:38.56Z" }, + { url = "https://files.pythonhosted.org/packages/1f/8f/710453617eabe20e18433864f335534c8aff63fbc68d8cd9dbc70a3d08f6/librt-0.12.0-cp311-cp311-win32.whl", hash = "sha256:aaa04b44d4fe86d824616b1f9c13e34c7c01ec0c96dd2abc4f59423696f788e2", size = 98067, upload-time = "2026-06-30T16:12:40.102Z" }, + { url = "https://files.pythonhosted.org/packages/42/53/401bff50a56e95daf151d911c99adf5732af2190e8f4d11886c9a229103c/librt-0.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:9aaeeddb8e7e4ae3bb9f944e0e618418cb91c0071d5ddbfcc3584b3cf59d39f0", size = 118346, upload-time = "2026-06-30T16:12:41.388Z" }, + { url = "https://files.pythonhosted.org/packages/e5/9a/a3a9078fe88bfc2d2d99dcf1c18593938ae830089cf84c3b2532a6c49d63/librt-0.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:18a2402fa3123ab76ecca670e6fb33038fde7c1e91181b885226ec4d30af2c2c", size = 104760, upload-time = "2026-06-30T16:12:43.112Z" }, + { url = "https://files.pythonhosted.org/packages/d5/1a/5bec493821b0e85b91de4f234912b50133d1aedb875048eef27938ec3f96/librt-0.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9bce19aa7c05f91c989f9da7b567f81d21d57a2e6501e2b811aa0f3f79614c1a", size = 146756, upload-time = "2026-06-30T16:12:44.395Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d0/cc04b48a57c1f275387f5578847214c4a6c21bfb24c6c8c8d6ba753fe403/librt-0.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0ace09f5bf4d982fe726015f102fb856658b41580597104e301e630ed1d8d86", size = 145537, upload-time = "2026-06-30T16:12:45.95Z" }, + { url = "https://files.pythonhosted.org/packages/9e/10/c02325556beb2aa158c9e549ddade8cc9a23b36cdad14756dbed730c1ff1/librt-0.12.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d007efe9243ede81ce75990ad7aa172da1e2024144b3eff17ba46a5fff1fff3c", size = 488637, upload-time = "2026-06-30T16:12:47.658Z" }, + { url = "https://files.pythonhosted.org/packages/cb/9e/7b49ca1c30baa9c8df96024aa09a97c35a97455e36004c9b5311703c56f3/librt-0.12.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:ad324a5e4858388a4864915b90a42efc8b374376393f14b9940f2454e791912b", size = 483651, upload-time = "2026-06-30T16:12:49.283Z" }, + { url = "https://files.pythonhosted.org/packages/4d/71/03c8c8cec39645fda451132ff9d6d662fc5aea42a1a188a77a4fddb35906/librt-0.12.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10a40cf74cdd97b6f8f905056db73f5d459783de2ca04c6ebd1bf47652818e7e", size = 518359, upload-time = "2026-06-30T16:12:50.999Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ec/a9f357f94bbcba92277d22af22cff42ef706ae5d9d6d58b69bebf3a67954/librt-0.12.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:92e61c09de95217ae02a9d17f4f66cf073253cdc51bcfdc0f15c62c9a70baa85", size = 509510, upload-time = "2026-06-30T16:12:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/7a/34/717055325d028743aa01a7691ad59a63352a26a8ff2e7eeb0c9249514150/librt-0.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0461344061d6fc3718940f5855d95647831cef6d03a6c7506897f98222784ad4", size = 527302, upload-time = "2026-06-30T16:12:54.244Z" }, + { url = "https://files.pythonhosted.org/packages/95/f8/7612eeedb3395d92f7c6a84dca5f15e282d650483a4dc01aa5b9cffdfda3/librt-0.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e6dfe89074732c9287b3c0f5a6af575c9ede380a788013876cc7b14fe0da0361", size = 532568, upload-time = "2026-06-30T16:12:55.74Z" }, + { url = "https://files.pythonhosted.org/packages/79/1e/a9afe85d5bb8b65dc27be3809ed1d69082079e1e9717fd2c66aa9939600c/librt-0.12.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9efed79d51ad1383bba0855f613cca7aa91c943e709af2413ac7f4bb9936ce08", size = 521579, upload-time = "2026-06-30T16:12:57.884Z" }, + { url = "https://files.pythonhosted.org/packages/b3/1e/93aebb219d52c37ea578f83b0588cd7b040974e464d4e435086a48b4dc4d/librt-0.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1eac6cc0e23e448fb3c1446ed85ff796afb616eed5897c978d35dbec030b7c7c", size = 558743, upload-time = "2026-06-30T16:12:59.577Z" }, + { url = "https://files.pythonhosted.org/packages/3c/85/1680c0ec332f238e3145c5608d313ab0a43281e210a5dd87e3bc3cc25631/librt-0.12.0-cp312-cp312-win32.whl", hash = "sha256:0ab8ee0210047ae86ca023ccfbfe3df82077fd1c9bc021aebbf37d993ef64af0", size = 99200, upload-time = "2026-06-30T16:13:01.015Z" }, + { url = "https://files.pythonhosted.org/packages/30/0e/abca12d8904875aa2ad66327390a3f7b1b75ebc43c0a00fc763cecf32ea5/librt-0.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:51c8bfa12632c81b94401c101bcedd0c56c3a1f8fa3273ca3472b28cd2f54003", size = 119390, upload-time = "2026-06-30T16:13:02.493Z" }, + { url = "https://files.pythonhosted.org/packages/32/a5/4203481b6d3a3bb348c82ac71abf1fcb4cb3ae8422a24a8dee4cd3ac5bd7/librt-0.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:5eebd451f5def089369ba6d8ff0291303d035e8154f9f26f7633835c5b029ade", size = 105117, upload-time = "2026-06-30T16:13:03.952Z" }, + { url = "https://files.pythonhosted.org/packages/f2/87/568d948c8079c9ff3c9e8110cf85f1eb70218e1209af29d0b7b89aa4a60c/librt-0.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8d9a55760a34ae5ce70434aabb6a6c61c6c44a0ec58ca1cfd9cd86e4745d417d", size = 146808, upload-time = "2026-06-30T16:13:05.417Z" }, + { url = "https://files.pythonhosted.org/packages/e7/1d/bea471ecea210088847bb5f3c4b4b424d596518934c06679b78ca85d6e63/librt-0.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ff0b197e338b4cf432873e0d6ef025213fdea85311ec4d87d2ea88c28adf2409", size = 145503, upload-time = "2026-06-30T16:13:07.023Z" }, + { url = "https://files.pythonhosted.org/packages/eb/9e/984ad422b56de95fdce158f06b051655373784ebea0aba9a7fcbc41614d1/librt-0.12.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e69f120a20b69e2539d603bbd4d62db38399b10f8bf73a1cf445038a621e8af", size = 488421, upload-time = "2026-06-30T16:13:08.492Z" }, + { url = "https://files.pythonhosted.org/packages/50/03/1a2f94009b07ea71f8e1a4cfe53370565b56da9caa341b89e0699325e9f5/librt-0.12.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:fde3cde595e947fc8e755b0a21f919a1622483d07c662d00496e040773d22591", size = 483488, upload-time = "2026-06-30T16:13:10.169Z" }, + { url = "https://files.pythonhosted.org/packages/aa/3b/084bdc295823fbb6ab91670047adf8f420787f9e8794bf2d140b66dc196b/librt-0.12.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d977447315fa09ea4e8c7ae9b4e22f7659b5128161c1fd55ff786b5349f73503", size = 518428, upload-time = "2026-06-30T16:13:11.681Z" }, + { url = "https://files.pythonhosted.org/packages/c9/22/5a307390b93a115ffbecd95c64eecb4e56269680e45e9415ada7285f2cf4/librt-0.12.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ffac8a67e4143cea9a549d4822b93bc0bbaad73fc25aa0ab0ba5ec27d178677", size = 509744, upload-time = "2026-06-30T16:13:13.217Z" }, + { url = "https://files.pythonhosted.org/packages/b5/90/83f3cb6184f5d669660717b4b2e317c9ddaccf7ca5bb97f2196deac1a3b7/librt-0.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:94af1ed773ff104ef08ef3d669a0ba9d3a5916c609eb698cffe5d5476d66ff9b", size = 527749, upload-time = "2026-06-30T16:13:15.277Z" }, + { url = "https://files.pythonhosted.org/packages/7d/3b/f162be5cc88d47378e3a20776fe425fa1c2bece755da15e2783ebf06d3d6/librt-0.12.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:548199d21d22fb26398dfbbe0ba953a52465c66f3a49f38e6fddce1b127faf53", size = 532582, upload-time = "2026-06-30T16:13:17.074Z" }, + { url = "https://files.pythonhosted.org/packages/c9/28/6c5d2f6b7232fd24f284fc4cab37a459fe69a9096a09942f44cc5c55e073/librt-0.12.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c8f1f413b966a9dd3ecf80cd337b0ad7bb3de2474a4ff448ed3ebabfc3f803fc", size = 522235, upload-time = "2026-06-30T16:13:18.823Z" }, + { url = "https://files.pythonhosted.org/packages/a9/1c/bd115360587fdc22c8ae8fac14c040a556b442e2965d4370d2cf274c8b95/librt-0.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:55f13f95b629be5b6ab38918e439bf14169d6f9a8deaae55e0c14e12fb0c74b9", size = 559055, upload-time = "2026-06-30T16:13:20.509Z" }, + { url = "https://files.pythonhosted.org/packages/fe/5a/c26f49f576437014825a86faea3cec60c1ed17f976abd567b6c12b8e35a7/librt-0.12.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:8b2dc079dfe29e77a47a19073d2040fa4879aa3656501f1650f8402ddce0313c", size = 79809, upload-time = "2026-06-30T16:13:22.401Z" }, + { url = "https://files.pythonhosted.org/packages/69/0b/a55244261d9ad7375ac039b8af06d42602722e2e8b8d8d6b86e4a3888c02/librt-0.12.0-cp313-cp313-win32.whl", hash = "sha256:da58944be8270f2bfee628a9a2a60c1cf6a12c8bea8e2c9b6edf3e5414ca7793", size = 99308, upload-time = "2026-06-30T16:13:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/c9/bf/ed9465e58d44c5a5637795547d0841c8934aab905ea452cac1adf14672cf/librt-0.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:1db4be3037e4ce065a071fa7deee93e78ebc25f448340a02a6c1c0b82c37e383", size = 119438, upload-time = "2026-06-30T16:13:25.188Z" }, + { url = "https://files.pythonhosted.org/packages/c0/44/3cad652aeb892e6e8ffe48d0fafa2bc652f28ec7ed3f4403fcbb1be4f948/librt-0.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:05fd2542892ad770b5dd45003fd080477cf220b611d3ee59b0792097eb0873a9", size = 105118, upload-time = "2026-06-30T16:13:26.533Z" }, + { url = "https://files.pythonhosted.org/packages/0e/51/3a0e05618c12423b6fc5141b590ec02a6efb645833edc8736a6c7b46d1ec/librt-0.12.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:b37ee42e09722284a6d9288fe44a191f7276060a3195939bb77c6502058dbb34", size = 145579, upload-time = "2026-06-30T16:13:27.909Z" }, + { url = "https://files.pythonhosted.org/packages/77/9e/fd399d099dfb4020f3f7c34e7e6210c389fa89f7d79ca92f5afb0395f278/librt-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ade11988728b3e4768dadc5696e82c60e9b35fc95335a9b4d1f5d69e753ccec7", size = 150139, upload-time = "2026-06-30T16:13:29.357Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ee/610239fbd8c4b005443664c5d4c3bc1717daedd8c71369bf45011aa87194/librt-0.12.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f351ed425380e39bd86df382578aa5b8c5b98e2e265112de7379e7d030258150", size = 480457, upload-time = "2026-06-30T16:13:30.78Z" }, + { url = "https://files.pythonhosted.org/packages/0c/10/ceddc9010f26c541444be36e1153a79b64626694db2d33a524c719fa3e46/librt-0.12.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:857d2163e088c868967717ace8e980017fd868a735f3de010412af02bdc30319", size = 479002, upload-time = "2026-06-30T16:13:32.398Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f1/b1523d9718e8192e5403e6b41a02742e17ba554369f0729b9f30ab590e2d/librt-0.12.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2befc80aa5f2f5b93f28abaaf11feff6677931dd548320e44c52deaa9399744", size = 510527, upload-time = "2026-06-30T16:13:34.615Z" }, + { url = "https://files.pythonhosted.org/packages/f6/0e/0f3ff43befb18a531615736791e52fb67eaa71ff7b89e6e5f7004b64cc6e/librt-0.12.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:be3694dcfa97c6715dd19ac73d3e1b21a805514a5785663e57fecacd3ff64e5a", size = 500988, upload-time = "2026-06-30T16:13:36.408Z" }, + { url = "https://files.pythonhosted.org/packages/a8/1a/0278ea4a9e599dc507c43839a87f2c764ad04bf69418e2d763d58659e55f/librt-0.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2d5f67e86f45638843d025b0828f2e9e55fc45ff9180d2618ccdeaf72a796050", size = 519318, upload-time = "2026-06-30T16:13:37.883Z" }, + { url = "https://files.pythonhosted.org/packages/59/55/090e10e62be2f35265e41601337f83ac9f83be9aca1bf92692e3a82effdd/librt-0.12.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:64572c85e4ab7d572c9b72cd76b5f90b21181b1459fa6b1aac6f8958c4fcff31", size = 527127, upload-time = "2026-06-30T16:13:39.682Z" }, + { url = "https://files.pythonhosted.org/packages/1f/34/8052c9ec678be6ba751279947831f089aa69b009000b985ce91d1979669a/librt-0.12.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:8b961912b0e688c1eb4658a46bdb0606b31918d65597fbe7356ca83aa653ffcc", size = 509766, upload-time = "2026-06-30T16:13:41.266Z" }, + { url = "https://files.pythonhosted.org/packages/6f/f8/8761b36189e9ec8dc20b49fa84cef22852c6c41fcda56f760f7fc1360da5/librt-0.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:722375903e3f079436a7a33da51ce73931536dd041f9feb01536f05d8e010c96", size = 552043, upload-time = "2026-06-30T16:13:43.197Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/7283971ef6b70269938b49c7b25f670ec6325d252265fbcc996f9b364379/librt-0.12.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:a5a96a8f536b65ef1bf910c09e7e71647edde5111f6e1b51f413c6fba5bfe71b", size = 79472, upload-time = "2026-06-30T16:13:44.64Z" }, + { url = "https://files.pythonhosted.org/packages/c3/5e/b30940dea935e8ac5bd0e0abb1985f5274590d557ac3a252ca0d5392ce52/librt-0.12.0-cp314-cp314-win32.whl", hash = "sha256:8ffc99c356f1777c506e1b69dc303879153ae2640ba15b8f3d4448bc87139149", size = 94246, upload-time = "2026-06-30T16:13:45.962Z" }, + { url = "https://files.pythonhosted.org/packages/7d/4e/0af9fe63f35fa304da3b05688f30ff6a329bcc59581b1cc51dc87fd30141/librt-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:1e68fb20798f455cda41d20a306a23c901218883f17a4bab1ed6e1331b265fb7", size = 114951, upload-time = "2026-06-30T16:13:47.279Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8e/843c495d7db35e13b84cd533898fa89145c40dc255da0bc316d53d631464/librt-0.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:2df534f97916cf38ec9b1ddafeb68ae1a4cd4a54775ff26a797026774c0517cf", size = 100562, upload-time = "2026-06-30T16:13:48.699Z" }, + { url = "https://files.pythonhosted.org/packages/75/30/c686d0f978d5fd6867c5bbad96b015c9445746764d1c228e16a2d30d9382/librt-0.12.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:c09e581b1c2b8a62b809d4f4bd101ca3de93791e5b0ed1a14085d911be3dee3f", size = 153897, upload-time = "2026-06-30T16:13:50.017Z" }, + { url = "https://files.pythonhosted.org/packages/40/46/f6f2d77ce46628b48fb5280709013b5109cf3a2c46a2472093cdfc03519d/librt-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:976888d0d831402086e641018bcc3208e0a38f0835789da91f72894b2cb4161f", size = 156391, upload-time = "2026-06-30T16:13:51.462Z" }, + { url = "https://files.pythonhosted.org/packages/c2/46/cd790c7e19e460779471530ffab454541d6ea4a3b7d338cad7f16ff96995/librt-0.12.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:563c37cdb41d08fe1e3f08b201abac0e317ca18e88b91285466ee0a585797520", size = 564151, upload-time = "2026-06-30T16:13:53.146Z" }, + { url = "https://files.pythonhosted.org/packages/54/12/724559a15fb023cbdef7aee1e81fbfbc3ee22fd09009baa816cea63e3a60/librt-0.12.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b97eb1a3140e279cc76f85b0fb92b7eb3dfbe0471260ee878bc9dc4bf9a0d649", size = 546002, upload-time = "2026-06-30T16:13:54.665Z" }, + { url = "https://files.pythonhosted.org/packages/4b/7e/f9d8c257ab4909f101c7c13734367749e782fd8625545f0343502c2f09f1/librt-0.12.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:06e0623351ab9904cf628245f99c714586f4dd23dc740b88c8bc670d8401a847", size = 584204, upload-time = "2026-06-30T16:13:56.301Z" }, + { url = "https://files.pythonhosted.org/packages/9b/33/64665810575ac23b6cb6ef364de51309b7803620c12885b6e895ebc29591/librt-0.12.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:da12f017b2e404554be14d466cd992459feaa44f252b0f18d909a85266ce1237", size = 573688, upload-time = "2026-06-30T16:13:58.1Z" }, + { url = "https://files.pythonhosted.org/packages/0f/01/27522995c6627455abc7a939d57535fb1a7836d398ccedb3d7585f46039e/librt-0.12.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d97f31003a5c86b9e78155a829572c3a26484064fb7ac1d9695fe628bd93d029", size = 604719, upload-time = "2026-06-30T16:13:59.831Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1f/099e61b1b688551d6d2ce9d4d2ae2242a938759db8551e6cbac7f7176ee5/librt-0.12.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:bd43a6c69876aef4f04eaae3d3b99b0be64755fda274002fa445b92480bf664e", size = 598183, upload-time = "2026-06-30T16:14:01.457Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c1/050400249665503bdd5b83cec518fa7b183b609341c8dcd58161775c4226/librt-0.12.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c01755c72fca1dc6b8d5c2ed228b8e7b2ffe184675c22f0f05ebd8fe188b9250", size = 582559, upload-time = "2026-06-30T16:14:03.29Z" }, + { url = "https://files.pythonhosted.org/packages/da/d1/eef8f0e6722518b65a3d3bcd9309f9f44e208ce5d6728070820f988e7078/librt-0.12.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:625ae561d5fa36400856dcc27464400d047bc2d5e3446be88f437b03fefd72e4", size = 626375, upload-time = "2026-06-30T16:14:04.957Z" }, + { url = "https://files.pythonhosted.org/packages/8b/78/f0bb41a6f2bbd3c77bdcc66980dc0d69ca1192a0ecec25377afcc5e6db73/librt-0.12.0-cp314-cp314t-win32.whl", hash = "sha256:8d73191883553ee0739741544bf3b00aba2a1224e45d9580b30cbc29e21dc03b", size = 97752, upload-time = "2026-06-30T16:14:06.555Z" }, + { url = "https://files.pythonhosted.org/packages/92/24/e279c27972ab051a070237cfa45728fa51670c3f22f1a4d391711e9f4c31/librt-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e1cbb037324e759f0afa270229731ff0047772667f3cb38ef5df2cabf0175ede", size = 119562, upload-time = "2026-06-30T16:14:07.908Z" }, + { url = "https://files.pythonhosted.org/packages/06/e6/42a475bfca683b0cd5366f6dd06580062b7e567bb8534d225c877c2f14f3/librt-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:bca1472acbd473eff61059b4409f802c5a1bcb4cd0344d06f939df9c4c125d40", size = 104282, upload-time = "2026-06-30T16:14:09.29Z" }, ] [[package]] @@ -1162,7 +1167,7 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "mdurl", marker = "python_full_version < '3.11'" }, + { name = "mdurl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ @@ -1171,12 +1176,12 @@ wheels = [ [package.optional-dependencies] linkify = [ - { name = "linkify-it-py", marker = "python_full_version < '3.11'" }, + { name = "linkify-it-py" }, ] [[package]] name = "markdown-it-py" -version = "4.1.0" +version = "4.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15'", @@ -1184,16 +1189,16 @@ resolution-markers = [ "python_full_version == '3.11.*'", ] dependencies = [ - { name = "mdurl", marker = "python_full_version >= '3.11'" }, + { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/5c/f3aedc83549aae71cd52b9e9687fe896e3dc6e966ba20eba04718605d198/markdown_it_py-4.1.0.tar.gz", hash = "sha256:760e3f87b2787c044c5138a5ba107b7c2be26c03b13cc7f8fe42756b65b1df6c", size = 81613, upload-time = "2026-05-06T16:32:13.649Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/88/802c82060c54bc7dde21eb0033e337838b8181a1323254aa9ec41cbfc3d1/markdown_it_py-4.1.0-py3-none-any.whl", hash = "sha256:d4939a62a2dd0cd9cb80a191a711ba1d39bac8ed5ef9e9966895b0171c01c46d", size = 90955, upload-time = "2026-05-06T16:32:12.184Z" }, + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] [package.optional-dependencies] linkify = [ - { name = "linkify-it-py", marker = "python_full_version >= '3.11'" }, + { name = "linkify-it-py" }, ] [[package]] @@ -1287,7 +1292,7 @@ version = "0.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655, upload-time = "2025-08-11T07:25:49.083Z" } wheels = [ @@ -1504,7 +1509,7 @@ wheels = [ [[package]] name = "mypy" -version = "2.0.0" +version = "2.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ast-serialize" }, @@ -1514,51 +1519,52 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cf/dc/7e6d49f04fca40b9dd5c752a51a432ffe67fb45200702bc9eee0cb4bbb26/mypy-2.0.0.tar.gz", hash = "sha256:1a9e3900ac5c40f1fe813506c7739da6e6f0eab2729067ebd94bfb0bbba53532", size = 3869036, upload-time = "2026-05-06T19:26:43.22Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/49/1e/9983d2d5b5d2dc3677177bcf0fa6b25185ecf750cc0559e02199625a31c5/mypy-2.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:65d6f22d643bccaeb182d41d2a9f0990a05a871673c4ae3f97d4931eca0d2294", size = 14663140, upload-time = "2026-05-06T19:25:59.474Z" }, - { url = "https://files.pythonhosted.org/packages/69/bc/b4009c91d3ced13c8f406acf47bbe56365025cd21bf6585cd1e87375a708/mypy-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:106650bce72114f43019bf72197296f51c2cd47adfa9d073ea2976c247a404c5", size = 13526733, upload-time = "2026-05-06T19:22:56.425Z" }, - { url = "https://files.pythonhosted.org/packages/f0/99/2403cb0ceeb1552f70e70e779e3d0713b24f84c7ca0e9e14b2b7bc684cf0/mypy-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c734b7eb89a4cc4ec347f8187ffa730e2b59693407bc93dcb878183037f80a17", size = 13951940, upload-time = "2026-05-06T19:24:43.45Z" }, - { url = "https://files.pythonhosted.org/packages/1d/f7/4848a14c2667b6eb62841c9aeb7e1f6479613b1ef9a65564fe1f5518a35b/mypy-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd9e60388944d0f1432a2419ab938a78d5658df1d143a7172cfe1a197276cf49", size = 14833983, upload-time = "2026-05-06T19:23:16.827Z" }, - { url = "https://files.pythonhosted.org/packages/ec/28/c51831f9f1c6e46cbce765bd0a18981b84696e40bd1eea14e0a08494af44/mypy-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f95e3890666c3be41af7a7179f4872341c08e90c161ba8e7a08a21f9be92c131", size = 15135591, upload-time = "2026-05-06T19:24:32.96Z" }, - { url = "https://files.pythonhosted.org/packages/40/7f/3c25e503a94f9ec18352464551bc6c506dee2bca93c6d0e0b5568eefc269/mypy-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:e8e8709ce1b1046b8aad77a506dd01491157102dd727128c0b374b5025c7d769", size = 10983019, upload-time = "2026-05-06T19:20:30.942Z" }, - { url = "https://files.pythonhosted.org/packages/75/da/5cf833fd3b53fd4b5797e55dc16fb7efab16fddbc7205d49ff65b15d554e/mypy-2.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:0165968759c99ab79dc1a9f8aaec18e93a1bedcf7c13edd70e68dd3d5faf17cb", size = 9914165, upload-time = "2026-05-06T19:21:49.165Z" }, - { url = "https://files.pythonhosted.org/packages/8b/1e/268b81393b81d64683f670680215553e70ae92c55805915b3440080e05e4/mypy-2.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17b7222e9fdfd352e61fb3131da117e55cc465f701ff232f1bd97a02bbad91f", size = 14580849, upload-time = "2026-05-06T19:23:06.567Z" }, - { url = "https://files.pythonhosted.org/packages/6e/32/d159a8002d9e5c44e59ece9d641a26956c89be5b6827f819d9a9dc678c65/mypy-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cc0a61adea1a5ffc2d47a4dc4bb180d8103f477fc2a90a1cdcbb168c2cc6caff", size = 13444955, upload-time = "2026-05-06T19:25:11.982Z" }, - { url = "https://files.pythonhosted.org/packages/cd/5d/3b28d5a2799591da0ee5490418e94497eaf5d701e42d8b001b5e17a9b3d6/mypy-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8578f857b519993d065e5805290b71467ebfae772407a5f57e823755e4fdb850", size = 13873124, upload-time = "2026-05-06T19:20:39.684Z" }, - { url = "https://files.pythonhosted.org/packages/60/23/f40f723955617b814d5ddc1154d8938b77aaf6926c2dbf72846e8943a0b7/mypy-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:33f668a37a650df60f7b825c1ac61e6baadd4ac3c89519e929badde58d28edf5", size = 14748822, upload-time = "2026-05-06T19:25:30.972Z" }, - { url = "https://files.pythonhosted.org/packages/d6/16/eded971224a483e422a141ffd580c00e1b919df8e529f06d03a4a987878c/mypy-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29ea6da86c8c5e9addd48fa6e624f467341b3814f54ded871b28980468686dea", size = 14992675, upload-time = "2026-05-06T19:23:34.511Z" }, - { url = "https://files.pythonhosted.org/packages/ea/6a/1cbd7290f00b4dbaa4c4502e53ac05645ea635e4d1e3dcd42687c2fc39cd/mypy-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:904baa0124ebbccf0c7ba94f722cf9186ee30478f5e5b11432ffc8929248ee55", size = 10983628, upload-time = "2026-05-06T19:26:39.48Z" }, - { url = "https://files.pythonhosted.org/packages/83/3f/8caa9bcc2636cd512642050747466b695fa2540d7040544fd7ddb721d671/mypy-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:440165501295e523bf1e5d3e411b62b367b901c65610938e75f0e56ba0462461", size = 9906041, upload-time = "2026-05-06T19:24:03.199Z" }, - { url = "https://files.pythonhosted.org/packages/f6/4b/f6cd12ef1eb63be1c342da3e8ca811d2280276177f6de4ef20cb2366d79b/mypy-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:660790551c988e69d8bf7a35c8b4149edeb22f4a339165702be843532e9dcdb5", size = 14756610, upload-time = "2026-05-06T19:26:19.221Z" }, - { url = "https://files.pythonhosted.org/packages/32/73/67d09ca28bee21feaca264b2a680cf2d300bcc2071136ad064928324c843/mypy-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7a15bf92cd8781f8e72f69ffa7e30d1f434402d065ee1ecd5223ef2ef100f914", size = 13554270, upload-time = "2026-05-06T19:26:08.977Z" }, - { url = "https://files.pythonhosted.org/packages/61/b3/44718b5c6b1b5a27440ff2effe6a1be0fa2a190c0f4e2e21a83728416f95/mypy-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4ff370b43d7def05bbcd2f5267f0bcda72dd6a552ef2ea9375b02d6fe06da270", size = 13924663, upload-time = "2026-05-06T19:21:24.932Z" }, - { url = "https://files.pythonhosted.org/packages/6a/2b/bbb9cc5773f946846a7c340097e59bcf84095437dda0d56bb4f6cf1f6541/mypy-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37bd246590a018e5a11703b7b09c39d47ede3df5ba3fa863c5b8590b465beb01", size = 14946862, upload-time = "2026-05-06T19:24:23.023Z" }, - { url = "https://files.pythonhosted.org/packages/43/25/e9318566f443a5130b4ff0ad3367ee6c4c4c49ff083fe5214a7318c18282/mypy-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cce87e92214fac8bf8feb8a680d0c1b6fb748d50e9b57fbb13e4b1d83a3ed19b", size = 15175090, upload-time = "2026-05-06T19:26:28.794Z" }, - { url = "https://files.pythonhosted.org/packages/67/65/2ec28c834f21e164c33bc296a7db538ad50c74f83e517c7a0be95ff6de86/mypy-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:e19e9cb69b66a4141009d24898259914fa2b71d026de0b46edf9fafdbf4fd46e", size = 11052899, upload-time = "2026-05-06T19:25:39.084Z" }, - { url = "https://files.pythonhosted.org/packages/9e/72/d1ec625cfc9bd101c07a6834ef1f94e820296f8fdbad2eb03f50e0983f8c/mypy-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:b021614cb08d44785b025982163ec3c39c94bff766ead071fa9e82b4ef6f62cd", size = 9972935, upload-time = "2026-05-06T19:23:24.204Z" }, - { url = "https://files.pythonhosted.org/packages/e5/c6/996a1e535e5d0d597c3b1460fc962733091f885f312e749350eb2ac10965/mypy-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ef5f581b61240d1cc629b12f8df6565ed6ffac0d82ed745eef7833222ab50b9", size = 14737259, upload-time = "2026-05-06T19:20:23.081Z" }, - { url = "https://files.pythonhosted.org/packages/94/c5/0f9460e26b77f434bd53f47d1ce32a3cd4580c92a5331fa5dfc059f9421a/mypy-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:20e3470a165dbc249bdfbe8d1c5172727ef22688cffc279f8c3aa264ab9d4d9a", size = 13538377, upload-time = "2026-05-06T19:21:08.804Z" }, - { url = "https://files.pythonhosted.org/packages/b2/3e/8ea2f8dd1e5c9c279fb3c28193bdb850adf4d3d8172880abad829eced609/mypy-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:224ba142eee8b4d65d4db657cb1fc22abec30b135ded6ab297302ba1f62e505d", size = 13914264, upload-time = "2026-05-06T19:24:12.875Z" }, - { url = "https://files.pythonhosted.org/packages/be/ce/78bd3b8520f676acee9dab48ea71473e68f6d5cf14b59fbd800bea50a92b/mypy-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e879ad8a03908ff74d15e8a9b42bf049918e6798d52c011011f1873d0b5877e", size = 14926761, upload-time = "2026-05-06T19:20:12.846Z" }, - { url = "https://files.pythonhosted.org/packages/61/ef/b52fa340522da3d22e669117c3b83155c2660f7cdc035856958fbfffb224/mypy-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:65c5c15bcbd18d6fe927cc55c459597a3517d69cc3123f067be3b020010e115e", size = 15157014, upload-time = "2026-05-06T19:25:49.78Z" }, - { url = "https://files.pythonhosted.org/packages/7a/0c/dde7614250c6d017936c7aa3bb63b9b52c7cfd298d3f1be9be45f307870b/mypy-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:d1a068acd7c9fb77e9f8923f1556f2f49d6d7895821121b8d97fa5642b9c52f5", size = 11067049, upload-time = "2026-05-06T19:21:16.116Z" }, - { url = "https://files.pythonhosted.org/packages/27/ec/1d6af4830a94a285442db19caa02f160cc1a255e4f324eec5458e6c2bafb/mypy-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:ef9d96da1ddffbc21f27d3939319b6846d12393baa17c4d2f3e81e040e73ce2c", size = 9967903, upload-time = "2026-05-06T19:22:15.52Z" }, - { url = "https://files.pythonhosted.org/packages/ce/2c/6fefe954207860aed6eeb91776795e64a257d3ce0360862288984ce121f5/mypy-2.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c918c64e8ce36557851b0347f84eb12f1965d3a06813c36df253eb0c0afd1d82", size = 14729633, upload-time = "2026-05-06T19:24:53.383Z" }, - { url = "https://files.pythonhosted.org/packages/23/d6/d336f5b820af189eb0390cce21de62d264c0a4e64713dfbe81bfc4fc7739/mypy-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:301f1a8ccc7d79b542ee218b28bb49443a83e194eb3d10da63ff1649e5aa5d34", size = 13559524, upload-time = "2026-05-06T19:22:24.906Z" }, - { url = "https://files.pythonhosted.org/packages/af/a6/d7bb54fde1770f0484e5fbdbdce37a41e95ed0a1cd493ec60ead111e356c/mypy-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fdf4ef489d44ce350bac3fd699907834e551d4c934e9cc862ef201215ab1558d", size = 13936018, upload-time = "2026-05-06T19:25:02.992Z" }, - { url = "https://files.pythonhosted.org/packages/7d/ba/5be51316b91e6a6bf6e3a8adb3de500e7e1fb5bf9491743b8cbc81a34a2c/mypy-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9cde2d0989f912fc850890f727d0d76495e7a6c5bdd9912a1efdb64952b4398d", size = 14910712, upload-time = "2026-05-06T19:25:21.83Z" }, - { url = "https://files.pythonhosted.org/packages/b7/37/e2c8c3b373e20ebfb66e6c83a99027fd67df4ec43b08879f74e822d2dc4c/mypy-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cdf05693c231a14fe37dbfce192a3a1372c26a833af4a80f550547742952e719", size = 15141499, upload-time = "2026-05-06T19:20:50.924Z" }, - { url = "https://files.pythonhosted.org/packages/12/36/07756f933e00416d912e35878cfcf89a593a3350a885691c0bb85ae0226a/mypy-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:73aee2da33a2237e66cbe84a94780e53599847e86bb3aa7b93e405e8cd9905f2", size = 11240511, upload-time = "2026-05-06T19:21:32.39Z" }, - { url = "https://files.pythonhosted.org/packages/70/05/79ac1f20f2397353f3845f7b8bb5d8006cda7c8ef9092f04f9de3c6135f2/mypy-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:1f6dcd8f39971f41edab2728c877c4ac8b50ad3c387ff2770423b79a05d23910", size = 10149336, upload-time = "2026-05-06T19:22:08.383Z" }, - { url = "https://files.pythonhosted.org/packages/53/e0/0db84e0ebbad6e99e566c68e4b465784f2a2294f7719e8db9d509ef23087/mypy-2.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a04e980b9275c76159da66c6e1723c7798306f9802b31bdaf9358d0c84030ce8", size = 15797362, upload-time = "2026-05-06T19:22:00.835Z" }, - { url = "https://files.pythonhosted.org/packages/0a/a4/14cc0768164dd53bec48aa41a20270b18df9bf72aa5054278bf133608315/mypy-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:33f9cf4825469b2bc73c53ba55f6d9a9b4cdb60f9e6e228745581520f29b8771", size = 14635914, upload-time = "2026-05-06T19:23:43.675Z" }, - { url = "https://files.pythonhosted.org/packages/08/48/d866a3e23b4dc5974c77d9cf65a435bf22de01a84dd4620917950e233960/mypy-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:191675c3c7dc2a5c7722a035a6909c277f14046c5e4e02aa5fbf65f8524f08ad", size = 15270866, upload-time = "2026-05-06T19:22:34.756Z" }, - { url = "https://files.pythonhosted.org/packages/71/eb/de9ef94958eb2078a6b908ceb247757dc384d3a238d3bd6ed7d81de5eaf8/mypy-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3d26c4321a3b06fc9f04c741e0733af693f82d823f8e64e47b2e63b7f19fa84", size = 16093131, upload-time = "2026-05-06T19:23:56.541Z" }, - { url = "https://files.pythonhosted.org/packages/ad/07/0ab2c1a9d26e90942612724cbd5788f16b7810c5dd39bfcf79286c6c4524/mypy-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bbcbc4d5917ca6ce12de70e051de7f533e3bf92d548b41a38a2232a6fe356525", size = 16330685, upload-time = "2026-05-06T19:21:42.037Z" }, - { url = "https://files.pythonhosted.org/packages/a6/8f/46f85d1371a5be642dad263828118ae1efd536d91d8bd2000c68acff3920/mypy-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:dbc6ba6d40572ae49268531565793a8f07eac7fc65ad76d482c9b4c8765b6043", size = 12752017, upload-time = "2026-05-06T19:22:44.002Z" }, - { url = "https://files.pythonhosted.org/packages/7a/e6/94ca48800cac19eb28a58188a768aaec0d16cac0f373915f073058ab0855/mypy-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:77926029dfcb7e1a3ecb0acb2ddbb24ca36be03f7d623e1759ad5376be8f6c01", size = 10527097, upload-time = "2026-05-06T19:20:58.973Z" }, - { url = "https://files.pythonhosted.org/packages/5c/14/fd0694aa594d6e9f9fd16ce821be2eff295197a273262ef56ddcc1388d68/mypy-2.0.0-py3-none-any.whl", hash = "sha256:8a92b2be3146b4fa1f062af7eb05574cbf3e6eb8e1f14704af1075423144e4e5", size = 2673434, upload-time = "2026-05-06T19:26:32.856Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/e9/7e/be536678c6ae49ef058aba4b483d8c7bc104f471479016066f345bc1f5f8/mypy-2.2.0.tar.gz", hash = "sha256:2cdd99d48590dce6f6b7f1961eda75386364398fcdaad86923bc0f0231bf9baf", size = 3950939, upload-time = "2026-07-08T01:37:27.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/f1/a818c375094e20a74ec51444cce6979cedd61d476f860c2f084ea8653bd2/mypy-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97d21f3a1582ef30d0b77f9ca3ad88b4263f3c5aea9e7380cb5d7175160aec7e", size = 14903842, upload-time = "2026-07-08T01:33:27.944Z" }, + { url = "https://files.pythonhosted.org/packages/33/15/f332590488a8e4bb4a24036484c8bc750fe01fbef09701451a8790ac4c44/mypy-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2529017942b951cc43db2e2712b71cc3aa7e9d90567630c03ed63d430aeec61a", size = 13902986, upload-time = "2026-07-08T01:36:59.24Z" }, + { url = "https://files.pythonhosted.org/packages/38/9f/7ae37860922d264b536790a3307caa195eb8abb733f2e81608229bbb0f07/mypy-2.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0823d7f273f3b4a49df7573eac271ddbf77a0e5f53e24d294a4f0f77ad22e1d7", size = 14132163, upload-time = "2026-07-08T01:34:16.111Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6d/25c31c85a793340a4a9be593f8fe2cea08fd7b615f8b602b3f52f2d822f6/mypy-2.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d78a0fc90704894bc9948d78affad14b882b08183a7c30412d185748aaa9418b", size = 15070110, upload-time = "2026-07-08T01:34:44.933Z" }, + { url = "https://files.pythonhosted.org/packages/cb/67/7adf1caa143f6a0d9c564de24e0c1ed48340185110c3b918adc2f447192b/mypy-2.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6efab25fa3568569fda06928743382900860c48be9200c1758ef5ce94b532714", size = 15371554, upload-time = "2026-07-08T01:34:27.688Z" }, + { url = "https://files.pythonhosted.org/packages/49/cb/ceca928213076f540d9b068c3655c52d43549f124c1f6dece5ecb747bbeb/mypy-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:daeaf5287091d68f674c91416cabab0f80f36e347ed17fded38d7ebde682e9d1", size = 11063618, upload-time = "2026-07-08T01:36:13.235Z" }, + { url = "https://files.pythonhosted.org/packages/41/24/08caa177a4f2e0c44b96d5ad85f2754761b45bb6d65841451ef5dc9edb86/mypy-2.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:f8d97940a0259e09c219903579720b2df12170c0c3a3b3799837c1fb63deb44e", size = 10070720, upload-time = "2026-07-08T01:37:13.251Z" }, + { url = "https://files.pythonhosted.org/packages/96/2e/1ea8028583fef6561d146b51d738d91268201313ecf69e603e808a740e74/mypy-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea6fe1a30f3e7dc574d641497ffead2428046b0f8bc5804d13b4e4392fdc317b", size = 14739569, upload-time = "2026-07-08T01:35:33.202Z" }, + { url = "https://files.pythonhosted.org/packages/ba/67/c0607da57d78358b3b4fbfa90ee8ca5c6bd1dbb997c9648904ad4d8861d8/mypy-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6965829a6d847a0925f51149472bbeb7a39332fb4801972fdfd9cedd9f8d43a4", size = 13821442, upload-time = "2026-07-08T01:33:45.991Z" }, + { url = "https://files.pythonhosted.org/packages/bb/56/0407007d4ec7a762bac20724af1f0a57a9d860186c39e73105b6b8396fa2/mypy-2.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a906bfc9c4c5de3ece6dc4726f8076d56ce9be1720baf0c6f84e926c10262a4", size = 14049813, upload-time = "2026-07-08T01:35:44.282Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d1/d718e006c8fed4bece7a1bebeea6dcd05f31433af552fc45a82fef426379/mypy-2.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:91df92625cb3452758f27f4965b000fb05ad89b00c282cc3430a7bd6b0e5389e", size = 14978473, upload-time = "2026-07-08T01:36:54.064Z" }, + { url = "https://files.pythonhosted.org/packages/82/03/dae7299c45a84efb1590875f92652a5beb2da98a2cff9a567995e2583fe4/mypy-2.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d42893d15894fd34f395090e2d78315ba7c637d5ee221683e02893f578c2f548", size = 15224649, upload-time = "2026-07-08T01:35:15.988Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8e/738e4e73d030f20852a81383c74319ca4a9a4fdaadc3a75823588fe2c833/mypy-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3abaeec02cdc72e30a147d99eb81852b6b745a2c8d19607e25241d79b1abbce", size = 11049851, upload-time = "2026-07-08T01:34:39.31Z" }, + { url = "https://files.pythonhosted.org/packages/94/09/6c58caedb3fa5831a9b179687cd7dc252c66a61dca4800e5ba19c8eff82b/mypy-2.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:c39bdb7ceab252d15011e26d3a254b4aaa3bbf121b551febfa301df9b0c69abe", size = 10060307, upload-time = "2026-07-08T01:33:21.852Z" }, + { url = "https://files.pythonhosted.org/packages/d1/be/fbaba7b0ee89874fb11668416dec9e5585c190b676b0796cff26a9290fe8/mypy-2.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:484a2be712b245ac6e89847141f1f50c612b0a924aa25917e63e6cfcf4da07cd", size = 14928025, upload-time = "2026-07-08T01:37:24.376Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8f/f79a7c5a76671b0f563d4beaa7d99fe90df4500d2c1d2ba1be0432121bcf/mypy-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fb0a020dc68480d40e484675558ed637140df1ccbf896a81ba68bca85f2b50a0", size = 13793027, upload-time = "2026-07-08T01:34:33.937Z" }, + { url = "https://files.pythonhosted.org/packages/b2/b9/3db0086bab611d34e26061b86189e6f71de6d22a9b81699a93b006eabcf6/mypy-2.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc361340732ce7108fa0308812caf02bb6868f16112f1efd35bcad88badf3327", size = 14108322, upload-time = "2026-07-08T01:36:08.316Z" }, + { url = "https://files.pythonhosted.org/packages/58/29/4f1e13979a848de2a0fd385462354b58358b6e8b3d9661663e308f6e3d5d/mypy-2.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b0179a3a0b833f724a65f22613607cf7ea941ab17ec34fa283f8d6dfe21d9fa9", size = 15190198, upload-time = "2026-07-08T01:36:20.168Z" }, + { url = "https://files.pythonhosted.org/packages/14/f7/7759f6294d9d25d86671957d0974a215a2a24d429526e26a2f603de951c5/mypy-2.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e0899b13da1e4ba44b880550f247402ce90ffecc71c54b220bcbe7ecb34f394", size = 15424222, upload-time = "2026-07-08T01:33:39.398Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1b/05b212bef4d2234b5f0b551ea53ce0680d8075b2e79861c765f70b590945/mypy-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:511320b17467402e2906130e185abffffa3d7648aff1444fc2abb61f4c8a087d", size = 11135191, upload-time = "2026-07-08T01:35:03.019Z" }, + { url = "https://files.pythonhosted.org/packages/92/51/495e7122f6589948b36d3820a046461906756a0eb1b6dedc13ebfec7815e/mypy-2.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:7589f370b33dcdd95708f5340f13a67c2c49140957f934b42ef63064d343cca0", size = 10132502, upload-time = "2026-07-08T01:34:04.508Z" }, + { url = "https://files.pythonhosted.org/packages/a3/5f/2d7a9ac5646274cd6e77ce3abcc2a9ece760c2b21f4c4b9f301711e07855/mypy-2.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6968f27347ef539c443ddfd6897e79db525ddb8c856aa8fbf14c34f310ca5193", size = 14931618, upload-time = "2026-07-08T01:33:51.702Z" }, + { url = "https://files.pythonhosted.org/packages/b2/8a/1adaa7caaa104f87021b1ac71252d62e646e9b623d77900ac7a0ae252bf3/mypy-2.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3df226d2a0ae2c3b03845af217800a68e2965d4b14914c99b78d3a2c8ae23299", size = 13857718, upload-time = "2026-07-08T01:35:27.555Z" }, + { url = "https://files.pythonhosted.org/packages/1d/15/b11586b5aebbb82213e297fc30a6fcf3bed6a9deea3739cd8dd87621f3fd/mypy-2.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc53553996aca2094216ad9306a6f06c5265d206c1bcb54dd367560bd3557825", size = 14059704, upload-time = "2026-07-08T01:33:57.363Z" }, + { url = "https://files.pythonhosted.org/packages/03/db/071e05ab442596bdf7a845e830d5ef7128a0175281038245b171a6b16873/mypy-2.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:996abf2f0bebf572556c60720e8dc0cf5292b64060fa68d7f2bc9caa48e01b6f", size = 15128719, upload-time = "2026-07-08T01:33:33.855Z" }, + { url = "https://files.pythonhosted.org/packages/f3/1c/c4b84eafb85ee315da72471523cc1bf7d7c42164085c42333601da7a8817/mypy-2.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ec287c2381898c652bf8ff79448627fe1a9ee76d22005181fac7315a485c7108", size = 15378692, upload-time = "2026-07-08T01:34:10.468Z" }, + { url = "https://files.pythonhosted.org/packages/68/a4/59a0ee94877fdfe2958cec9b6add72a75393063c79cb60ab4026dd5e10c2/mypy-2.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:c2c967a7685fa93fcf1a778b3ebe76e756b28ba14655f539d7b61ff3da69352a", size = 11150911, upload-time = "2026-07-08T01:35:21.603Z" }, + { url = "https://files.pythonhosted.org/packages/90/e4/6a9144be50180ed43d8c92de9b03dff504daa92b5bcc0353e8960799a23b/mypy-2.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:d59a4b80351ec92e5f7415fcdd008bd77fcbefc7adf9cbc7ffe4eb9f71617734", size = 10125389, upload-time = "2026-07-08T01:36:36.164Z" }, + { url = "https://files.pythonhosted.org/packages/73/32/0aa8d8d197023ca6040f7b25a486cb47037b6350b0d3bae657c8f85fb43f/mypy-2.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1f6c3d76853071409ac58fc0aadfb276a22af5f190fdaa02152a858088a39ebd", size = 14926083, upload-time = "2026-07-08T01:36:02.365Z" }, + { url = "https://files.pythonhosted.org/packages/e2/7c/35bbe0cb10e6699f90e988e537aaf4282a6c16e37f58848a242eb0a98bde/mypy-2.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bdaa177e80cc3292824d4ef3670b5b58771ee8d57c290e0c9c89e7968212332c", size = 13879985, upload-time = "2026-07-08T01:36:31.093Z" }, + { url = "https://files.pythonhosted.org/packages/f9/0c/1597fbebd873e9b63452317740ae3dd32692cec5da180cc65acd96cd28cf/mypy-2.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80923e6d6e7878291f537ee11052f974954c20cb569798429a5dc265eb780b47", size = 14076883, upload-time = "2026-07-08T01:34:21.789Z" }, + { url = "https://files.pythonhosted.org/packages/68/35/2ec021a83ec01b5d522639f78d8b36adade7fa4821db0f48fd6d82e861f3/mypy-2.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f24bd465a09077c8d64be8f19a6646db467a55490fd315fe7871afe6bb9645", size = 15103567, upload-time = "2026-07-08T01:36:47.717Z" }, + { url = "https://files.pythonhosted.org/packages/53/3a/8cb3529f6d6800c7d069935e5c83a05d80263847b8a947cf6b0b16a9e958/mypy-2.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:db34595464869f474708e769413d1d739fc33a69850f253757b9a4cc20bc1fec", size = 15354641, upload-time = "2026-07-08T01:36:41.592Z" }, + { url = "https://files.pythonhosted.org/packages/d6/4d/320bc9a9553f8a9db5e847ec5ded762ef7ed7403c76c4ba2e8181c80e2f0/mypy-2.2.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:b48092132c7b0ef4322773fecae62fc5b0bc339be348badeec8af502122a4a51", size = 7694355, upload-time = "2026-07-08T01:37:03.291Z" }, + { url = "https://files.pythonhosted.org/packages/90/05/bf3b349e2f885cd3aab488111bb9049439c28bc028dac5073350d3df8fbe/mypy-2.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:6fc0e98b95e31755ca06d89f75fafa7820fbb3ea2caace6d83cba17625cd0acb", size = 11329146, upload-time = "2026-07-08T01:35:38.318Z" }, + { url = "https://files.pythonhosted.org/packages/41/a5/558b06e6cfe17ab88bb38f7b370b6bc68a74ba177c9e138db9748e422d2d/mypy-2.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:bc73a5b4d40e8a3e6b12ef82eb0c90430964e34016a36c2aff4e3bfe37ba41f0", size = 10316586, upload-time = "2026-07-08T01:36:25.458Z" }, + { url = "https://files.pythonhosted.org/packages/0b/21/f0b96f19a9b8ba111a45ffbe9508e818b7f6990469b38f6888943f7bfd3a/mypy-2.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6257bd4b4c0ae2148548b869a1ff3758e38645b92c8fe65eca401866c3c551c1", size = 15922565, upload-time = "2026-07-08T01:35:56.282Z" }, + { url = "https://files.pythonhosted.org/packages/18/f2/1dbcb20b0865d5e992541450a8c73f2fcc90f8bd7d8a4b81313e16934870/mypy-2.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:dfa22b3ae862ac1ce76f5976ddd402651b5f090bcfd49c6d0484b8983a29eaf8", size = 14816515, upload-time = "2026-07-08T01:34:58.167Z" }, + { url = "https://files.pythonhosted.org/packages/84/a2/18cce9c7d5b4d14010d1f13836da11b234dda917b17ca8671fc32c136997/mypy-2.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30a430bf26fe8cf372f3933fbd83e633d6561868803645a20e4e6d4523f52a3b", size = 15272246, upload-time = "2026-07-08T01:37:08.72Z" }, + { url = "https://files.pythonhosted.org/packages/ce/71/24d720c7924829bd675cbde2d0fa779f50abf676ca617f53d6a8bfef5fa7/mypy-2.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d58655a60e823b1a4c9ebcda072897fb0193c2f3e6f8e7c433e152aa4cb00233", size = 16226295, upload-time = "2026-07-08T01:34:51.861Z" }, + { url = "https://files.pythonhosted.org/packages/b7/5e/785730990fc863ad8340b4ab44ac4ca23270aecff92c180ccdf27f9f5869/mypy-2.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d4452c955caf14e28bb046cbd0c3671272e6381630a8b81b0da9713558148890", size = 16493275, upload-time = "2026-07-08T01:35:09.337Z" }, + { url = "https://files.pythonhosted.org/packages/93/33/55b1edf16f639f153972380d6977b81f65509c5b8f9c86b58b94b7990b03/mypy-2.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:68f5b7f7f755200f68c7181e3dfb28be9858162257690e539759c9f57721e388", size = 11749038, upload-time = "2026-07-08T01:35:50.071Z" }, + { url = "https://files.pythonhosted.org/packages/61/36/67424748a4e65e97f0e05bf00df379dfb6c2d817f82cc3a4ce5c96d99beb/mypy-2.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:78d201accfafce3801d978f2b8dbbd473a9ce364cc0a0dfd9192fe47d977e129", size = 10704254, upload-time = "2026-07-08T01:37:17.971Z" }, + { url = "https://files.pythonhosted.org/packages/28/cb/142c2097ca02c0d295b00625ff946808bdda65acda17d163c680d8a6a474/mypy-2.2.0-py3-none-any.whl", hash = "sha256:ecc138da861e932d1344214da4bae866b21900a9c2778824b51fe2fb47f5180e", size = 2726094, upload-time = "2026-07-08T01:34:00.075Z" }, ] [[package]] @@ -1578,12 +1584,12 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "jinja2", marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "mdit-py-plugins", marker = "python_full_version < '3.11'" }, - { name = "pyyaml", marker = "python_full_version < '3.11'" }, - { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" } }, + { name = "jinja2" }, + { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" } }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" } }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/a5/9626ba4f73555b3735ad86247a8077d4603aa8628537687c839ab08bfe44/myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4", size = 93985, upload-time = "2025-02-12T10:53:03.833Z" } wheels = [ @@ -1600,12 +1606,12 @@ resolution-markers = [ "python_full_version == '3.11.*'", ] dependencies = [ - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "jinja2", marker = "python_full_version >= '3.11'" }, - { name = "markdown-it-py", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "mdit-py-plugins", marker = "python_full_version >= '3.11'" }, - { name = "pyyaml", marker = "python_full_version >= '3.11'" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } }, + { name = "jinja2" }, + { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" } }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/fa/7b45eef11b7971f0beb29d27b7bfe0d747d063aa29e170d9edd004733c8a/myst_parser-5.0.0.tar.gz", hash = "sha256:f6f231452c56e8baa662cc352c548158f6a16fcbd6e3800fc594978002b94f3a", size = 98535, upload-time = "2026-01-15T09:08:18.036Z" } @@ -1615,7 +1621,7 @@ wheels = [ [[package]] name = "nf-core" -version = "4.0.3dev" +version = "4.0.3.dev0" source = { editable = "." } dependencies = [ { name = "click" }, @@ -1647,7 +1653,7 @@ dependencies = [ { name = "trogon" }, ] -[package.optional-dependencies] +[package.dev-dependencies] dev = [ { name = "mypy" }, { name = "myst-parser", version = "4.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, @@ -1684,8 +1690,6 @@ requires-dist = [ { name = "jinja2" }, { name = "jsonschema", specifier = ">=4.0" }, { name = "markdown", specifier = ">=3.3" }, - { name = "mypy", marker = "extra == 'dev'", specifier = ">=2.0.0" }, - { name = "myst-parser", marker = "extra == 'dev'" }, { name = "packaging" }, { name = "pdiff" }, { name = "pillow" }, @@ -1693,42 +1697,47 @@ requires-dist = [ { name = "prompt-toolkit", specifier = "<=3.0.52" }, { name = "pydantic", specifier = ">=2.2.1" }, { name = "pygithub" }, - { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" }, - { name = "pytest-asyncio", marker = "extra == 'dev'" }, - { name = "pytest-clarity", marker = "extra == 'dev'", specifier = ">=1.0.1" }, - { name = "pytest-cov", marker = "extra == 'dev'" }, - { name = "pytest-datafiles", marker = "extra == 'dev'" }, - { name = "pytest-sugar", marker = "extra == 'dev'", specifier = ">=1.1.1" }, - { name = "pytest-textual-snapshot", marker = "extra == 'dev'", specifier = "==1.1.0" }, - { name = "pytest-workflow", marker = "extra == 'dev'", specifier = ">=2.0.0" }, - { name = "pytest-xdist", marker = "extra == 'dev'", specifier = ">=3.7.0" }, { name = "pyyaml" }, { name = "questionary", specifier = ">=2.0.1" }, { name = "refgenie" }, { name = "repo2rocrate" }, { name = "requests" }, { name = "requests-cache" }, - { name = "responses", marker = "extra == 'dev'" }, { name = "rich", specifier = ">=13.3.1" }, { name = "rich-click", specifier = "==1.9.*" }, { name = "rocrate" }, { name = "ruamel-yaml" }, - { name = "ruff", marker = "extra == 'dev'" }, { name = "setuptools", specifier = "<81" }, - { name = "sphinx", marker = "extra == 'dev'" }, - { name = "sphinx-rtd-theme", marker = "extra == 'dev'" }, { name = "tabulate" }, { name = "textual", specifier = "==8.2.4" }, - { name = "textual-dev", marker = "extra == 'dev'", specifier = "==1.8.0" }, { name = "trogon" }, - { name = "types-jsonschema", marker = "extra == 'dev'" }, - { name = "types-markdown", marker = "extra == 'dev'" }, - { name = "types-pyyaml", marker = "extra == 'dev'" }, - { name = "types-requests", marker = "extra == 'dev'" }, - { name = "types-setuptools", marker = "extra == 'dev'" }, - { name = "typing-extensions", marker = "extra == 'dev'", specifier = ">=4.0.0" }, ] -provides-extras = ["dev"] + +[package.metadata.requires-dev] +dev = [ + { name = "mypy", specifier = ">=2.0.0" }, + { name = "myst-parser" }, + { name = "pytest", specifier = ">=8.0.0" }, + { name = "pytest-asyncio" }, + { name = "pytest-clarity", specifier = ">=1.0.1" }, + { name = "pytest-cov" }, + { name = "pytest-datafiles" }, + { name = "pytest-sugar", specifier = ">=1.1.1" }, + { name = "pytest-textual-snapshot", specifier = "==1.1.0" }, + { name = "pytest-workflow", specifier = ">=2.0.0" }, + { name = "pytest-xdist", specifier = ">=3.7.0" }, + { name = "responses" }, + { name = "ruff" }, + { name = "sphinx" }, + { name = "sphinx-rtd-theme" }, + { name = "textual-dev", specifier = "==1.8.0" }, + { name = "types-jsonschema" }, + { name = "types-markdown" }, + { name = "types-pyyaml" }, + { name = "types-requests" }, + { name = "types-setuptools" }, + { name = "typing-extensions", specifier = ">=4.0.0" }, +] [[package]] name = "numpy" @@ -2168,26 +2177,26 @@ wheels = [ [[package]] name = "prek" -version = "0.3.13" +version = "0.3.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3c/59/0a279983f96bd5d538b4975f0a23121082aa3b8560b6649fdf61f8011b07/prek-0.3.13.tar.gz", hash = "sha256:c48586ee3708bfbf3df80121f55583e9a7d0fa166b08172c091fe5971e92a0ac", size = 444848, upload-time = "2026-05-05T18:07:09.076Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/60/5b980c70525ca5f0d17942d8eae13b399051aa384413366fe5df229712ea/prek-0.3.11.tar.gz", hash = "sha256:c4cf77848009503c58d80ff216e32af45b63ea49652bb5546748c1ebfd4d9847", size = 433440, upload-time = "2026-04-27T04:22:59.923Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/6a/9baa2bda21dccc2927e952416f6cc23a75eb99c9ed18837164ac2e4a5640/prek-0.3.13-py3-none-linux_armv6l.whl", hash = "sha256:b00d38f01235073c35aa5f48df57fefef45a6cec2ae0884d750345a2c7220370", size = 5506622, upload-time = "2026-05-05T18:06:53.091Z" }, - { url = "https://files.pythonhosted.org/packages/56/77/d44b5d9bdca0879b865f8e47bf84cf5dc9e8b358d029e6d9b83d8809c116/prek-0.3.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0d89ac712c60e34d1550a606ad5fdfb8ad71d44ced8afa2fa5cbc106be4abd9e", size = 5878743, upload-time = "2026-05-05T18:07:23.164Z" }, - { url = "https://files.pythonhosted.org/packages/08/cf/19e8525cde8b3aa12858aca434d1fa653ef3b152da5af11eafc857634dc2/prek-0.3.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f9b5265863d18b5be4ea094fdce4fd6ca61a8c89a70ee3d8ee153b3e0ed6b272", size = 5434909, upload-time = "2026-05-05T18:07:25.276Z" }, - { url = "https://files.pythonhosted.org/packages/7a/9a/e5f97194782de4dab622ce09dafb3ebdd2ee4d354a83ac4def7ebeee236c/prek-0.3.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:64b59a1550780af2bba37297c704b17f81d8e9df6288af1fab4017938e33b1db", size = 5697536, upload-time = "2026-05-05T18:07:05.475Z" }, - { url = "https://files.pythonhosted.org/packages/c4/8c/e1f548ffc4b227e4c2b5a9b30f5978a7e0e6dad51305b97a2ba5b2a923e7/prek-0.3.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ce6cd8f114ba9bbdbe97422103fd886101949b1c42e588a7543c4436ead2020", size = 5428160, upload-time = "2026-05-05T18:07:01.489Z" }, - { url = "https://files.pythonhosted.org/packages/8a/44/abd919b00905a32d21dca2cec32c707860cf217da2431b62dd52684b310e/prek-0.3.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc03e924a24d8d961f56195853c8b206cb196be6db4ad8312125dae847d718ac", size = 5827275, upload-time = "2026-05-05T18:07:17.437Z" }, - { url = "https://files.pythonhosted.org/packages/af/ed/cafd2b80d58a83faf8371c6543bd1475a2224242a3294da7f8582f6aa551/prek-0.3.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ca8c526a23873177fb3b92013500b08ef5f8bedc7263f9f3a44dd2f49645a26", size = 6710293, upload-time = "2026-05-05T18:07:10.663Z" }, - { url = "https://files.pythonhosted.org/packages/35/09/52a4a27596b764173a34d74db09356b30faaacb4a1075b75adbc036a0008/prek-0.3.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5bbb175478438a871e3281d2c3c3f067288af73ad81707a9bdebfd769766c7d", size = 6096556, upload-time = "2026-05-05T18:07:19.46Z" }, - { url = "https://files.pythonhosted.org/packages/63/60/80f61729ce6498815d46d5580cf76da2c157c9b6494046183682441a0ea3/prek-0.3.13-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:a65327a014d838341af757dfc05a706d10e8e33f039bc32bb3dbe2fa21c440c0", size = 5693267, upload-time = "2026-05-05T18:07:03.66Z" }, - { url = "https://files.pythonhosted.org/packages/36/9d/c7a663fe70676ffab2e0c6c9a71997a3ccd002ed5bc60b7422a937911af0/prek-0.3.13-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:b6a200843a36a5b0c41764ce7639ccb3471d48b097f1c5e3fc8f034219b42626", size = 5532865, upload-time = "2026-05-05T18:07:15.237Z" }, - { url = "https://files.pythonhosted.org/packages/32/68/506ef5a235536030e16f61e7210474554f6e05f845f27df5877d2dbb1a06/prek-0.3.13-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:bdacaad8f35f343e063d251211fe34db1de9e5cc591795361ad69a6485202258", size = 5395951, upload-time = "2026-05-05T18:06:55.183Z" }, - { url = "https://files.pythonhosted.org/packages/3e/00/22d7c6db7f43b58f7d015913c12660c9bbc82751cff6cfd8c31993cf30eb/prek-0.3.13-py3-none-musllinux_1_1_i686.whl", hash = "sha256:f00328f1c520d8fefb910ab0d3c6764ee330d227952baa19b7e3de7242bd8b3b", size = 5681195, upload-time = "2026-05-05T18:07:12.804Z" }, - { url = "https://files.pythonhosted.org/packages/10/e3/fdf9882238796914ddaf11381a9083b374980156200a953324f6c795f34d/prek-0.3.13-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:e5530a867bcf5b172b7513a64e71b06a337d1d184696227ae953845867376b8d", size = 6212085, upload-time = "2026-05-05T18:07:07.213Z" }, - { url = "https://files.pythonhosted.org/packages/ca/1d/528759931344b5c7103085798f5fa2e86d27d9410b753a6bcbe7726aa8ba/prek-0.3.13-py3-none-win32.whl", hash = "sha256:326fac2bdce00074ce6c5046b861d310638aee2b9de1ed241ba7eb32bdc83898", size = 5199566, upload-time = "2026-05-05T18:07:21.416Z" }, - { url = "https://files.pythonhosted.org/packages/6b/d0/8715ee837c73314a02767d20652cc312d1b6ff6733fa00f52de2b648bc3a/prek-0.3.13-py3-none-win_amd64.whl", hash = "sha256:841049f89f5ec9f4035299283d11e566ac5a068e3742ead1055ea04f886831fc", size = 5589599, upload-time = "2026-05-05T18:06:57.28Z" }, - { url = "https://files.pythonhosted.org/packages/ff/cf/0af0b15be0ebd82f7e50adee149b05a73533d78cb1b97cb889f0647ebffe/prek-0.3.13-py3-none-win_arm64.whl", hash = "sha256:a9fd74e0aec550c6b8d41076fdcdd6ff121cd7d94d743c1338bd794784e3c775", size = 5419029, upload-time = "2026-05-05T18:06:59.645Z" }, + { url = "https://files.pythonhosted.org/packages/ee/2a/3392fa7d1fd1ce538915baa7597e7203bbe888367a8b15bfd51ca74d4714/prek-0.3.11-py3-none-linux_armv6l.whl", hash = "sha256:787e605716cfdc86ec01e7c5cf62799f39c28d49de5e37d75595c8e6248cb0f3", size = 5423112, upload-time = "2026-04-27T04:22:52.659Z" }, + { url = "https://files.pythonhosted.org/packages/a9/b0/3fc653b30b70d6c2714fc56bcfe1c2439437fc38f60b72bc300603ace4cd/prek-0.3.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ef1f37187ca52d75ba9c46b53007476c4eab2c3f11bd23defd57a81c62d90442", size = 5801382, upload-time = "2026-04-27T04:23:04.464Z" }, + { url = "https://files.pythonhosted.org/packages/2e/46/39aedc7843c3703f1f43b686622e4f8cd123e03b87a163e5c8f2fbd56cda/prek-0.3.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e0d0828a1b50447502ea1be3f5a84da474fdca558cd5d76a1a5205169bb808c7", size = 5370817, upload-time = "2026-04-27T04:22:49.277Z" }, + { url = "https://files.pythonhosted.org/packages/15/83/df5f3aeacbdea96a88c4f06c98d3932469711fed4e3bf5b703dd6507abe7/prek-0.3.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:bf49464b526ee36d2130baf60ab9580560bfaa60efd2997328e6d6671e209014", size = 5621405, upload-time = "2026-04-27T04:23:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/8f/f2/e32c9720747a327669863a4f92d05b9e6fadb851e903b0d7310a97c956a4/prek-0.3.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac344529f0d34757c7c95f65e66b9f6440a691f826eaf43f503247bd22023558", size = 5339780, upload-time = "2026-04-27T04:22:47.614Z" }, + { url = "https://files.pythonhosted.org/packages/29/2e/0e2f71b63bc2e5372575d5c1574b0666d2f90d30da51ed706a32cbf465a0/prek-0.3.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83672d963f249e2f246d3bec97f8fd2e8032e70da0a7d9acb2fa38af76dd82d2", size = 5735277, upload-time = "2026-04-27T04:23:12.437Z" }, + { url = "https://files.pythonhosted.org/packages/09/46/88abf51ac88eeff1ad2fe7d1797ca1fea43eb1ac1ddb8331463ac5b27ed2/prek-0.3.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef70957195d2896a30dd849e64f88344df7bb51af9c950cf16bd11519e7424b0", size = 6622420, upload-time = "2026-04-27T04:23:05.982Z" }, + { url = "https://files.pythonhosted.org/packages/5d/b6/592028a45b084a68b76c7edef909c789d1c96b26761388f63659beef7166/prek-0.3.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f0cc07d2cdb5fe2882015d5fdafc9af98b4c560d4caa1ae948caeab4341b79", size = 6020038, upload-time = "2026-04-27T04:22:54.367Z" }, + { url = "https://files.pythonhosted.org/packages/ca/f7/e97f55a1645a2e9becffeee28892ad8bb66cd144dabfa4392ea8e2674bbe/prek-0.3.11-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:d7554b436dae2ec97f4351a46817e3561657244307d1c0915f355b859f4fab71", size = 5622539, upload-time = "2026-04-27T04:23:01.314Z" }, + { url = "https://files.pythonhosted.org/packages/41/e2/f3119eef6b621782ad216a86d449609858ea34c57cf4a40fc6dc80556d7e/prek-0.3.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:caba5d635a5b64b7ac64d903f29b043ca5b0d9d9693543a0ef331ade89e6ad3f", size = 5440681, upload-time = "2026-04-27T04:23:07.422Z" }, + { url = "https://files.pythonhosted.org/packages/04/62/22dd4f59a47654faeebe74651182ecc48d436542646cc92723052dfd9a45/prek-0.3.11-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:c95a63f19dde48e84b70bd63a235670834af15fa4df8b85d8b7894dd5bc419a9", size = 5314773, upload-time = "2026-04-27T04:22:57.912Z" }, + { url = "https://files.pythonhosted.org/packages/bb/94/a8361462acb8d8f5b8505255b95ffbfc2ee0872a79b4e066eb330692f7be/prek-0.3.11-py3-none-musllinux_1_1_i686.whl", hash = "sha256:7353b45f44a386c676fe96ba72a5ee326b676f789339f405cf6f1d69a1707194", size = 5596208, upload-time = "2026-04-27T04:23:09.08Z" }, + { url = "https://files.pythonhosted.org/packages/04/0c/5f065b86bbeb9977074a055d8a05e90c7201f6c4c7032dada61739b5f8cb/prek-0.3.11-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:39f4e86176ccbb70c098df6abbc8e36c1d86cb81281abe92fb79dcd572418214", size = 6132833, upload-time = "2026-04-27T04:22:56.054Z" }, + { url = "https://files.pythonhosted.org/packages/19/0c/8ab0ae140201dcee505f58b60abbe56bd05ac96b821a6866f6f90c4d971f/prek-0.3.11-py3-none-win32.whl", hash = "sha256:35d2361049653a3dcf27227b7f1b340c5c42a12c0e0361c4b785921bfd125839", size = 5120856, upload-time = "2026-04-27T04:23:02.752Z" }, + { url = "https://files.pythonhosted.org/packages/57/05/9844c1125d3714f6f6c7b475884128a4b0c6c3ee0cd208ead44ca8174687/prek-0.3.11-py3-none-win_amd64.whl", hash = "sha256:a387689cd2e182f92dbb681151ee5a04f494fe97e95d6d783875da90b950e6d5", size = 5510916, upload-time = "2026-04-27T04:22:45.704Z" }, + { url = "https://files.pythonhosted.org/packages/ff/13/24b0288c553dc8d61f44c4d0746fe9bb1e1bd29d1e70571658536e4c0f72/prek-0.3.11-py3-none-win_arm64.whl", hash = "sha256:e4a8f900378a6657c7eb2fc4b12fa5c934edf209d0a24544539842479ec16e0b", size = 5345988, upload-time = "2026-04-27T04:22:50.918Z" }, ] [[package]] @@ -2355,7 +2364,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.13.4" +version = "2.13.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -2363,125 +2372,125 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d9/e4/40d09941a2cebcb20609b86a559817d5b9291c49dd6f8c87e5feffbe703a/pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d", size = 844068, upload-time = "2026-04-20T14:46:43.632Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, + { url = "https://files.pythonhosted.org/packages/f3/0a/fd7d723f8f8153418fb40cf9c940e82004fce7e987026b08a68a36dd3fe7/pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927", size = 471981, upload-time = "2026-04-20T14:46:41.402Z" }, ] [[package]] name = "pydantic-core" -version = "2.46.4" +version = "2.46.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/08/f1ba952f1c8ae5581c70fa9c6da89f247b83e3dd8c09c035d5d7931fc23d/pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4", size = 2113146, upload-time = "2026-05-06T13:37:36.537Z" }, - { url = "https://files.pythonhosted.org/packages/56/c6/65f646c7ff09bd257f660434adb45c4dfcbbcebcc030562fecf6f5bf887d/pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5", size = 1949769, upload-time = "2026-05-06T13:37:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/64/ba/bfb1d928fd5b49e1258935ff104ae356e9fd89384a55bf9f847e9193ad40/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba", size = 1974958, upload-time = "2026-05-06T13:37:28.611Z" }, - { url = "https://files.pythonhosted.org/packages/4e/74/76223bfb117b64af743c9b6670d1364516f5c0604f96b48f3272f6af6cc6/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b", size = 2042118, upload-time = "2026-05-06T13:36:55.216Z" }, - { url = "https://files.pythonhosted.org/packages/cb/7b/848732968bc8f48f3187542f08358b9d842db564147b256669426ebb1652/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c", size = 2222876, upload-time = "2026-05-06T13:38:25.455Z" }, - { url = "https://files.pythonhosted.org/packages/b5/2f/e90b63ee2e14bd8d3db8f705a6d75d64e6ee1b7c2c8833747ce706e1e0ce/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50", size = 2286703, upload-time = "2026-05-06T13:37:53.304Z" }, - { url = "https://files.pythonhosted.org/packages/ba/1e/acc4d70f88a0a277e4a1fa77ebb985ceabaf900430f875bf9338e11c9420/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd", size = 2092042, upload-time = "2026-05-06T13:38:46.981Z" }, - { url = "https://files.pythonhosted.org/packages/a9/da/0a422b57bf8504102bf3c4ccea9c41bab5a5cee6a54650acf8faf67f5a24/pydantic_core-2.46.4-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01", size = 2117231, upload-time = "2026-05-06T13:39:23.146Z" }, - { url = "https://files.pythonhosted.org/packages/bd/2a/2ac13c3af305843e23c5078c53d135656b3f05a2fd78cb7bbbb12e97b473/pydantic_core-2.46.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d", size = 2168388, upload-time = "2026-05-06T13:40:08.06Z" }, - { url = "https://files.pythonhosted.org/packages/72/04/2beacf7e1607e93eefe4aed1b4709f079b905fb77530179d4f7c71745f22/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4", size = 2184769, upload-time = "2026-05-06T13:38:13.901Z" }, - { url = "https://files.pythonhosted.org/packages/9e/29/d2b9fd9f539133548eaf622c06a4ce176cb46ac59f32d0359c4abc0de047/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f", size = 2319312, upload-time = "2026-05-06T13:39:08.24Z" }, - { url = "https://files.pythonhosted.org/packages/7c/af/0f7a5b85fec6075bea96e3ef9187de38fccced0de92c1e7feda8d5cc7bb9/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39", size = 2361817, upload-time = "2026-05-06T13:38:43.2Z" }, - { url = "https://files.pythonhosted.org/packages/25/a4/73363fec545fd3ec025490bdda2743c56d0dd5b6266b1a53bbe9e4265375/pydantic_core-2.46.4-cp310-cp310-win32.whl", hash = "sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d", size = 1987085, upload-time = "2026-05-06T13:39:25.497Z" }, - { url = "https://files.pythonhosted.org/packages/01/aa/62f082da2c91fac1c234bc9ee0066257ce83f0604abd72e4c9d5991f2d84/pydantic_core-2.46.4-cp310-cp310-win_amd64.whl", hash = "sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf", size = 2074311, upload-time = "2026-05-06T13:39:59.922Z" }, - { url = "https://files.pythonhosted.org/packages/5c/fa/6d7708d2cfc1a832acb6aeb0cd16e801902df8a0f583bb3b4b527fde022e/pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594", size = 2111872, upload-time = "2026-05-06T13:40:27.596Z" }, - { url = "https://files.pythonhosted.org/packages/ae/6f/aa064a3e74b5745afbdf250594f38e7ead05e2d651bcb35994b9417a0d4d/pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c", size = 1948255, upload-time = "2026-05-06T13:39:12.574Z" }, - { url = "https://files.pythonhosted.org/packages/43/3a/41114a9f7569b84b4d84e7a018c57c56347dac30c0d4a872946ec4e36c46/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826", size = 1972827, upload-time = "2026-05-06T13:38:19.841Z" }, - { url = "https://files.pythonhosted.org/packages/ef/25/1ab42e8048fe551934d9884e8d64daa7e990ad386f310a15981aeb6a5b08/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04", size = 2041051, upload-time = "2026-05-06T13:38:10.447Z" }, - { url = "https://files.pythonhosted.org/packages/94/c2/1a934597ddf08da410385b3b7aae91956a5a76c635effef456074fad7e88/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e", size = 2221314, upload-time = "2026-05-06T13:40:13.089Z" }, - { url = "https://files.pythonhosted.org/packages/02/6d/9e8ad178c9c4df27ad3c8f25d1fe2a7ab0d2ba0559fad4aee5d3d1f16771/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3", size = 2285146, upload-time = "2026-05-06T13:38:59.224Z" }, - { url = "https://files.pythonhosted.org/packages/80/50/540cd3aeefc041beb111125c4bff779831a2111fc6b15a9138cda277d32c/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4", size = 2089685, upload-time = "2026-05-06T13:38:17.762Z" }, - { url = "https://files.pythonhosted.org/packages/6b/a4/b440ad35f05f6a38f89fa0f149accb3f0e02be94ca5e15f3c449a61b4bc9/pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398", size = 2115420, upload-time = "2026-05-06T13:37:58.195Z" }, - { url = "https://files.pythonhosted.org/packages/99/61/de4f55db8dfd57bfdfa9a12ec90fe1b57c4f41062f7ca86f08586b3e0ac0/pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3", size = 2165122, upload-time = "2026-05-06T13:37:01.167Z" }, - { url = "https://files.pythonhosted.org/packages/f7/52/7c529d7bdb2d1068bd52f51fe32572c8301f9a4febf1948f10639f1436f5/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848", size = 2182573, upload-time = "2026-05-06T13:38:45.04Z" }, - { url = "https://files.pythonhosted.org/packages/37/b3/7c40325848ba78247f2812dcf9c7274e38cd801820ca6dd9fe63bcfb0eb4/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3", size = 2317139, upload-time = "2026-05-06T13:37:15.539Z" }, - { url = "https://files.pythonhosted.org/packages/d9/37/f913f81a657c865b75da6c0dbed79876073c2a43b5bd9edbe8da785e4d49/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109", size = 2360433, upload-time = "2026-05-06T13:37:30.099Z" }, - { url = "https://files.pythonhosted.org/packages/c4/67/6acaa1be2567f9256b056d8477158cac7240813956ce86e49deae8e173b4/pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda", size = 1985513, upload-time = "2026-05-06T13:38:15.669Z" }, - { url = "https://files.pythonhosted.org/packages/aa/e6/c505f83dfeda9a2e5c995cfd872949e4d05e12f7feb3dca72f633daefa94/pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33", size = 2071114, upload-time = "2026-05-06T13:40:35.416Z" }, - { url = "https://files.pythonhosted.org/packages/0f/da/7a263a96d965d9d0df5e8de8a475f33495451117035b09acb110288c381f/pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d", size = 2044298, upload-time = "2026-05-06T13:38:29.754Z" }, - { url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" }, - { url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" }, - { url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" }, - { url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" }, - { url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" }, - { url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" }, - { url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" }, - { url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" }, - { url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" }, - { url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" }, - { url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" }, - { url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" }, - { url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" }, - { url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" }, - { url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" }, - { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, - { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, - { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, - { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, - { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, - { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, - { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, - { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, - { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, - { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, - { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, - { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, - { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, - { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, - { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, - { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, - { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, - { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, - { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, - { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, - { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, - { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, - { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, - { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, - { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, - { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, - { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, - { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, - { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, - { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, - { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, - { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, - { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, - { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, - { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, - { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, - { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, - { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, - { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, - { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, - { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, - { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, - { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, - { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, - { url = "https://files.pythonhosted.org/packages/ee/a4/73995fd4ebbb46ba0ee51e6fa049b8f02c40daebb762208feda8a6b7894d/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c", size = 2111589, upload-time = "2026-05-06T13:37:10.817Z" }, - { url = "https://files.pythonhosted.org/packages/fb/7f/f37d3a5e8bfcc2e403f5c57a730f2d815693fb42119e8ea48b3789335af1/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b", size = 1944552, upload-time = "2026-05-06T13:36:56.717Z" }, - { url = "https://files.pythonhosted.org/packages/15/3c/d7eb777b3ff43e8433a4efb39a17aa8fd98a4ee8561a24a67ef5db07b2d6/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b", size = 1982984, upload-time = "2026-05-06T13:39:06.207Z" }, - { url = "https://files.pythonhosted.org/packages/63/87/70b9f40170a81afd55ca26c9b2acb25c20d64bcfbf888fafecb3ba077d4c/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea", size = 2138417, upload-time = "2026-05-06T13:39:45.476Z" }, - { url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" }, - { url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" }, - { url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" }, - { url = "https://files.pythonhosted.org/packages/11/cb/428de0385b6c8d44b716feba566abfacfbd23ee3c4439faa789a1456242f/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0", size = 2112782, upload-time = "2026-05-06T13:37:04.016Z" }, - { url = "https://files.pythonhosted.org/packages/0b/b5/6a17bdadd0fc1f170adfd05a20d37c832f52b117b4d9131da1f41bb097ce/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7", size = 1952146, upload-time = "2026-05-06T13:39:43.092Z" }, - { url = "https://files.pythonhosted.org/packages/2a/dc/03734d80e362cd43ef65428e9de77c730ce7f2f11c60d2b1e1b39f0fbf99/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2", size = 2134492, upload-time = "2026-05-06T13:36:58.124Z" }, - { url = "https://files.pythonhosted.org/packages/de/df/5e5ffc085ed07cc22d298134d3d911c63e91f6a0eb91fe646750a3209910/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9", size = 2156604, upload-time = "2026-05-06T13:37:49.88Z" }, - { url = "https://files.pythonhosted.org/packages/81/44/6e112a4253e56f5705467cbab7ab5e91ee7398ba3d56d358635958893d3e/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf", size = 2183828, upload-time = "2026-05-06T13:37:43.053Z" }, - { url = "https://files.pythonhosted.org/packages/ac/ad/5565071e937d8e752842ac241463944c9eb14c87e2d269f2658a5bd05e98/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30", size = 2310000, upload-time = "2026-05-06T13:37:56.694Z" }, - { url = "https://files.pythonhosted.org/packages/4f/c3/66883a5cec183e7fba4d024b4cbbe61851a63750ef606b0afecc46d1f2bf/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc", size = 2361286, upload-time = "2026-05-06T13:40:05.667Z" }, - { url = "https://files.pythonhosted.org/packages/4b/2d/69abac8f838090bbecd5df894befb2c2619e7996a98ddb949db9f3b93225/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983", size = 2193071, upload-time = "2026-05-06T13:38:08.682Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/2a/ef/f7abb56c49382a246fd2ce9c799691e3c3e7175ec74b14d99e798bcddb1a/pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c", size = 471412, upload-time = "2026-04-20T14:40:56.672Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/98/b50eb9a411e87483b5c65dba4fa430a06bac4234d3403a40e5a9905ebcd0/pydantic_core-2.46.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1", size = 2108971, upload-time = "2026-04-20T14:43:51.945Z" }, + { url = "https://files.pythonhosted.org/packages/08/4b/f364b9d161718ff2217160a4b5d41ce38de60aed91c3689ebffa1c939d23/pydantic_core-2.46.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f", size = 1949588, upload-time = "2026-04-20T14:44:10.386Z" }, + { url = "https://files.pythonhosted.org/packages/8f/8b/30bd03ee83b2f5e29f5ba8e647ab3c456bf56f2ec72fdbcc0215484a0854/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3", size = 1975986, upload-time = "2026-04-20T14:43:57.106Z" }, + { url = "https://files.pythonhosted.org/packages/3c/54/13ccf954d84ec275d5d023d5786e4aa48840bc9f161f2838dc98e1153518/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a", size = 2055830, upload-time = "2026-04-20T14:44:15.499Z" }, + { url = "https://files.pythonhosted.org/packages/be/0e/65f38125e660fdbd72aa858e7dfae893645cfa0e7b13d333e174a367cd23/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807", size = 2222340, upload-time = "2026-04-20T14:41:51.353Z" }, + { url = "https://files.pythonhosted.org/packages/d1/88/f3ab7739efe0e7e80777dbb84c59eb98518e3f57ea433206194c2e425272/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda", size = 2280727, upload-time = "2026-04-20T14:41:30.461Z" }, + { url = "https://files.pythonhosted.org/packages/2a/6d/c228219080817bec4982f9531cadb18da6aaa770fdeb114f49c237ac2c9f/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57", size = 2092158, upload-time = "2026-04-20T14:44:07.305Z" }, + { url = "https://files.pythonhosted.org/packages/0f/b1/525a16711e7c6d61635fac3b0bd54600b5c5d9f60c6fc5aaab26b64a2297/pydantic_core-2.46.3-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045", size = 2116626, upload-time = "2026-04-20T14:42:34.118Z" }, + { url = "https://files.pythonhosted.org/packages/ef/7c/17d30673351439a6951bf54f564cf2443ab00ae264ec9df00e2efd710eb5/pydantic_core-2.46.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943", size = 2160691, upload-time = "2026-04-20T14:41:14.023Z" }, + { url = "https://files.pythonhosted.org/packages/86/66/af8adbcbc0886ead7f1a116606a534d75a307e71e6e08226000d51b880d2/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f", size = 2182543, upload-time = "2026-04-20T14:40:48.886Z" }, + { url = "https://files.pythonhosted.org/packages/b0/37/6de71e0f54c54a4190010f57deb749e1ddf75c568ada3b1320b70067f121/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4", size = 2324513, upload-time = "2026-04-20T14:42:36.121Z" }, + { url = "https://files.pythonhosted.org/packages/51/b1/9fc74ce94f603d5ef59ff258ca9c2c8fb902fb548d340a96f77f4d1c3b7f/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a", size = 2361853, upload-time = "2026-04-20T14:43:24.886Z" }, + { url = "https://files.pythonhosted.org/packages/40/d0/4c652fc592db35f100279ee751d5a145aca1b9a7984b9684ba7c1b5b0535/pydantic_core-2.46.3-cp310-cp310-win32.whl", hash = "sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7", size = 1980465, upload-time = "2026-04-20T14:44:46.239Z" }, + { url = "https://files.pythonhosted.org/packages/27/b8/a920453c38afbe1f355e1ea0b0d94a0a3e0b0879d32d793108755fa171d5/pydantic_core-2.46.3-cp310-cp310-win_amd64.whl", hash = "sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6", size = 2073884, upload-time = "2026-04-20T14:43:01.201Z" }, + { url = "https://files.pythonhosted.org/packages/22/a2/1ba90a83e85a3f94c796b184f3efde9c72f2830dcda493eea8d59ba78e6d/pydantic_core-2.46.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5", size = 2106740, upload-time = "2026-04-20T14:41:20.932Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f6/99ae893c89a0b9d3daec9f95487aa676709aa83f67643b3f0abaf4ab628a/pydantic_core-2.46.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c", size = 1948293, upload-time = "2026-04-20T14:43:42.115Z" }, + { url = "https://files.pythonhosted.org/packages/3e/b8/2e8e636dc9e3f16c2e16bf0849e24be82c5ee82c603c65fc0326666328fc/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e", size = 1973222, upload-time = "2026-04-20T14:41:57.841Z" }, + { url = "https://files.pythonhosted.org/packages/34/36/0e730beec4d83c5306f417afbd82ff237d9a21e83c5edf675f31ed84c1fe/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287", size = 2053852, upload-time = "2026-04-20T14:40:43.077Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f0/3071131f47e39136a17814576e0fada9168569f7f8c0e6ac4d1ede6a4958/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe", size = 2221134, upload-time = "2026-04-20T14:43:03.349Z" }, + { url = "https://files.pythonhosted.org/packages/2f/a9/a2dc023eec5aa4b02a467874bad32e2446957d2adcab14e107eab502e978/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050", size = 2279785, upload-time = "2026-04-20T14:41:19.285Z" }, + { url = "https://files.pythonhosted.org/packages/0a/44/93f489d16fb63fbd41c670441536541f6e8cfa1e5a69f40bc9c5d30d8c90/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2", size = 2089404, upload-time = "2026-04-20T14:43:10.108Z" }, + { url = "https://files.pythonhosted.org/packages/2a/78/8692e3aa72b2d004f7a5d937f1dfdc8552ba26caf0bec75f342c40f00dec/pydantic_core-2.46.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa", size = 2114898, upload-time = "2026-04-20T14:44:51.475Z" }, + { url = "https://files.pythonhosted.org/packages/6a/62/e83133f2e7832532060175cebf1f13748f4c7e7e7165cdd1f611f174494b/pydantic_core-2.46.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c", size = 2157856, upload-time = "2026-04-20T14:43:46.64Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ec/6a500e3ad7718ee50583fae79c8651f5d37e3abce1fa9ae177ae65842c53/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf", size = 2180168, upload-time = "2026-04-20T14:42:00.302Z" }, + { url = "https://files.pythonhosted.org/packages/d8/53/8267811054b1aa7fc1dc7ded93812372ef79a839f5e23558136a6afbfde1/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b", size = 2322885, upload-time = "2026-04-20T14:41:05.253Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c1/1c0acdb3aa0856ddc4ecc55214578f896f2de16f400cf51627eb3c26c1c4/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e", size = 2360328, upload-time = "2026-04-20T14:41:43.991Z" }, + { url = "https://files.pythonhosted.org/packages/f0/d0/ef39cd0f4a926814f360e71c1adeab48ad214d9727e4deb48eedfb5bce1a/pydantic_core-2.46.3-cp311-cp311-win32.whl", hash = "sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb", size = 1979464, upload-time = "2026-04-20T14:43:12.215Z" }, + { url = "https://files.pythonhosted.org/packages/18/9c/f41951b0d858e343f1cf09398b2a7b3014013799744f2c4a8ad6a3eec4f2/pydantic_core-2.46.3-cp311-cp311-win_amd64.whl", hash = "sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346", size = 2070837, upload-time = "2026-04-20T14:41:47.707Z" }, + { url = "https://files.pythonhosted.org/packages/9f/1e/264a17cd582f6ed50950d4d03dd5fefd84e570e238afe1cb3e25cf238769/pydantic_core-2.46.3-cp311-cp311-win_arm64.whl", hash = "sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6", size = 2053647, upload-time = "2026-04-20T14:42:27.535Z" }, + { url = "https://files.pythonhosted.org/packages/4b/cb/5b47425556ecc1f3fe18ed2a0083188aa46e1dd812b06e406475b3a5d536/pydantic_core-2.46.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67", size = 2101946, upload-time = "2026-04-20T14:40:52.581Z" }, + { url = "https://files.pythonhosted.org/packages/a1/4f/2fb62c2267cae99b815bbf4a7b9283812c88ca3153ef29f7707200f1d4e5/pydantic_core-2.46.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089", size = 1951612, upload-time = "2026-04-20T14:42:42.996Z" }, + { url = "https://files.pythonhosted.org/packages/50/6e/b7348fd30d6556d132cddd5bd79f37f96f2601fe0608afac4f5fb01ec0b3/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0", size = 1977027, upload-time = "2026-04-20T14:42:02.001Z" }, + { url = "https://files.pythonhosted.org/packages/82/11/31d60ee2b45540d3fb0b29302a393dbc01cd771c473f5b5147bcd353e593/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789", size = 2063008, upload-time = "2026-04-20T14:44:17.952Z" }, + { url = "https://files.pythonhosted.org/packages/8a/db/3a9d1957181b59258f44a2300ab0f0be9d1e12d662a4f57bb31250455c52/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d", size = 2233082, upload-time = "2026-04-20T14:40:57.934Z" }, + { url = "https://files.pythonhosted.org/packages/9c/e1/3277c38792aeb5cfb18c2f0c5785a221d9ff4e149abbe1184d53d5f72273/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c", size = 2304615, upload-time = "2026-04-20T14:42:12.584Z" }, + { url = "https://files.pythonhosted.org/packages/5e/d5/e3d9717c9eba10855325650afd2a9cba8e607321697f18953af9d562da2f/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395", size = 2094380, upload-time = "2026-04-20T14:43:05.522Z" }, + { url = "https://files.pythonhosted.org/packages/a1/20/abac35dedcbfd66c6f0b03e4e3564511771d6c9b7ede10a362d03e110d9b/pydantic_core-2.46.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396", size = 2135429, upload-time = "2026-04-20T14:41:55.549Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a5/41bfd1df69afad71b5cf0535055bccc73022715ad362edbc124bc1e021d7/pydantic_core-2.46.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d", size = 2174582, upload-time = "2026-04-20T14:41:45.96Z" }, + { url = "https://files.pythonhosted.org/packages/79/65/38d86ea056b29b2b10734eb23329b7a7672ca604df4f2b6e9c02d4ee22fe/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca", size = 2187533, upload-time = "2026-04-20T14:40:55.367Z" }, + { url = "https://files.pythonhosted.org/packages/b6/55/a1129141678a2026badc539ad1dee0a71d06f54c2f06a4bd68c030ac781b/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976", size = 2332985, upload-time = "2026-04-20T14:44:13.05Z" }, + { url = "https://files.pythonhosted.org/packages/d7/60/cb26f4077719f709e54819f4e8e1d43f4091f94e285eb6bd21e1190a7b7c/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b", size = 2373670, upload-time = "2026-04-20T14:41:53.421Z" }, + { url = "https://files.pythonhosted.org/packages/6b/7e/c3f21882bdf1d8d086876f81b5e296206c69c6082551d776895de7801fa0/pydantic_core-2.46.3-cp312-cp312-win32.whl", hash = "sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4", size = 1966722, upload-time = "2026-04-20T14:44:30.588Z" }, + { url = "https://files.pythonhosted.org/packages/57/be/6b5e757b859013ebfbd7adba02f23b428f37c86dcbf78b5bb0b4ffd36e99/pydantic_core-2.46.3-cp312-cp312-win_amd64.whl", hash = "sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1", size = 2072970, upload-time = "2026-04-20T14:42:54.248Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f8/a989b21cc75e9a32d24192ef700eea606521221a89faa40c919ce884f2b1/pydantic_core-2.46.3-cp312-cp312-win_arm64.whl", hash = "sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72", size = 2035963, upload-time = "2026-04-20T14:44:20.4Z" }, + { url = "https://files.pythonhosted.org/packages/9b/3c/9b5e8eb9821936d065439c3b0fb1490ffa64163bfe7e1595985a47896073/pydantic_core-2.46.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37", size = 2102109, upload-time = "2026-04-20T14:41:24.219Z" }, + { url = "https://files.pythonhosted.org/packages/91/97/1c41d1f5a19f241d8069f1e249853bcce378cdb76eec8ab636d7bc426280/pydantic_core-2.46.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f", size = 1951820, upload-time = "2026-04-20T14:42:14.236Z" }, + { url = "https://files.pythonhosted.org/packages/30/b4/d03a7ae14571bc2b6b3c7b122441154720619afe9a336fa3a95434df5e2f/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8", size = 1977785, upload-time = "2026-04-20T14:42:31.648Z" }, + { url = "https://files.pythonhosted.org/packages/ae/0c/4086f808834b59e3c8f1aa26df8f4b6d998cdcf354a143d18ef41529d1fe/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad", size = 2062761, upload-time = "2026-04-20T14:40:37.093Z" }, + { url = "https://files.pythonhosted.org/packages/fa/71/a649be5a5064c2df0db06e0a512c2281134ed2fcc981f52a657936a7527c/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c", size = 2232989, upload-time = "2026-04-20T14:42:59.254Z" }, + { url = "https://files.pythonhosted.org/packages/a2/84/7756e75763e810b3a710f4724441d1ecc5883b94aacb07ca71c5fb5cfb69/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f", size = 2303975, upload-time = "2026-04-20T14:41:32.287Z" }, + { url = "https://files.pythonhosted.org/packages/6c/35/68a762e0c1e31f35fa0dac733cbd9f5b118042853698de9509c8e5bf128b/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35", size = 2095325, upload-time = "2026-04-20T14:42:47.685Z" }, + { url = "https://files.pythonhosted.org/packages/77/bf/1bf8c9a8e91836c926eae5e3e51dce009bf495a60ca56060689d3df3f340/pydantic_core-2.46.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687", size = 2133368, upload-time = "2026-04-20T14:41:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/e5/50/87d818d6bab915984995157ceb2380f5aac4e563dddbed6b56f0ed057aba/pydantic_core-2.46.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3", size = 2173908, upload-time = "2026-04-20T14:42:52.044Z" }, + { url = "https://files.pythonhosted.org/packages/91/88/a311fb306d0bd6185db41fa14ae888fb81d0baf648a761ae760d30819d33/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022", size = 2186422, upload-time = "2026-04-20T14:43:29.55Z" }, + { url = "https://files.pythonhosted.org/packages/8f/79/28fd0d81508525ab2054fef7c77a638c8b5b0afcbbaeee493cf7c3fef7e1/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23", size = 2332709, upload-time = "2026-04-20T14:42:16.134Z" }, + { url = "https://files.pythonhosted.org/packages/b3/21/795bf5fe5c0f379308b8ef19c50dedab2e7711dbc8d0c2acf08f1c7daa05/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7", size = 2372428, upload-time = "2026-04-20T14:41:10.974Z" }, + { url = "https://files.pythonhosted.org/packages/45/b3/ed14c659cbe7605e3ef063077680a64680aec81eb1a04763a05190d49b7f/pydantic_core-2.46.3-cp313-cp313-win32.whl", hash = "sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13", size = 1965601, upload-time = "2026-04-20T14:41:42.128Z" }, + { url = "https://files.pythonhosted.org/packages/ef/bb/adb70d9a762ddd002d723fbf1bd492244d37da41e3af7b74ad212609027e/pydantic_core-2.46.3-cp313-cp313-win_amd64.whl", hash = "sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0", size = 2071517, upload-time = "2026-04-20T14:43:36.096Z" }, + { url = "https://files.pythonhosted.org/packages/52/eb/66faefabebfe68bd7788339c9c9127231e680b11906368c67ce112fdb47f/pydantic_core-2.46.3-cp313-cp313-win_arm64.whl", hash = "sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec", size = 2035802, upload-time = "2026-04-20T14:43:38.507Z" }, + { url = "https://files.pythonhosted.org/packages/7f/db/a7bcb4940183fda36022cd18ba8dd12f2dff40740ec7b58ce7457befa416/pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b", size = 2097614, upload-time = "2026-04-20T14:44:38.374Z" }, + { url = "https://files.pythonhosted.org/packages/24/35/e4066358a22e3e99519db370494c7528f5a2aa1367370e80e27e20283543/pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018", size = 1951896, upload-time = "2026-04-20T14:40:53.996Z" }, + { url = "https://files.pythonhosted.org/packages/87/92/37cf4049d1636996e4b888c05a501f40a43ff218983a551d57f9d5e14f0d/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34", size = 1979314, upload-time = "2026-04-20T14:41:49.446Z" }, + { url = "https://files.pythonhosted.org/packages/d8/36/9ff4d676dfbdfb2d591cf43f3d90ded01e15b1404fd101180ed2d62a2fd3/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7", size = 2056133, upload-time = "2026-04-20T14:42:23.574Z" }, + { url = "https://files.pythonhosted.org/packages/bc/f0/405b442a4d7ba855b06eec8b2bf9c617d43b8432d099dfdc7bf999293495/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2", size = 2228726, upload-time = "2026-04-20T14:44:22.816Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f8/65cd92dd5a0bd89ba277a98ecbfaf6fc36bbd3300973c7a4b826d6ab1391/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba", size = 2301214, upload-time = "2026-04-20T14:44:48.792Z" }, + { url = "https://files.pythonhosted.org/packages/fd/86/ef96a4c6e79e7a2d0410826a68fbc0eccc0fd44aa733be199d5fcac3bb87/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f", size = 2099927, upload-time = "2026-04-20T14:41:40.196Z" }, + { url = "https://files.pythonhosted.org/packages/6d/53/269caf30e0096e0a8a8f929d1982a27b3879872cca2d917d17c2f9fdf4fe/pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22", size = 2128789, upload-time = "2026-04-20T14:41:15.868Z" }, + { url = "https://files.pythonhosted.org/packages/00/b0/1a6d9b6a587e118482910c244a1c5acf4d192604174132efd12bf0ac486f/pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f", size = 2173815, upload-time = "2026-04-20T14:44:25.152Z" }, + { url = "https://files.pythonhosted.org/packages/87/56/e7e00d4041a7e62b5a40815590114db3b535bf3ca0bf4dca9f16cef25246/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127", size = 2181608, upload-time = "2026-04-20T14:41:28.933Z" }, + { url = "https://files.pythonhosted.org/packages/e8/22/4bd23c3d41f7c185d60808a1de83c76cf5aeabf792f6c636a55c3b1ec7f9/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c", size = 2326968, upload-time = "2026-04-20T14:42:03.962Z" }, + { url = "https://files.pythonhosted.org/packages/24/ac/66cd45129e3915e5ade3b292cb3bc7fd537f58f8f8dbdaba6170f7cabb74/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1", size = 2369842, upload-time = "2026-04-20T14:41:35.52Z" }, + { url = "https://files.pythonhosted.org/packages/a2/51/dd4248abb84113615473aa20d5545b7c4cd73c8644003b5259686f93996c/pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505", size = 1959661, upload-time = "2026-04-20T14:41:00.042Z" }, + { url = "https://files.pythonhosted.org/packages/20/eb/59980e5f1ae54a3b86372bd9f0fa373ea2d402e8cdcd3459334430f91e91/pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e", size = 2071686, upload-time = "2026-04-20T14:43:16.471Z" }, + { url = "https://files.pythonhosted.org/packages/8c/db/1cf77e5247047dfee34bc01fa9bca134854f528c8eb053e144298893d370/pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df", size = 2026907, upload-time = "2026-04-20T14:43:31.732Z" }, + { url = "https://files.pythonhosted.org/packages/57/c0/b3df9f6a543276eadba0a48487b082ca1f201745329d97dbfa287034a230/pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf", size = 2095047, upload-time = "2026-04-20T14:42:37.982Z" }, + { url = "https://files.pythonhosted.org/packages/66/57/886a938073b97556c168fd99e1a7305bb363cd30a6d2c76086bf0587b32a/pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee", size = 1934329, upload-time = "2026-04-20T14:43:49.655Z" }, + { url = "https://files.pythonhosted.org/packages/0b/7c/b42eaa5c34b13b07ecb51da21761297a9b8eb43044c864a035999998f328/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a", size = 1974847, upload-time = "2026-04-20T14:42:10.737Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9b/92b42db6543e7de4f99ae977101a2967b63122d4b6cf7773812da2d7d5b5/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c", size = 2041742, upload-time = "2026-04-20T14:40:44.262Z" }, + { url = "https://files.pythonhosted.org/packages/0f/19/46fbe1efabb5aa2834b43b9454e70f9a83ad9c338c1291e48bdc4fecf167/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1", size = 2236235, upload-time = "2026-04-20T14:41:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/77/da/b3f95bc009ad60ec53120f5d16c6faa8cabdbe8a20d83849a1f2b8728148/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64", size = 2282633, upload-time = "2026-04-20T14:44:33.271Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6e/401336117722e28f32fb8220df676769d28ebdf08f2f4469646d404c43a3/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb", size = 2109679, upload-time = "2026-04-20T14:44:41.065Z" }, + { url = "https://files.pythonhosted.org/packages/fc/53/b289f9bc8756a32fe718c46f55afaeaf8d489ee18d1a1e7be1db73f42cc4/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6", size = 2108342, upload-time = "2026-04-20T14:42:50.144Z" }, + { url = "https://files.pythonhosted.org/packages/10/5b/8292fc7c1f9111f1b2b7c1b0dcf1179edcd014fc3ea4517499f50b829d71/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c", size = 2157208, upload-time = "2026-04-20T14:42:08.133Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9e/f80044e9ec07580f057a89fc131f78dda7a58751ddf52bbe05eaf31db50f/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47", size = 2167237, upload-time = "2026-04-20T14:42:25.412Z" }, + { url = "https://files.pythonhosted.org/packages/f8/84/6781a1b037f3b96be9227edbd1101f6d3946746056231bf4ac48cdff1a8d/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab", size = 2312540, upload-time = "2026-04-20T14:40:40.313Z" }, + { url = "https://files.pythonhosted.org/packages/3e/db/19c0839feeb728e7df03255581f198dfdf1c2aeb1e174a8420b63c5252e5/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba", size = 2369556, upload-time = "2026-04-20T14:41:09.427Z" }, + { url = "https://files.pythonhosted.org/packages/e0/15/3228774cb7cd45f5f721ddf1b2242747f4eb834d0c491f0c02d606f09fed/pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56", size = 1949756, upload-time = "2026-04-20T14:41:25.717Z" }, + { url = "https://files.pythonhosted.org/packages/b8/2a/c79cf53fd91e5a87e30d481809f52f9a60dd221e39de66455cf04deaad37/pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8", size = 2051305, upload-time = "2026-04-20T14:43:18.627Z" }, + { url = "https://files.pythonhosted.org/packages/0b/db/d8182a7f1d9343a032265aae186eb063fe26ca4c40f256b21e8da4498e89/pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374", size = 2026310, upload-time = "2026-04-20T14:41:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/66/7f/03dbad45cd3aa9083fbc93c210ae8b005af67e4136a14186950a747c6874/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46", size = 2105683, upload-time = "2026-04-20T14:42:19.779Z" }, + { url = "https://files.pythonhosted.org/packages/26/22/4dc186ac8ea6b257e9855031f51b62a9637beac4d68ac06bee02f046f836/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874", size = 1940052, upload-time = "2026-04-20T14:43:59.274Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ca/d376391a5aff1f2e8188960d7873543608130a870961c2b6b5236627c116/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76", size = 1988172, upload-time = "2026-04-20T14:41:17.469Z" }, + { url = "https://files.pythonhosted.org/packages/0e/6b/523b9f85c23788755d6ab949329de692a2e3a584bc6beb67fef5e035aa9d/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531", size = 2128596, upload-time = "2026-04-20T14:40:41.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/42/f426db557e8ab2791bc7562052299944a118655496fbff99914e564c0a94/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803", size = 2091877, upload-time = "2026-04-20T14:43:27.091Z" }, + { url = "https://files.pythonhosted.org/packages/5c/4f/86a832a9d14df58e663bfdf4627dc00d3317c2bd583c4fb23390b0f04b8e/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3", size = 1932428, upload-time = "2026-04-20T14:40:45.781Z" }, + { url = "https://files.pythonhosted.org/packages/11/1a/fe857968954d93fb78e0d4b6df5c988c74c4aaa67181c60be7cfe327c0ca/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5", size = 1997550, upload-time = "2026-04-20T14:44:02.425Z" }, + { url = "https://files.pythonhosted.org/packages/17/eb/9d89ad2d9b0ba8cd65393d434471621b98912abb10fbe1df08e480ba57b5/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4", size = 2137657, upload-time = "2026-04-20T14:42:45.149Z" }, + { url = "https://files.pythonhosted.org/packages/1f/da/99d40830684f81dec901cac521b5b91c095394cc1084b9433393cde1c2df/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25", size = 2107973, upload-time = "2026-04-20T14:42:06.175Z" }, + { url = "https://files.pythonhosted.org/packages/99/a5/87024121818d75bbb2a98ddbaf638e40e7a18b5e0f5492c9ca4b1b316107/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3", size = 1947191, upload-time = "2026-04-20T14:43:14.319Z" }, + { url = "https://files.pythonhosted.org/packages/60/62/0c1acfe10945b83a6a59d19fbaa92f48825381509e5701b855c08f13db76/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536", size = 2123791, upload-time = "2026-04-20T14:43:22.766Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/3b2393b4c8f44285561dc30b00cf307a56a2eff7c483a824db3b8221ca51/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1", size = 2153197, upload-time = "2026-04-20T14:44:27.932Z" }, + { url = "https://files.pythonhosted.org/packages/ba/75/5af02fb35505051eee727c061f2881c555ab4f8ddb2d42da715a42c9731b/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c", size = 2181073, upload-time = "2026-04-20T14:43:20.729Z" }, + { url = "https://files.pythonhosted.org/packages/10/92/7e0e1bd9ca3c68305db037560ca2876f89b2647deb2f8b6319005de37505/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85", size = 2315886, upload-time = "2026-04-20T14:44:04.826Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d8/101655f27eaf3e44558ead736b2795d12500598beed4683f279396fa186e/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8", size = 2360528, upload-time = "2026-04-20T14:40:47.431Z" }, + { url = "https://files.pythonhosted.org/packages/07/0f/1c34a74c8d07136f0d729ffe5e1fdab04fbdaa7684f61a92f92511a84a15/pydantic_core-2.46.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff", size = 2184144, upload-time = "2026-04-20T14:42:57Z" }, ] [[package]] @@ -2723,11 +2732,11 @@ wheels = [ [[package]] name = "pytz" -version = "2026.2" +version = "2026.1.post1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a", size = 320861, upload-time = "2026-05-04T01:35:29.667Z" } +sdist = { url = "https://files.pythonhosted.org/packages/56/db/b8721d71d945e6a8ac63c0fc900b2067181dbb50805958d4d4661cf7d277/pytz-2026.1.post1.tar.gz", hash = "sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1", size = 321088, upload-time = "2026-03-03T07:47:50.683Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141, upload-time = "2026-05-04T01:35:27.408Z" }, + { url = "https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl", hash = "sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a", size = 510489, upload-time = "2026-03-03T07:47:49.167Z" }, ] [[package]] @@ -2922,7 +2931,7 @@ version = "15.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } @@ -3179,23 +3188,23 @@ resolution-markers = [ "python_full_version < '3.11'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version < '3.11'" }, - { name = "babel", marker = "python_full_version < '3.11'" }, - { name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" }, - { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "imagesize", marker = "python_full_version < '3.11'" }, - { name = "jinja2", marker = "python_full_version < '3.11'" }, - { name = "packaging", marker = "python_full_version < '3.11'" }, - { name = "pygments", marker = "python_full_version < '3.11'" }, - { name = "requests", marker = "python_full_version < '3.11'" }, - { name = "snowballstemmer", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.11'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.11'" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" } }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, + { name = "tomli" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611, upload-time = "2024-10-13T20:27:13.93Z" } wheels = [ @@ -3210,23 +3219,23 @@ resolution-markers = [ "python_full_version == '3.11.*'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version == '3.11.*'" }, - { name = "babel", marker = "python_full_version == '3.11.*'" }, - { name = "colorama", marker = "python_full_version == '3.11.*' and sys_platform == 'win32'" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "imagesize", marker = "python_full_version == '3.11.*'" }, - { name = "jinja2", marker = "python_full_version == '3.11.*'" }, - { name = "packaging", marker = "python_full_version == '3.11.*'" }, - { name = "pygments", marker = "python_full_version == '3.11.*'" }, - { name = "requests", marker = "python_full_version == '3.11.*'" }, - { name = "roman-numerals", marker = "python_full_version == '3.11.*'" }, - { name = "snowballstemmer", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.11.*'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.11.*'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } wheels = [ @@ -3242,23 +3251,23 @@ resolution-markers = [ "python_full_version >= '3.12' and python_full_version < '3.15'", ] dependencies = [ - { name = "alabaster", marker = "python_full_version >= '3.12'" }, - { name = "babel", marker = "python_full_version >= '3.12'" }, - { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" }, - { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, - { name = "imagesize", marker = "python_full_version >= '3.12'" }, - { name = "jinja2", marker = "python_full_version >= '3.12'" }, - { name = "packaging", marker = "python_full_version >= '3.12'" }, - { name = "pygments", marker = "python_full_version >= '3.12'" }, - { name = "requests", marker = "python_full_version >= '3.12'" }, - { name = "roman-numerals", marker = "python_full_version >= '3.12'" }, - { name = "snowballstemmer", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" }, + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } }, + { name = "imagesize" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "roman-numerals" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } wheels = [ @@ -3386,7 +3395,7 @@ version = "8.2.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "4.1.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version >= '3.11'" }, { name = "mdit-py-plugins" }, { name = "platformdirs" }, { name = "pygments" }, @@ -3512,7 +3521,7 @@ wheels = [ [[package]] name = "typer" -version = "0.25.1" +version = "0.25.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, @@ -3520,9 +3529,9 @@ dependencies = [ { name = "rich" }, { name = "shellingham" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e4/51/9aed62104cea109b820bbd6c14245af756112017d309da813ef107d42e7e/typer-0.25.1.tar.gz", hash = "sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc", size = 122276, upload-time = "2026-04-30T19:32:16.964Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/27/ede8cec7596e0041ba7e7b80b47d132562f56ff454313a16f6084e555c9f/typer-0.25.0.tar.gz", hash = "sha256:123eaf9f19bb40fd268310e12a542c0c6b4fab9c98d9d23342a01ff95e3ce930", size = 120150, upload-time = "2026-04-26T08:46:14.767Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl", hash = "sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89", size = 58409, upload-time = "2026-04-30T19:32:18.271Z" }, + { url = "https://files.pythonhosted.org/packages/9a/72/193d4e586ec5a4db834a36bbeb47641a62f951f114ffd0fe5b1b46e8d56f/typer-0.25.0-py3-none-any.whl", hash = "sha256:ac01b48823d3db9a83c9e164338057eadbb1c9957a2a6b4eeb486669c560b5dc", size = 55993, upload-time = "2026-04-26T08:46:15.889Z" }, ] [[package]] @@ -3557,14 +3566,14 @@ wheels = [ [[package]] name = "types-requests" -version = "2.33.0.20260503" +version = "2.33.0.20260408" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a1/b8/57e94268c0d82ac3eaa2fc35aa8ca7bbc2542f726b67dcf90b0b00a3b14d/types_requests-2.33.0.20260503.tar.gz", hash = "sha256:9721b2d9dbee7131f2fb39f20f0ebb1999c18cef4b512c9a7932f3722de7c5f4", size = 23931, upload-time = "2026-05-03T05:20:08.882Z" } +sdist = { url = "https://files.pythonhosted.org/packages/69/6a/749dc53a54a3f35842c1f8197b3ca6b54af6d7458a1bfc75f6629b6da666/types_requests-2.33.0.20260408.tar.gz", hash = "sha256:95b9a86376807a216b2fb412b47617b202091c3ea7c078f47cc358d5528ccb7b", size = 23882, upload-time = "2026-04-08T04:34:49.33Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/82/959113a6351f3ca046cd0a8cd2cee071d7ea47473560557a01eeae9a6fe2/types_requests-2.33.0.20260503-py3-none-any.whl", hash = "sha256:02aaa7e3577a13471715bb1bddb693cc985ea514f754b503bf033e6a09a3e528", size = 20736, upload-time = "2026-05-03T05:20:07.858Z" }, + { url = "https://files.pythonhosted.org/packages/90/b8/78fd6c037de4788c040fdd323b3369804400351b7827473920f6c1d03c10/types_requests-2.33.0.20260408-py3-none-any.whl", hash = "sha256:81f31d5ea4acb39f03be7bc8bed569ba6d5a9c5d97e89f45ac43d819b68ca50f", size = 20739, upload-time = "2026-04-08T04:34:48.325Z" }, ] [[package]] @@ -3647,11 +3656,11 @@ wheels = [ [[package]] name = "wcwidth" -version = "0.7.0" +version = "0.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2c/ee/afaf0f85a9a18fe47a67f1e4422ed6cf1fe642f0ae0a2f81166231303c52/wcwidth-0.7.0.tar.gz", hash = "sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0", size = 182132, upload-time = "2026-05-02T16:04:12.653Z" } +sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684, upload-time = "2026-02-06T19:19:40.919Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/52/e465037f5375f43533d1a80b6923955201596a99142ed524d77b571a1418/wcwidth-0.7.0-py3-none-any.whl", hash = "sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2", size = 110825, upload-time = "2026-05-02T16:04:11.033Z" }, + { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189, upload-time = "2026-02-06T19:19:39.646Z" }, ] [[package]] From 7cb52b498af4f38a8632fd05ec9bd5cc0738fba4 Mon Sep 17 00:00:00 2001 From: "codspeed-hq[bot]" <117304815+codspeed-hq[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:36:05 +0000 Subject: [PATCH 098/135] ci: add CodSpeed performance benchmarks (#4384) Co-authored-by: CodSpeed Bot Co-authored-by: mashehu --- .github/workflows/codspeed.yml | 50 +++++++++++++++++++++++++++ benchmarks/test_startup_benchmarks.py | 38 ++++++++++++++++++++ pyproject.toml | 1 + uv.lock | 39 +++++++++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 .github/workflows/codspeed.yml create mode 100644 benchmarks/test_startup_benchmarks.py diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml new file mode 100644 index 0000000000..43e5d03ac3 --- /dev/null +++ b/.github/workflows/codspeed.yml @@ -0,0 +1,50 @@ +name: CodSpeed benchmarks + +on: + push: + branches: + - main + - dev + pull_request: + # `workflow_dispatch` allows CodSpeed to trigger backtest + # performance analysis in order to generate initial data. + workflow_dispatch: + +# Cancel if a newer run with the same workflow name is queued +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + id-token: write # for OpenID Connect authentication with CodSpeed + +jobs: + startup-benchmarks: + name: Run start-up benchmarks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + name: Check out source-code repository + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + with: + python-version: "3.10" + + - name: Install uv + uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + with: + enable-cache: true + + - name: Install dependencies + run: uv sync --all-extras + + # These benchmarks spawn a fresh interpreter per round to measure + # import/start-up cost, which CodSpeed's instruction-counting + # "simulation" instrument can't see. Use "walltime" mode instead. + - name: Run start-up benchmarks + uses: CodSpeedHQ/action@a4a36bb07c0638b0b4ca52bf1f3dad1b4289e52f # v4.18.1 + with: + mode: walltime + run: uv run pytest benchmarks/test_startup_benchmarks.py --codspeed diff --git a/benchmarks/test_startup_benchmarks.py b/benchmarks/test_startup_benchmarks.py new file mode 100644 index 0000000000..b0fe26207d --- /dev/null +++ b/benchmarks/test_startup_benchmarks.py @@ -0,0 +1,38 @@ +"""CodSpeed wall-time benchmarks for nf-core CLI start-up cost. + +These spawn a fresh interpreter per round so that heavy, lazily-imported +dependencies (pydantic, requests, questionary, PyGithub, trogon, ...) are not +cached in sys.modules from a previous round. Run them under CodSpeed's +"walltime" instrument: the "simulation" instrument only profiles the parent +test process and never sees the child interpreter's import cost. + +Rounds are kept low because each one pays for a full interpreter boot. +""" + +import os +import subprocess +import sys + +IMPORT_CMD = [sys.executable, "-c", "import nf_core.__main__"] +HELP_CMD = [sys.executable, "-m", "nf_core", "--help"] + +# Keep the help invocation offline and deterministic. +_ENV = {**os.environ, "NFCORE_NO_VERSION_CHECK": "1"} + + +def test_import_main_startup(benchmark): + """Wall-time cost of importing the CLI entry point in a fresh interpreter.""" + + def run(): + subprocess.run(IMPORT_CMD, check=True, capture_output=True) + + benchmark.pedantic(run, rounds=10, warmup_rounds=2) + + +def test_cli_help_startup(benchmark): + """Wall-time cost of a full `nf-core --help` invocation.""" + + def run(): + subprocess.run(HELP_CMD, check=True, capture_output=True, env=_ENV) + + benchmark.pedantic(run, rounds=10, warmup_rounds=2) diff --git a/pyproject.toml b/pyproject.toml index 52c30709dc..51f8c4d8ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,6 +79,7 @@ dev = [ "typing_extensions>=4.0.0", "pytest-asyncio", "pytest-clarity>=1.0.1", + "pytest-codspeed>=5.0.3", "pytest-sugar>=1.1.1", "pytest-textual-snapshot==1.1.0", "pytest-workflow>=2.0.0", diff --git a/uv.lock b/uv.lock index 8db081c0be..3b2264a936 100644 --- a/uv.lock +++ b/uv.lock @@ -1661,6 +1661,7 @@ dev = [ { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-clarity" }, + { name = "pytest-codspeed" }, { name = "pytest-cov" }, { name = "pytest-datafiles" }, { name = "pytest-sugar" }, @@ -1720,6 +1721,7 @@ dev = [ { name = "pytest", specifier = ">=8.0.0" }, { name = "pytest-asyncio" }, { name = "pytest-clarity", specifier = ">=1.0.1" }, + { name = "pytest-codspeed", specifier = ">=5.0.3" }, { name = "pytest-cov" }, { name = "pytest-datafiles" }, { name = "pytest-sugar", specifier = ">=1.1.1" }, @@ -2634,6 +2636,43 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/52/5c/cafa97944de55738a6a2c5a7cee00d073cb80495032d2b112c4546525eca/pytest-clarity-1.0.1.tar.gz", hash = "sha256:505fe345fad4fe11c6a4187fe683f2c7c52c077caa1e135f3e483fe112db7772", size = 4891, upload-time = "2021-06-11T18:16:18.372Z" } +[[package]] +name = "pytest-codspeed" +version = "5.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, + { name = "rich" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e1/b4/cf932fcd1960a2fd6d9b09eb403253a8709aeee975961afa6299239a830e/pytest_codspeed-5.0.3.tar.gz", hash = "sha256:91afef90e6a96b013495e4702ef5d6358614a449e71008cdc194ef668778b92f", size = 324571, upload-time = "2026-05-22T16:20:49.231Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/f5/a8f70147216e4b84046ca406d03ecc8e83e3ea56ba1bdca0bb79cca79fee/pytest_codspeed-5.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:005348ea52ace3ede2e2f595913912ad2564cca7b124211a88dc78a9cb1fca63", size = 366249, upload-time = "2026-05-22T16:20:39.985Z" }, + { url = "https://files.pythonhosted.org/packages/f6/bd/7a4dbcf457fcc3ed788c55d402f3af2671e0e342b6098090fd590aa8712e/pytest_codspeed-5.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dbe6a4a00b449b6ba2771f644cbc38bdf55acf5c812e60e5659110e19dd9f510", size = 932229, upload-time = "2026-05-22T16:20:37.283Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e1/414ea4c66559f24ec06aeb6db62bfc7079582dac1452e648affe1eb5cfb4/pytest_codspeed-5.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ac4344f34bbcdd17f6f8c30dbac3da2f80d223dd112e568fd7f7c2cd4cbc693", size = 934647, upload-time = "2026-05-22T16:20:31.997Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ef/32ce60d42a4aa43e728d988e13eb6568fbc7b10a514517b459bafd3f2b94/pytest_codspeed-5.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f56d0339cd98d26f6e561987be25bdd2761a5d53d8f73493b1ebe02d0d451093", size = 366253, upload-time = "2026-05-22T16:21:10.013Z" }, + { url = "https://files.pythonhosted.org/packages/2a/15/c66ef90a793c5d2c039e63a1726a5e55c678be2618b0f5f1660d0f79e25f/pytest_codspeed-5.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c682f6645d4eb472f3bd95dbda1805e3af4243610572cb7d6bf94a88e8a0b6c", size = 932465, upload-time = "2026-05-22T16:20:34.265Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7b/d231279301967f05b7909160489e85ee3a1b9da76094ea25343faba1abc2/pytest_codspeed-5.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f852bee785a7a124cb1720b1915670c6742af87747dc4d838f3ffdbd365ce9d9", size = 934925, upload-time = "2026-05-22T16:20:47.63Z" }, + { url = "https://files.pythonhosted.org/packages/c2/22/456c48160b761d5028c8afa119f085a9fc42855a783a13d73918078969f0/pytest_codspeed-5.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2eeb25fb1ac3f73c4de50e739e78fea396b89782bdb740bf2a7cd2df21f8d4ee", size = 366255, upload-time = "2026-05-22T16:20:56.214Z" }, + { url = "https://files.pythonhosted.org/packages/74/33/ac7441fa937c9d9f158083a8c46920a5a5c81ed3c5f96240fc8d650db5c2/pytest_codspeed-5.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73c5c9d98a3372a42611989ccfa437cce3842431ac6d6b9ab42c4f0e59c070f7", size = 932325, upload-time = "2026-05-22T16:21:08.814Z" }, + { url = "https://files.pythonhosted.org/packages/77/bc/8b994adcb9e9016e7d9a808056a3dd9cca21441e432ef456eae2b697d7fe/pytest_codspeed-5.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2e0ab65df73e837666d12357280ca50ff6d6ac03ea5266703be518b68170edf", size = 934885, upload-time = "2026-05-22T16:21:01.444Z" }, + { url = "https://files.pythonhosted.org/packages/dc/8e/e032451e9e0a06b0c4bff53105f62b693d9a54595dd8c024693741ce3380/pytest_codspeed-5.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6524c57fec279a22ffef6112af404036afc71b4704758ae9f0abda429b8478d4", size = 366253, upload-time = "2026-05-22T16:20:46.192Z" }, + { url = "https://files.pythonhosted.org/packages/a9/7b/ae76fd8ac656b9695806a6aafd5f22ec32e6ce20e266a58f9112e01d3cd8/pytest_codspeed-5.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c383c9121deb58a69f174188e9e4488ffc0daced0ed276abf87747182511901", size = 932360, upload-time = "2026-05-22T16:20:30.589Z" }, + { url = "https://files.pythonhosted.org/packages/a6/4a/dfd43d943fdb143be4fd62f34c2793ba349dc27aa188e521d19d629aa7ab/pytest_codspeed-5.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4bcdb4b6522738152885ef067e0c8524d5699828d780fb6f464cdb3db44369c", size = 934928, upload-time = "2026-05-22T16:20:38.62Z" }, + { url = "https://files.pythonhosted.org/packages/04/6a/fdcec19c7f267c195f147c51d3fd2245f6b8d09b80495ed0a90c008e0842/pytest_codspeed-5.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:25464363c7f9b9bd5022e969c0addba616fa40ac9b8f0fc9e030c4538863b32d", size = 366259, upload-time = "2026-05-22T16:21:06.039Z" }, + { url = "https://files.pythonhosted.org/packages/6a/96/c6b03b81dcd21ae3d6b32cca0b3c10149fa378eb21b338d4b63c9eb8050b/pytest_codspeed-5.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:efd43f82ea03ced8488a767ded9473f050791ab7783ea8654107e1e0ac66af40", size = 932395, upload-time = "2026-05-22T16:21:04.804Z" }, + { url = "https://files.pythonhosted.org/packages/96/08/56ad8f1cc7d6962f8a680141b361e93467a2abc53d976cd9d5e1edd740e3/pytest_codspeed-5.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:782f9985b6f6b45b8bc20152d206d3a52b56dd088ba81cb70a71f0b39841be9e", size = 934994, upload-time = "2026-05-22T16:20:28.809Z" }, + { url = "https://files.pythonhosted.org/packages/0b/54/9096c4545f09da94b1b00f3be2fe4952949e86c9bcafca9a29b26aed1a75/pytest_codspeed-5.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9aa0815b90196f3c20d736ea8691381e97f12bbe8c7d87af10a351e434b452cb", size = 366311, upload-time = "2026-05-22T16:20:41.791Z" }, + { url = "https://files.pythonhosted.org/packages/a7/3c/24c53f67a38ad48cb087105ac30a8aa0923223ee274ea9bf2dc705edaa59/pytest_codspeed-5.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:85505c96a3477c346ec2d2b7dced8478f4c651e2b1666ee102d53a832b511853", size = 933169, upload-time = "2026-05-22T16:20:43.178Z" }, + { url = "https://files.pythonhosted.org/packages/d1/de/2213f868fa7694f743f96cccbc07e757f45c920c523cccc2da97bc8652df/pytest_codspeed-5.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20eba63765be9d1b6cacbbfad84b87d49eb04b357a7045a0899880da181f81e3", size = 935522, upload-time = "2026-05-22T16:21:03.398Z" }, + { url = "https://files.pythonhosted.org/packages/df/85/5dfea1c031d6cccc11653464828edf205c30f798caf5b2a85375aacd914a/pytest_codspeed-5.0.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:ec9fa6f0af0a9feb0e0bd517fb59ef28f806fbd50c0c6900ac26cbb4d080eba5", size = 366275, upload-time = "2026-05-22T16:20:59.463Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2b/af4d1b612f03b98a6cf3c7d5f62678917a60110a8bf380d49ab408b31137/pytest_codspeed-5.0.3-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8df77b3409f54f4a268f77f3ff74992fe1d995cdbaf2cecf8ad74d32db217ce7", size = 932537, upload-time = "2026-05-22T16:20:54.945Z" }, + { url = "https://files.pythonhosted.org/packages/f5/a2/c7ec45e36a61b418efb2a3cccaa67a0c2fcf1f21d5880f64c33114f0c249/pytest_codspeed-5.0.3-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5d8695a227ea1c3a41d25db5b3fe720bf1b4808bd38862be811a4efd902c792", size = 934153, upload-time = "2026-05-22T16:21:07.494Z" }, + { url = "https://files.pythonhosted.org/packages/cf/c7/d5bada9618a0af56a5c8065fc61280849cab8e7c1e24025807a51c3157ce/pytest_codspeed-5.0.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bf4cc4178cbace8f4d2bd240408276bc4da3850ac5fcb5fb5f8a74ab417615bb", size = 366339, upload-time = "2026-05-22T16:20:51.968Z" }, + { url = "https://files.pythonhosted.org/packages/a8/37/fb27aeb40a81320e7349553b877a21333c897b27c8dfe215630452908f36/pytest_codspeed-5.0.3-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:abe793da40f87295d33988673d34f06ea569848b44490b847552cd416816258a", size = 933055, upload-time = "2026-05-22T16:20:44.861Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d9/6f2d69e96deaf0475a695fc9195af59e7a3b5fab50782855e65c63a7bc28/pytest_codspeed-5.0.3-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3a9ed38dfa776443b86f4b49a982e8443d0953db4974bd2673d63cc904ae1ad", size = 934481, upload-time = "2026-05-22T16:20:58.264Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b2/1d2a993c532146dce9eca5b5942d51898021c3579ce18b2454f932a915f8/pytest_codspeed-5.0.3-py3-none-any.whl", hash = "sha256:fe2ea83c924c2250675b75686c3ee456b8cf0208d83d552e182a195fdf467378", size = 74033, upload-time = "2026-05-22T16:20:26.814Z" }, +] + [[package]] name = "pytest-cov" version = "7.1.0" From e3dbb4fd25285152472def3582b9c447f6e3c956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 8 Jul 2026 14:08:49 +0200 Subject: [PATCH 099/135] specify required containers to not require arm (#4387) --- nf_core/modules/containers.py | 33 +++++++++++--- nf_core/modules/lint/module_containers.py | 3 +- nf_core/modules/modules_utils.py | 20 ++++++--- nf_core/utils.py | 3 ++ tests/modules/test_containers.py | 54 ++++++++++++++++++++++- 5 files changed, 96 insertions(+), 17 deletions(-) diff --git a/nf_core/modules/containers.py b/nf_core/modules/containers.py index 132e443499..9e701617c0 100644 --- a/nf_core/modules/containers.py +++ b/nf_core/modules/containers.py @@ -493,6 +493,22 @@ def callback(build_id: str) -> None: return containers, not has_failures + @staticmethod + def _raise_if_build_failed(result: dict, build_ref: str, details_uri: str = "") -> None: + """ + Raise a uniform error if a finished Wave build did not succeed. + + Accepts either the container submit response or a ``/status`` response — both + expose ``succeeded``/``reason``/``detailsUri`` — so the failure contract lives + in one place. ``details_uri`` overrides the value on ``result`` (the status + poller keeps the last non-empty build-log URL it saw). + """ + if result.get("succeeded"): + return + reason = result.get("reason") or "no reason provided" + details = details_uri or result.get("detailsUri") or "" + raise RuntimeError(f"Wave build {build_ref} failed: {reason}. Build log: {details}") + @classmethod def _await_build( cls, @@ -528,9 +544,7 @@ def _await_build( status = wave_request("get", status_url, error_context=f"Wave status check for request {request_id}") details_uri = status.get("detailsUri") or details_uri if status.get("status") == "DONE": - if not status.get("succeeded"): - reason = status.get("reason") or "no reason provided" - raise RuntimeError(f"Wave build {request_id} failed: {reason}. Build log: {details_uri}") + cls._raise_if_build_failed(status, request_id, details_uri) log.debug(f"Wave build {request_id} completed in {status.get('duration')}s") return if time.monotonic() > deadline: @@ -589,10 +603,15 @@ def request_container( if build_id and on_build_id is not None: on_build_id(build_id) - # A build that is cached (or already reported DONE in the submit response) is - # resolved immediately; otherwise poll the container status endpoint until it - # finishes. - if not meta_data.get("cached") and meta_data.get("status") != "DONE": + # Wave returns a targetImage/buildId even for failed builds, so a cached/DONE + # submit response must still be checked for success — not only the polling path. + succeeded = meta_data.get("succeeded") + is_final = bool(meta_data.get("cached")) or meta_data.get("status") == "DONE" + if is_final and succeeded is not None: + # Submit response already carries an authoritative result. + cls._raise_if_build_failed(meta_data, build_id or request_id) + elif not is_final or request_id: + # Not final, or final but ambiguous: the status endpoint is authoritative. cls._await_build(request_id, cancel_event=cancel_event) image = meta_data.get("targetImage") or meta_data.get("containerImage") or "" diff --git a/nf_core/modules/lint/module_containers.py b/nf_core/modules/lint/module_containers.py index 25d0dce6e0..cfef840007 100644 --- a/nf_core/modules/lint/module_containers.py +++ b/nf_core/modules/lint/module_containers.py @@ -6,7 +6,6 @@ from nf_core.components.nfcore_component import NFCoreComponent from nf_core.modules.modules_utils import ContainerEntry, MetaYmlContainers, module_uses_dockerfile -from nf_core.utils import CONTAINER_PLATFORMS log = logging.getLogger(__name__) @@ -210,7 +209,7 @@ def lint_meta_yml_containers(module: NFCoreComponent, skip_docker=False, skip_co ) ) - for plat in CONTAINER_PLATFORMS: + for plat in containers.conda: conda_entry = containers.conda.get(plat) docker_entry = containers.docker.get(plat) if containers.docker else None conda_lock = conda_entry.lock_file if conda_entry else "" diff --git a/nf_core/modules/modules_utils.py b/nf_core/modules/modules_utils.py index 6a3ed22604..70cb7ffb62 100644 --- a/nf_core/modules/modules_utils.py +++ b/nf_core/modules/modules_utils.py @@ -6,7 +6,12 @@ import requests from pydantic import BaseModel, ValidationInfo, field_validator, model_validator -from nf_core.utils import CONTAINER_PLATFORMS, CONTAINER_SYSTEMS, NFCORE_CACHE_DIR +from nf_core.utils import ( + CONTAINER_PLATFORMS, + CONTAINER_SYSTEMS, + NFCORE_CACHE_DIR, + REQUIRED_CONTAINER_PLATFORMS, +) from ..components.nfcore_component import NFCoreComponent @@ -88,10 +93,13 @@ def dump_for_meta_yml(self) -> dict: @model_validator(mode="after") def check_container_systems_complete(self, info: ValidationInfo) -> "MetaYmlContainers": """ - Require a non-empty section with an entry for every platform, for each container - system named in ``context={"require_complete": [...]}`` (``True`` means all of - ``CONTAINER_SYSTEMS``, i.e. conda is exempt). Plain construction (e.g. the partial - states built up during container builds) is not affected. + Require a non-empty section with an entry for every *required* platform + (``REQUIRED_CONTAINER_PLATFORMS``), for each container system named in + ``context={"require_complete": [...]}`` (``True`` means all of + ``CONTAINER_SYSTEMS``, i.e. conda is exempt). Optional platforms such as + ``linux/arm64`` are validated when present but never required. Plain + construction (e.g. the partial states built up during container builds) is + not affected. """ require = (info.context or {}).get("require_complete") if not require: @@ -100,7 +108,7 @@ def check_container_systems_complete(self, info: ValidationInfo) -> "MetaYmlCont entries = getattr(self, system) if not entries: raise ValueError(f"No containers specified for {system}") - for plf in CONTAINER_PLATFORMS: + for plf in REQUIRED_CONTAINER_PLATFORMS: if plf not in entries: raise ValueError(f"No {system} entries found for expected platform: {plf}") return self diff --git a/nf_core/utils.py b/nf_core/utils.py index 98db9aba31..0e751d4c52 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -109,6 +109,9 @@ def is_interactive() -> bool: CONTAINER_SYSTEMS = ["docker", "singularity"] CONTAINER_PLATFORMS = ["linux/amd64", "linux/arm64"] +# Platforms a module must provide containers for. Others (e.g. linux/arm64) are +# supported and validated when present, but not required. +REQUIRED_CONTAINER_PLATFORMS = ["linux/amd64"] class ContainerRegistryUrls(Enum): diff --git a/tests/modules/test_containers.py b/tests/modules/test_containers.py index 5ba5c27d76..8b137a5196 100644 --- a/tests/modules/test_containers.py +++ b/tests/modules/test_containers.py @@ -186,6 +186,43 @@ def test_request_container_build_failure_raises(self, mock_post, mock_get): # Polled the v1alpha2 container status endpoint with the requestId assert mock_get.call_args[0][0].endswith("/v1alpha2/container/req-fail/status") + @mock.patch("nf_core.modules.containers.requests.get") + @mock.patch("nf_core.modules.containers.requests.post") + def test_request_container_cached_failed_build_raises(self, mock_post, mock_get): + # Wave reports a previously-failed build as cached/DONE but still returns a + # targetImage. The submit-response success flag must be honoured so the failed + # build is not silently recorded as a valid container. + mock_post.return_value = self._fake_response( + { + "buildId": "bd-aa7e45b61425a0b2_7", + "requestId": "req-cached", + "cached": True, + "status": "DONE", + "succeeded": False, + "reason": "arm64 build failed", + "detailsUri": "https://wave/log", + "targetImage": "community.wave.seqera.io/library/busco:6.1.0--aa7e45b61425a0b2", + } + ) + with pytest.raises(RuntimeError, match="Wave build bd-aa7e45b61425a0b2_7 failed: arm64 build failed"): + ModuleContainers.request_container("docker", CONTAINER_PLATFORMS[0], self.environment_yml) + # A cached failure is resolved from the submit response alone - no status poll. + mock_get.assert_not_called() + + @mock.patch("nf_core.modules.containers.requests.get") + @mock.patch("nf_core.modules.containers.requests.post") + def test_request_container_cached_without_result_polls_status(self, mock_post, mock_get): + # Cached/DONE submit response with no explicit success flag -> fall back to the + # authoritative status endpoint before accepting the image. + mock_post.return_value = self._fake_response( + {"buildId": "bd-cached", "requestId": "req-cached", "cached": True, "targetImage": "testC:latest"} + ) + mock_get.return_value = self._fake_response({"status": "DONE", "succeeded": True}) + + container = ModuleContainers.request_container("docker", CONTAINER_PLATFORMS[0], self.environment_yml) + assert container.name == "testC:latest" + assert mock_get.call_args[0][0].endswith("/v1alpha2/container/req-cached/status") + @mock.patch("nf_core.modules.containers.requests.post") def test_request_container_missing_image_raises(self, mock_post): mock_post.return_value = self._fake_response({"buildId": "build-4", "cached": True}) @@ -255,13 +292,26 @@ def test_get_containers_from_meta_missing_system(self): assert result is None assert "No containers specified for docker" in self.caplog.text - def test_get_containers_from_meta_missing_platform_key(self): + def test_get_containers_from_meta_optional_platform_missing_ok(self): + """An optional platform (e.g. linux/arm64) may be absent - amd64 alone is valid.""" containers = { "docker": {CONTAINER_PLATFORMS[0]: {"name": "img:1.0"}}, "singularity": {CONTAINER_PLATFORMS[0]: {"name": "sif:1.0"}}, } self._write_meta({"name": "bpipe/test", "containers": containers}) - missing_platform = CONTAINER_PLATFORMS[1] + result = self.module_containers.get_containers_from_meta() + assert result is not None + assert CONTAINER_PLATFORMS[0] in result.docker + assert CONTAINER_PLATFORMS[1] not in result.docker + + def test_get_containers_from_meta_missing_required_platform(self): + """A required platform (linux/amd64) must be present, or the section is invalid.""" + containers = { + "docker": {CONTAINER_PLATFORMS[1]: {"name": "img:1.0"}}, + "singularity": {CONTAINER_PLATFORMS[1]: {"name": "sif:1.0"}}, + } + self._write_meta({"name": "bpipe/test", "containers": containers}) + missing_platform = CONTAINER_PLATFORMS[0] self.caplog.set_level(logging.DEBUG, logger="nf_core.modules.containers") result = self.module_containers.get_containers_from_meta() assert result is None From facc0352102e507475d0a1a2b8cbe66e2ecaf873 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 21:24:46 +0200 Subject: [PATCH 100/135] Update GitHub Actions (#4389) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update GitHub Actions * Apply suggestion from @mashehu * add fuller integration bench mark (cherry picked from commit 4d109c3ca5fd01be75e72f1ca02848841c646d13) * fix test --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Matthias Hörtenhuber Co-authored-by: mashehu --- .github/workflows/codspeed.yml | 8 +-- .github/workflows/create-lint-wf.yml | 2 +- .../create-test-lint-wf-template.yml | 2 +- .github/workflows/create-test-wf.yml | 2 +- .github/workflows/deploy-pypi.yml | 2 +- .github/workflows/nextflow-source-test.yml | 2 +- .github/workflows/pytest.yml | 2 +- .github/workflows/sync.yml | 2 +- .../workflows/update-template-snapshots.yml | 2 +- .../workflows/update-textual-snapshots.yml | 2 +- benchmarks/test_startup_benchmarks.py | 62 ++++++++++++++++--- .../.github/workflows/linting.yml | 2 +- nf_core/pipelines/download/download.py | 14 +++-- 13 files changed, 79 insertions(+), 25 deletions(-) diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 43e5d03ac3..5749944b56 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -24,16 +24,16 @@ jobs: name: Run start-up benchmarks runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out source-code repository - name: Set up Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: python-version: "3.10" - name: Install uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true @@ -44,7 +44,7 @@ jobs: # import/start-up cost, which CodSpeed's instruction-counting # "simulation" instrument can't see. Use "walltime" mode instead. - name: Run start-up benchmarks - uses: CodSpeedHQ/action@a4a36bb07c0638b0b4ca52bf1f3dad1b4289e52f # v4.18.1 + uses: CodSpeedHQ/action@9f3a37ece7abc84992501a7fcd54d1704f3458fa # v4.18.4 with: mode: walltime run: uv run pytest benchmarks/test_startup_benchmarks.py --codspeed diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index a95e7b930a..5c43f71151 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -52,7 +52,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index 433f36e477..1b9ecfe1a1 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -64,7 +64,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index e2ad32db3f..85f9144f18 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index 4ec6e56d8e..1fd4c1fb07 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -22,7 +22,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index 28f85bb143..55b77eac15 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 970544be6c..1d43675eb2 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -82,7 +82,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Install uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index fa11f4fba6..e2acb07ee0 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -82,7 +82,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index bbb2192c53..74bc47fd11 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -61,7 +61,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index abf70edafb..3a31d597da 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -42,7 +42,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true diff --git a/benchmarks/test_startup_benchmarks.py b/benchmarks/test_startup_benchmarks.py index b0fe26207d..d9f9ca6b77 100644 --- a/benchmarks/test_startup_benchmarks.py +++ b/benchmarks/test_startup_benchmarks.py @@ -13,26 +13,74 @@ import subprocess import sys +import pytest + IMPORT_CMD = [sys.executable, "-c", "import nf_core.__main__"] HELP_CMD = [sys.executable, "-m", "nf_core", "--help"] +COMMAND_GROUPS = ["pipelines", "modules", "subworkflows", "test-datasets"] # Keep the help invocation offline and deterministic. _ENV = {**os.environ, "NFCORE_NO_VERSION_CHECK": "1"} -def test_import_main_startup(benchmark): - """Wall-time cost of importing the CLI entry point in a fresh interpreter.""" - +def _benchmark_command(benchmark, command): def run(): - subprocess.run(IMPORT_CMD, check=True, capture_output=True) + subprocess.run(command, check=True, capture_output=True, env=_ENV) benchmark.pedantic(run, rounds=10, warmup_rounds=2) +def _cli_script(setup, args): + return f"{setup}\nimport sys\nsys.argv = {args!r}\nfrom nf_core.__main__ import run_nf_core\nrun_nf_core()" + + +def test_import_main_startup(benchmark): + """Wall-time cost of importing the CLI entry point in a fresh interpreter.""" + _benchmark_command(benchmark, IMPORT_CMD) + + def test_cli_help_startup(benchmark): """Wall-time cost of a full `nf-core --help` invocation.""" + _benchmark_command(benchmark, HELP_CMD) - def run(): - subprocess.run(HELP_CMD, check=True, capture_output=True, env=_ENV) - benchmark.pedantic(run, rounds=10, warmup_rounds=2) +@pytest.mark.parametrize("command_group", COMMAND_GROUPS) +def test_cli_command_group_help_startup(benchmark, command_group): + """Wall-time cost of loading each top-level command tree and rendering its help.""" + _benchmark_command(benchmark, [sys.executable, "-m", "nf_core", command_group, "--help"]) + + +def test_pipelines_create_startup(benchmark, tmp_path): + """Start the create command, stubbing only template generation and other writes.""" + args = [ + "nf-core", + "pipelines", + "create", + "--name", + "benchmark", + "--description", + "benchmark pipeline", + "--author", + "nf-core", + "--outdir", + str(tmp_path / "pipeline"), + ] + setup = ( + "from nf_core.pipelines.create.create import PipelineCreate\nPipelineCreate.init_pipeline = lambda self: None" + ) + _benchmark_command(benchmark, [sys.executable, "-c", _cli_script(setup, args)]) + + +def test_modules_install_startup(benchmark, tmp_path): + """Start module installation, stubbing only the remote clone and resulting writes.""" + args = ["nf-core", "modules", "install", "fastp", "-d", str(tmp_path)] + setup = """import nf_core.modules.install as install_module +install_module.ModuleInstall = type( + "ModuleInstall", + (), + { + "__init__": lambda self, *args, **kwargs: None, + "install": lambda self, *args, **kwargs: True, + }, +)""" + _benchmark_command(benchmark, [sys.executable, "-c", _cli_script(setup, args)]) diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index de51d453f6..d2f678bffc 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -34,7 +34,7 @@ jobs: architecture: "x64" - name: Setup uv - uses: astral-sh/setup-uv@f98e06938123ccabd21905ea5d0069192241f9f1 # v8.3.1 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 - name: read .nf-core.yml uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 diff --git a/nf_core/pipelines/download/download.py b/nf_core/pipelines/download/download.py index f02c24fbfc..5006847d23 100644 --- a/nf_core/pipelines/download/download.py +++ b/nf_core/pipelines/download/download.py @@ -703,12 +703,18 @@ def run_nextflow_inspect(params_file: Path | None = None) -> dict[str, Any]: try: out_json = run_nextflow_inspect() except RuntimeError as e: - # Extract Nextflow stdout from the chained CalledProcessError (errors go to stdout in NF) - nf_stdout = getattr(e.__cause__, "output", None) or b"" + # Nextflow's error text is embedded in the RuntimeError message by run_cmd; + # a chained CalledProcessError (if any) may carry it in stdout/stderr instead. + nf_error_parts = [str(e), getattr(e.__cause__, "output", None), getattr(e.__cause__, "stderr", None)] + nf_error = "\n".join( + part.decode("utf-8", errors="replace") if isinstance(part, bytes) else part + for part in nf_error_parts + if part + ) # Nextflow >= 26.04 enforces strict process directive syntax and rejects old-style # if/else container blocks with "Invalid process directive". Users need an older NF. - if b"Invalid process directive" in nf_stdout: + if "Invalid process directive" in nf_error: raise DownloadError( "nextflow inspect failed because the pipeline uses old-style process syntax " "that the default strict syntax of Nextflow >= 26.04 no longer accepts.\n" @@ -720,7 +726,7 @@ def run_nextflow_inspect(params_file: Path | None = None) -> dict[str, Any]: # only issue, retry inspect with an ephemeral params file that provides one. if re.search( r"missing required parameter\s*:\s*(?:--outdir|params\.outdir|outdir)\b", - nf_stdout.decode("utf-8", errors="replace"), + nf_error, flags=re.IGNORECASE, ): try: From 2936d8e38796bec034b4dcc30f83b2b387f70dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 15 Jul 2026 15:45:31 +0200 Subject: [PATCH 101/135] try out codspeed runners and add more realistic tests (#4395) --- .github/workflows/codspeed.yml | 14 ++++- benchmarks/test_startup_benchmarks.py | 74 ++++++++++++++++++++++----- 2 files changed, 75 insertions(+), 13 deletions(-) diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 5749944b56..51b052a93b 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -22,7 +22,7 @@ permissions: jobs: startup-benchmarks: name: Run start-up benchmarks - runs-on: ubuntu-latest + runs-on: codspeed-macro steps: - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 name: Check out source-code repository @@ -32,6 +32,11 @@ jobs: with: python-version: "3.10" + - name: Install Nextflow + uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + with: + version: ${{ github.event.inputs.nextflow-version || matrix.nextflow-version }} + - name: Install uv uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: @@ -40,6 +45,13 @@ jobs: - name: Install dependencies run: uv sync --all-extras + # Clone nf-core/modules into the local cache here, while network is + # available. The modules-install benchmark then runs entirely offline + # (no per-round fetch), so it stays deterministic even if the CodSpeed + # step sandboxes network during measurement. + - name: Warm nf-core/modules cache + run: uv run python -c "from nf_core.modules.modules_repo import ModulesRepo; ModulesRepo()" + # These benchmarks spawn a fresh interpreter per round to measure # import/start-up cost, which CodSpeed's instruction-counting # "simulation" instrument can't see. Use "walltime" mode instead. diff --git a/benchmarks/test_startup_benchmarks.py b/benchmarks/test_startup_benchmarks.py index d9f9ca6b77..52322c5433 100644 --- a/benchmarks/test_startup_benchmarks.py +++ b/benchmarks/test_startup_benchmarks.py @@ -10,6 +10,7 @@ """ import os +import shutil import subprocess import sys @@ -34,6 +35,39 @@ def _cli_script(setup, args): return f"{setup}\nimport sys\nsys.argv = {args!r}\nfrom nf_core.__main__ import run_nf_core\nrun_nf_core()" +@pytest.fixture(scope="session") +def generated_pipeline(tmp_path_factory): + """Render a real pipeline scaffold once, reused by the realistic benchmarks. + + Generation is expensive and identical for every consumer, so it happens a + single time per session and outside any measured rounds. Consumers that + mutate the pipeline (e.g. installing a module) must work on a copy so the + shared scaffold stays pristine and the suite is order-independent. + """ + from nf_core.pipelines.create.create import PipelineCreate + + pipeline_dir = tmp_path_factory.mktemp("pipeline_fixture") / "pipeline" + PipelineCreate("benchmark", "benchmark pipeline", "nf-core", outdir=pipeline_dir, no_git=True).init_pipeline() + return pipeline_dir + + +@pytest.fixture(scope="session") +def modules_cache(): + """Ensure a local nf-core/modules clone exists, without ever fetching. + + Constructing ``ModulesRepo`` clones the remote into ``NFCORE_DIR`` only if it + is not already present; ``no_pull_global`` suppresses the ``git fetch`` on an + existing clone. In CI the clone is warmed by an earlier, network-enabled + workflow step, so this fixture (and every measured round) runs offline. When + run locally against a cold cache it performs the one-off clone here, outside + the measured rounds. + """ + from nf_core.modules.modules_repo import ModulesRepo + + ModulesRepo.no_pull_global = True + ModulesRepo() + + def test_import_main_startup(benchmark): """Wall-time cost of importing the CLI entry point in a fresh interpreter.""" _benchmark_command(benchmark, IMPORT_CMD) @@ -71,16 +105,32 @@ def test_pipelines_create_startup(benchmark, tmp_path): _benchmark_command(benchmark, [sys.executable, "-c", _cli_script(setup, args)]) -def test_modules_install_startup(benchmark, tmp_path): - """Start module installation, stubbing only the remote clone and resulting writes.""" - args = ["nf-core", "modules", "install", "fastp", "-d", str(tmp_path)] - setup = """import nf_core.modules.install as install_module -install_module.ModuleInstall = type( - "ModuleInstall", - (), - { - "__init__": lambda self, *args, **kwargs: None, - "install": lambda self, *args, **kwargs: True, - }, -)""" +def test_modules_install_startup(benchmark, generated_pipeline, modules_cache, tmp_path): + """Install a real module into a real pipeline, offline. + + The pipeline scaffold (``generated_pipeline``) and the nf-core/modules clone + (``modules_cache``) are both prepared once, outside the measured rounds. The + rounds then run the real install (git checkout + file copy + modules.json + write) against a private copy of the scaffold. ``no_pull_global`` suppresses + the per-round ``git fetch`` and ``--force`` avoids the re-install prompt, so + every round is deterministic and network-free. + """ + target = tmp_path / "pipeline" + shutil.copytree(generated_pipeline, target) + args = ["nf-core", "modules", "install", "fastp", "-d", str(target), "--force"] + setup = "from nf_core.modules.modules_repo import ModulesRepo\nModulesRepo.no_pull_global = True" + _benchmark_command(benchmark, [sys.executable, "-c", _cli_script(setup, args)]) + + +def test_pipelines_schema_lint_startup(benchmark, generated_pipeline): + """Lint a real, freshly generated pipeline schema. + + The schema fixture is rendered once by ``generated_pipeline`` (outside the + measured rounds); the benchmark then runs the real lint (JSON parse + + JSON-Schema validation + default-param checks). Only ``fetch_wf_config`` is + stubbed to skip the ``nextflow config`` JVM subprocess, which would + otherwise dominate wall time and require Nextflow on the runner. + """ + args = ["nf-core", "pipelines", "schema", "lint", str(generated_pipeline)] + setup = "import nf_core.utils\nnf_core.utils.fetch_wf_config = lambda *args, **kwargs: {}" _benchmark_command(benchmark, [sys.executable, "-c", _cli_script(setup, args)]) From a058ed1a4aafcea0b2bd92c8b8de8ecb344b540a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:57:18 +0200 Subject: [PATCH 102/135] Update GitHub Actions (#4394) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/clean-up.yml | 2 +- .github/workflows/codspeed.yml | 4 ++-- nf_core/pipeline-template/.github/workflows/clean-up.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/clean-up.yml b/.github/workflows/clean-up.yml index b50679cf05..4a51eef698 100644 --- a/.github/workflows/clean-up.yml +++ b/.github/workflows/clean-up.yml @@ -10,7 +10,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10 + - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10 with: stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment if it is still useful." diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 51b052a93b..dc3c222bea 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -30,7 +30,7 @@ jobs: - name: Set up Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 with: - python-version: "3.10" + python-version: "3.14" - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 @@ -56,7 +56,7 @@ jobs: # import/start-up cost, which CodSpeed's instruction-counting # "simulation" instrument can't see. Use "walltime" mode instead. - name: Run start-up benchmarks - uses: CodSpeedHQ/action@9f3a37ece7abc84992501a7fcd54d1704f3458fa # v4.18.4 + uses: CodSpeedHQ/action@f99becdce5e5d51fd556489ebef684f4ecfd6286 # v4.18.5 with: mode: walltime run: uv run pytest benchmarks/test_startup_benchmarks.py --codspeed diff --git a/nf_core/pipeline-template/.github/workflows/clean-up.yml b/nf_core/pipeline-template/.github/workflows/clean-up.yml index 0228336d1b..309a0c5790 100644 --- a/nf_core/pipeline-template/.github/workflows/clean-up.yml +++ b/nf_core/pipeline-template/.github/workflows/clean-up.yml @@ -10,7 +10,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10 + - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10 with: stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment if it is still useful." From 4513429bfb23170e3b19562b1a851a147ae7b866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 15 Jul 2026 16:12:53 +0200 Subject: [PATCH 103/135] add log hint in `modules create` and add `create containers` to `modules bump-versions` (#4374) --- nf_core/commands_modules.py | 96 ++-------- nf_core/components/create.py | 7 + nf_core/modules/bump_versions.py | 276 +++++++++++++++++----------- nf_core/modules/containers.py | 137 +++++++++++++- tests/modules/test_bump_versions.py | 213 ++++++++++++++++++++- tests/modules/test_containers.py | 64 ++++++- 6 files changed, 589 insertions(+), 204 deletions(-) diff --git a/nf_core/commands_modules.py b/nf_core/commands_modules.py index c2717b4852..21c5791c73 100644 --- a/nf_core/commands_modules.py +++ b/nf_core/commands_modules.py @@ -4,7 +4,6 @@ import rich -from nf_core.pipelines.containers_utils import try_generate_container_configs from nf_core.utils import CONTAINER_PLATFORMS, rich_force_colors log = logging.getLogger(__name__) @@ -328,7 +327,13 @@ def modules_bump_versions(ctx, tool, directory, all_modules, show_all, dry_run): ctx.obj["modules_repo_branch"], ctx.obj["modules_repo_no_pull"], ) - version_bumper.bump_versions(module=tool, all_modules=all_modules, show_up_to_date=show_all, dry_run=dry_run) + version_bumper.bump_versions( + module=tool, + all_modules=all_modules, + show_up_to_date=show_all, + dry_run=dry_run, + hide_progress=ctx.obj["hide_progress"], + ) except ModuleExceptionError as e: log.error(e) sys.exit(1) @@ -341,92 +346,31 @@ def modules_containers_create(ctx, module: str, directory: Path, force: bool) -> """ Build docker and singularity containers for linux/arm64 and linux/amd64 using wave. """ - from rich.console import Group - from rich.live import Live - from rich.progress import BarColumn, MofNCompleteColumn, Progress, SpinnerColumn, TextColumn - from nf_core.modules.containers import ModuleContainers - from nf_core.pipelines.lint_utils import console try: - manager = ModuleContainers(module=module, directory=directory, verbose=ctx.obj["verbose"]) + module_containers = ModuleContainers(module=module, directory=directory, verbose=ctx.obj["verbose"]) ModuleContainers.check_tower_token() - # Normalize to a list of components: batch mode processes all available - # modules, single-module mode is just a list of one. - if manager.all_modules: - if not manager.available_modules: + if module_containers.all_modules: + if not module_containers.available_modules: log.error("No modules found to build containers for") sys.exit(1) - log.info(f"Building containers for {len(manager.available_modules)} module(s)") - components = manager.available_modules - else: - assert manager.nfcore_component is not None - components = [manager.nfcore_component] - - failed_modules = [] + log.info(f"Building containers for {len(module_containers.available_modules)} module(s)") - overall_progress = Progress( - "[bold blue]{task.description}", - BarColumn(), - MofNCompleteColumn(), - console=console, - disable=ctx.obj["hide_progress"], - ) - module_progress = Progress( - SpinnerColumn(finished_text="[green]✓[/green]"), - "[bold blue]{task.description}", - TextColumn("{task.fields[status]}"), - console=console, - disable=ctx.obj["hide_progress"], + failed_modules = module_containers.build_containers_with_progress( + force=force, hide_progress=ctx.obj["hide_progress"] ) - with Live(Group(overall_progress, module_progress), console=console, transient=True): - # The overall bar is only useful when processing more than one module - overall_task_id = overall_progress.add_task("modules", total=len(components), visible=len(components) > 1) - for component in components: - module_name = component.component_name - module_task_id = module_progress.add_task( - f"[cyan]{module_name}[/cyan]", - total=None, - status="building containers...", - ) - try: - if manager.all_modules: - # Per-module instance, reusing the already-scanned component list - module_manager = ModuleContainers( - module=module_name, - directory=directory, - verbose=ctx.obj["verbose"], - components=manager.available_modules, - ) - else: - module_manager = manager - _, success = module_manager.create( - progress_bar=module_progress, task_id=module_task_id, force=force - ) - if success: - module_manager.update_containers_in_meta() - if module_manager.repo_type == "pipeline": - try_generate_container_configs(directory, module_manager.module_directory) - else: - failed_modules.append(module_name) - except (ValueError, RuntimeError, OSError) as e: - log.error(f"✗ Failed to build containers for {module_name}: {e}") - failed_modules.append(module_name) - finally: - overall_progress.advance(overall_task_id) - module_progress.remove_task(module_task_id) - if failed_modules: - if manager.all_modules: + if module_containers.all_modules: log.warning( f"Failed to build containers for {len(failed_modules)} module(s): {', '.join(failed_modules)}" ) else: - log.error(f"✗ Some container builds failed for {manager.module}") + log.error(f"✗ Some container builds failed for {module_containers.module}") sys.exit(1) - elif manager.all_modules: + elif module_containers.all_modules: log.info("Successfully built containers for all modules") except (UserWarning, LookupError, FileNotFoundError, ValueError, RuntimeError) as e: @@ -441,8 +385,8 @@ def modules_containers_conda_lock(ctx, module, platform=CONTAINER_PLATFORMS[0]): from nf_core.modules.containers import ModuleContainers try: - manager = ModuleContainers(module, ".", verbose=ctx.obj["verbose"]) - lock_file = manager.get_conda_lock_file(platform) + module_containers = ModuleContainers(module, ".", verbose=ctx.obj["verbose"]) + lock_file = module_containers.get_conda_lock_file(platform) stdout.print(lock_file) except (UserWarning, LookupError, FileNotFoundError, ValueError, RuntimeError) as e: log.error(e) @@ -456,8 +400,8 @@ def modules_containers_list(ctx, module, plain_text=False): from nf_core.modules.containers import ModuleContainers try: - manager = ModuleContainers(module, ".", verbose=ctx.obj["verbose"]) - containers = manager.list_containers() + module_containers = ModuleContainers(module, ".", verbose=ctx.obj["verbose"]) + containers = module_containers.list_containers() if plain_text: for cs, p, img in containers: diff --git a/nf_core/components/create.py b/nf_core/components/create.py index 78e1c5f7d7..a23ea4b9bf 100644 --- a/nf_core/components/create.py +++ b/nf_core/components/create.py @@ -177,6 +177,13 @@ def create(self) -> bool: run_prettier_on_file(new_files) log.info("Created following files:\n " + "\n ".join(new_files)) + + if self.component_type == "modules": + log.info( + f"Build Docker & Singularity images (Seqera/Wave) and update [magenta]main.nf[/] with the container URLs:\n" + f" [blue]nf-core modules containers create {self.component_name}[/]" + ) + return True def _get_bioconda_tool(self): diff --git a/nf_core/modules/bump_versions.py b/nf_core/modules/bump_versions.py index eb0e923324..ba5e2920be 100644 --- a/nf_core/modules/bump_versions.py +++ b/nf_core/modules/bump_versions.py @@ -21,7 +21,7 @@ import nf_core.utils from nf_core.components.components_command import ComponentCommand from nf_core.components.nfcore_component import NFCoreComponent -from nf_core.utils import NFCoreYamlConfig, custom_yaml_dumper, rich_force_colors +from nf_core.utils import NFCoreYamlConfig, rich_force_colors from nf_core.utils import plural_s as _s log = logging.getLogger(__name__) @@ -50,26 +50,29 @@ def bump_versions( all_modules: bool = False, show_up_to_date: bool = False, dry_run: bool = False, + hide_progress: bool = False, ) -> list[NFCoreComponent]: """ Bump the container and conda version of single module or all modules. If module is the name of a directory in the modules directory, all modules in that directory will be bumped. - Looks for a bioconda tool version in the `main.nf` file of the module and checks whether - are more recent version is available. If yes, then tries to get docker/singularity - container links and replace the bioconda version and the container links in the main.nf file - of the respective module. + Looks for a bioconda tool version in the `environment.yml` file of the module and checks + whether a more recent version is available. If yes, the pinned version + in `environment.yml` is bumped and the Docker/Singularity containers are rebuilt from it + with Wave. Args: module: a specific module to update all_modules: whether to bump versions for all modules show_up_to_date: whether to show up-to-date modules as well dry_run: whether to dry run the command + hide_progress: whether to hide the progress bars Returns: list[NFCoreComponent]: the updated modules """ + hide_progress = hide_progress or os.environ.get("HIDE_PROGRESS", None) is not None self.up_to_date = [] self.updated = [] self.failed = [] @@ -121,8 +124,9 @@ def bump_versions( BarColumn(bar_width=None), "[magenta]{task.completed} of {task.total}[reset] » [bold yellow]{task.fields[test_name]}", transient=True, - disable=os.environ.get("HIDE_PROGRESS", None) is not None, + disable=hide_progress, ) + modules_to_rebuild: list[NFCoreComponent] = [] with progress_bar: bump_progress = progress_bar.add_task( "Bumping nf-core modules versions", @@ -131,39 +135,72 @@ def bump_versions( ) for mod in nfcore_modules: progress_bar.update(bump_progress, advance=1, test_name=mod.component_name) - self.bump_module_version(mod) + if self.bump_module_version(mod): + modules_to_rebuild.append(mod) + + if modules_to_rebuild: + self._build_wave_containers(modules_to_rebuild, hide_progress) self._print_results() return nfcore_modules + def _build_wave_containers(self, modules: list[NFCoreComponent], hide_progress: bool = False) -> None: + """Rebuild the Docker/Singularity containers for ``modules`` with Seqera Wave. + + Builds from each module's (already bumped) environment.yml and updates main.nf, + meta.yml and the conda lock files. Modules whose build fails are added to + ``self.failed``. + """ + from nf_core.modules.containers import ModuleContainers + + log.info(f"Building Seqera containers for {len(modules)} bumped module{_s(modules)} with Wave...") + module_containers = ModuleContainers( + module=None, + directory=self.directory, + all_modules=True, + components=modules, + ) + ModuleContainers.check_tower_token() + failed_modules = module_containers.build_containers_with_progress(hide_progress=hide_progress) + for module_name in failed_modules: + self.failed.append(("Container build with Wave failed", module_name)) + def bump_module_version(self, module: NFCoreComponent) -> bool: """ Bump the bioconda and container version of a single NFCoreComponent Args: module: NFCoreComponent + + Returns: + True if the module's ``environment.yml`` was bumped and its containers therefore + need rebuilding; False if it was already up to date, ignored or failed. """ config_version = None - bioconda_packages = [] - try: - # Extract bioconda version from `environment.yml` - bioconda_packages = self.get_bioconda_version(module) - except FileNotFoundError: - # try it in the main.nf instead - try: - with open(module.main_nf) as fh: - for line in fh: - if "bioconda::" in line: - bioconda_packages = [b for b in line.split() if "bioconda::" in b] - except FileNotFoundError: - log.error( - f"Neither `environment.yml` nor `main.nf` of {module.component_name} module could be read to get bioconada version of used tools." - ) - - # If multiple versions - don't update! (can't update mulled containers) - if not bioconda_packages or len(bioconda_packages) > 1: - self.failed.append(("Ignoring mulled container", module.component_name)) + # Extract the pinned conda dependencies from `environment.yml`. Wave rebuilds the containers + # straight from this file, so every pinned package can be bumped - including multi-package + # ("mulled") modules, which earlier versions had to skip because the old mulled container + # names could not be regenerated. + dependencies = self.get_bioconda_version(module) + + # Only channel-pinned, versioned deps (e.g. `bioconda::samtools=1.21`) can be bumped; skip + # pip sub-dicts, unpinned deps and anything without a `channel::name=version` shape. + conda_packages: list[tuple[str, str, str]] = [] # (channel, tool_name, current_version) + for dep in dependencies: + if not isinstance(dep, str): + continue + spec = dep.strip("'").strip('"') + if "::" not in spec or "=" not in spec: + continue + channel, name_version = spec.split("::", 1) + tool_name, current_version = name_version.split("=", 1) + # Drop an optional build string (`name=version=build`) + current_version = current_version.split("=", 1)[0] + conda_packages.append((channel, tool_name, current_version)) + + if not conda_packages: + self.failed.append(("No pinned conda dependencies to bump", module.component_name)) return False # Don't update if blocked in blacklist @@ -173,118 +210,139 @@ def bump_module_version(self, module: NFCoreComponent) -> bool: if not config_version: self.ignored.append(("Omitting module due to config.", module.component_name)) return False - - # check for correct version and newer versions - bioconda_tool_name = bioconda_packages[0].split("=")[0].replace("bioconda::", "").strip("'").strip('"') - bp = bioconda_packages[0] - bp = bp.strip("'").strip('"') - bioconda_version = bp.split("=")[1] - - if not config_version: - try: - response = nf_core.utils.anaconda_package(bp) - except (LookupError, ValueError): + if len(conda_packages) > 1: + # A single pinned version in the config can't be mapped onto a multi-package module self.failed.append( - ( - f"Conda version not specified correctly: {Path(module.main_nf).relative_to(self.directory)}", - module.component_name, - ) + ("Cannot pin a version via config for a multi-package module", module.component_name) ) return False - # Check that required version is available at all - if bioconda_version not in response.get("versions"): - self.failed.append((f"Conda package had unknown version: `{module.main_nf}`", module.component_name)) - return False - - # Check version is latest available - last_ver = response.get("latest_version") - else: - last_ver = config_version - - if last_ver is not None and last_ver != bioconda_version: - log.debug(f"Updating version for {module.component_name}") - # Get docker and singularity container links - try: - docker_img, singularity_img = nf_core.utils.get_biocontainer_tag(bioconda_tool_name, last_ver) - except LookupError as e: - self.failed.append((f"Could not download container tags: {e}", module.component_name)) - return False - - patterns = [ - (rf"biocontainers/{bioconda_tool_name}:[^'\"\s]+", docker_img), - ( - rf"https://depot.galaxyproject.org/singularity/{bioconda_tool_name}:[^'\"\s]+", - singularity_img, - ), - ] - - with open(module.main_nf) as fh: - content = fh.read() + # Resolve the target version for every package: the latest available on Anaconda, or the + # version pinned in the config blacklist. + targets: list[tuple[str, str, str, str]] = [] # (channel, tool_name, current_version, target_version) + for channel, tool_name, current_version in conda_packages: + if config_version: + target_version = config_version + else: + dep_spec = f"{channel}::{tool_name}={current_version}" + try: + response = nf_core.utils.anaconda_package(dep_spec) + except (LookupError, ValueError): + self.failed.append( + ( + f"Conda version not specified correctly: {Path(module.environment_yml).relative_to(self.directory) if module.environment_yml else module.component_name}", + module.component_name, + ) + ) + return False - # Go over file content of main.nf and find replacements - for pattern in patterns: - found_match = False - newcontent = [] - for line in content.splitlines(): - # Match the pattern - matches_pattern = re.findall(rf"^.*{pattern[0]}.*$", line) - if matches_pattern: - found_match = True - - # Replace the match - newline = re.sub(pattern[0], pattern[1], line) - newcontent.append(newline) - # No match, keep line as it is - else: - newcontent.append(line) - - if found_match: - content = "\n".join(newcontent) + "\n" - else: + # Check that the pinned version is available at all + if current_version not in response.get("versions"): self.failed.append( - (f"Did not find pattern {pattern[0]} in module {module.component_name}", module.component_name) + (f"Conda package had unknown version: `{module.environment_yml}`", module.component_name) ) return False - # Write new content to the file - with open(module.main_nf, "w") as fh: - fh.write(content) + target_version = response.get("latest_version") + + if target_version is None: + continue + targets.append((channel, tool_name, current_version, target_version)) - # change version in environment.yml + if not targets: + self.up_to_date.append((f"Module version up to date: {module.component_name}", module.component_name)) + return False + + # Check 1: bump any dependency behind the latest. Wave rebuilds the containers from + # environment.yml afterwards (see bump_versions()), updating main.nf, meta.yml and conda locks. + outdated = [t for t in targets if t[3] != t[2]] + if outdated: if not module.environment_yml: log.error(f"Could not read `environment.yml` of {module.component_name} module.") + self.failed.append(("No environment.yml found to update", module.component_name)) return False + # Rewrite the versions in the raw file text so YAML comments (e.g. renovate hints) and + # formatting survive - a yaml load/dump round-trip would silently drop them. with open(module.environment_yml) as fh: - env_yml = yaml.safe_load(fh) - env_yml["dependencies"][0] = re.sub( - bioconda_packages[0], f"bioconda::{bioconda_tool_name}={last_ver}", env_yml["dependencies"][0] - ) + content = fh.read() + for channel, tool_name, current_version, target_version in outdated: + log.debug(f"Updating {tool_name} version for {module.component_name}") + content = re.sub( + rf"({re.escape(channel)}::{re.escape(tool_name)})=[^\s'\"]+", + rf"\g<1>={target_version}", + content, + ) + self.updated.append( + (f"Module updated: {tool_name} {current_version} --> {target_version}", module.component_name) + ) with open(module.environment_yml, "w") as fh: - yaml.dump(env_yml, fh, default_flow_style=False, Dumper=custom_yaml_dumper()) + fh.write(content) + return True - self.updated.append( - ( - f"Module updated: {bioconda_version} --> {last_ver}", - module.component_name, + # Check 2: environment.yml is already current, but make sure the containers were actually + # built for every package. An earlier run may have bumped environment.yml and then been + # interrupted before the Wave build wrote the new containers / conda locks. + for _channel, tool_name, _current_version, target_version in targets: + if not self._containers_built_for_version(module, tool_name, target_version): + self.updated.append( + (f"Containers out of date - rebuilding for version {target_version}", module.component_name) ) + return True + + self.up_to_date.append((f"Module version up to date: {module.component_name}", module.component_name)) + return False + + def _containers_built_for_version(self, module: NFCoreComponent, tool_name: str, version: str) -> bool: + """Return True if the module's Wave conda-lock files already pin ``tool_name`` at ``version``. + + Image names are content hashes, so the version-bearing conda locks are checked instead, + assuming the bioconda dependency name matches the conda package name. No ``.conda-lock`` dir + means the module was never Wave-built (left alone); an empty dir, or a meta.yml without a + ``containers:`` section, means an interrupted build (rebuilt). + """ + from nf_core.components.components_utils import read_meta_yml + + conda_lock_dir = module.component_dir / ".conda-lock" + if not conda_lock_dir.is_dir(): + log.debug( + f"No conda-lock directory for {module.component_name}; treating as up to date " + "(Wave migration is out of scope for bump-versions)" ) return True + lock_files = list(conda_lock_dir.glob("*.txt")) + if not lock_files: + # Empty dir: a finished build always leaves locks, so this one was interrupted. + log.debug(f"Empty conda-lock directory for {module.component_name}; containers need rebuilding") + return False + # Lock entries look like `.../samtools-1.21-h50ea8bc_0.conda`; trailing `-` keeps 1.21 from + # matching 1.210. Stream each file so the search short-circuits. + needle = f"/{tool_name}-{version}-" + for lock_file in lock_files: + with lock_file.open() as fh: + if not any(needle in line for line in fh): + return False - else: - self.up_to_date.append((f"Module version up to date: {module.component_name}", module.component_name)) - return True + # The containers section is written last, so its absence means an interrupted build. Only + # require it to be present, not complete (arm64 builds may legitimately be missing). + if module.meta_yml is None or not Path(module.meta_yml).exists(): + log.debug(f"No meta.yml for {module.component_name}; containers need rebuilding") + return False + if not read_meta_yml(Path(module.meta_yml)).get("containers"): + log.debug(f"meta.yml for {module.component_name} has no containers section; containers need rebuilding") + return False + + return True def get_bioconda_version(self, module: NFCoreComponent) -> list[str]: """ Extract the bioconda version from a module """ # Check whether file exists and load it - bioconda_packages = [] + bioconda_packages: list[str] = [] if module.environment_yml is not None and module.environment_yml.exists(): with open(module.environment_yml) as fh: env_yml = yaml.safe_load(fh) - bioconda_packages = env_yml.get("dependencies", []) + bioconda_packages = (env_yml or {}).get("dependencies") or [] else: log.error(f"Could not read `environment.yml` of {module.component_name} module.") diff --git a/nf_core/modules/containers.py b/nf_core/modules/containers.py index 9e701617c0..f3788f1053 100644 --- a/nf_core/modules/containers.py +++ b/nf_core/modules/containers.py @@ -1,7 +1,9 @@ import base64 +import hashlib import logging import os import re +import shutil import threading import time from collections.abc import Callable @@ -86,6 +88,16 @@ class ModuleContainers: Helpers for building, linting and listing module containers. """ + # Wave build results, keyed by (environment.yml content hash, container_system, platform). + # Modules with an identical environment.yml (e.g. samtools/sort and samtools/view) resolve + # to the same container, so this avoids submitting duplicate builds within one process. + _build_cache: dict[tuple[str, str, str], ContainerEntry] = {} + # Path to an already-written conda lock file, keyed by Wave build_id. Modules that share + # a cached build (above) also share a build_id, so a later module can copy the file that + # an earlier one already downloaded instead of re-fetching identical lock contents. + _conda_lock_paths: dict[str, Path] = {} + _build_cache_lock = threading.Lock() + def __init__( self, module: str | None, @@ -452,11 +464,22 @@ def callback(build_id: str) -> None: conda_lock_path.parent.mkdir(parents=True, exist_ok=True) try: - # Download conda lock file (it will look up build_id from docker container) - log.debug(f"Downloading conda lock file for {platform} to {conda_lock_path}") - if progress_bar and task_id is not None: - progress_bar.update(task_id, status=f"conda lock {short_platform}...") - conda_lock_path.write_text(self.get_conda_lock_file(platform)) + with self._build_cache_lock: + cached_lock_path = self._conda_lock_paths.get(build_id) + if cached_lock_path is not None and cached_lock_path.exists(): + log.debug(f"Reusing conda lock file for build {build_id} (from {cached_lock_path})") + if progress_bar and task_id is not None: + progress_bar.update(task_id, status=f"conda lock {short_platform} (cached)...") + if cached_lock_path != conda_lock_path: + shutil.copyfile(cached_lock_path, conda_lock_path) + else: + # Download conda lock file (it will look up build_id from docker container) + log.debug(f"Downloading conda lock file for {platform} to {conda_lock_path}") + if progress_bar and task_id is not None: + progress_bar.update(task_id, status=f"conda lock {short_platform}...") + conda_lock_path.write_text(self.get_conda_lock_file(platform)) + with self._build_cache_lock: + self._conda_lock_paths[build_id] = conda_lock_path # Only register the entry once the lock has actually been written, so # meta.yml never points at a missing lock file. containers.conda[platform] = CondaEntry(lock_file=str(conda_lock_path)) @@ -509,6 +532,95 @@ def _raise_if_build_failed(result: dict, build_ref: str, details_uri: str = "") details = details_uri or result.get("detailsUri") or "" raise RuntimeError(f"Wave build {build_ref} failed: {reason}. Build log: {details}") + def build_containers_with_progress(self, force: bool = False, hide_progress: bool = False) -> list[str]: + """Build Seqera/Wave containers for the selected module(s) with a live progress display. + + Builds the single selected module, or every module in ``available_modules`` when + the instance was created with ``all_modules=True``. Shows an overall module bar + plus, per module, the per-build spinners (docker/singularity × platform) that + :meth:`create` renders when a progress bar is passed. + + Args: + force: Overwrite existing container directives even if already correct. + hide_progress: Disable the live progress display. + + Returns: + The names of the modules whose builds failed. + """ + from rich.console import Group + from rich.live import Live + from rich.progress import BarColumn, MofNCompleteColumn, Progress, SpinnerColumn, TextColumn + + from nf_core.pipelines.containers_utils import try_generate_container_configs + from nf_core.pipelines.lint_utils import console + + if self.all_modules: + components = self.available_modules + else: + assert self.nfcore_component is not None + components = [self.nfcore_component] + + failed_modules: list[str] = [] + + overall_progress = Progress( + "[bold blue]{task.description}", + BarColumn(), + MofNCompleteColumn(), + console=console, + disable=hide_progress, + ) + module_progress = Progress( + SpinnerColumn(finished_text="[green]✓[/green]"), + "[bold blue]{task.description}", + TextColumn("{task.fields[status]}"), + console=console, + disable=hide_progress, + ) + + # Batch builds defer config generation to one full scan after the loop. + batch = len(components) > 1 + + with Live(Group(overall_progress, module_progress), console=console, transient=True): + # The overall bar is only useful when processing more than one module + overall_task_id = overall_progress.add_task("modules", total=len(components), visible=len(components) > 1) + for component in components: + module_name = component.component_name + module_task_id = module_progress.add_task( + f"[cyan]{module_name}[/cyan]", + total=None, + status="building containers...", + ) + try: + if self.all_modules: + # Per-module instance, reusing the already-scanned component list + module_containers = ModuleContainers( + module=module_name, + directory=self.directory, + verbose=self.verbose, + components=self.available_modules, + ) + else: + module_containers = self + _, success = module_containers.create( + progress_bar=module_progress, task_id=module_task_id, force=force + ) + if success: + if module_containers.repo_type == "pipeline" and not batch: + try_generate_container_configs(self.directory, module_containers.module_directory) + else: + failed_modules.append(module_name) + except (ValueError, RuntimeError, OSError) as e: + log.error(f"✗ Failed to build containers for {module_name}: {e}") + failed_modules.append(module_name) + finally: + overall_progress.advance(overall_task_id) + module_progress.remove_task(module_task_id) + + if batch and self.repo_type == "pipeline" and len(failed_modules) < len(components): + try_generate_container_configs(self.directory) + + return failed_modules + @classmethod def _await_build( cls, @@ -573,12 +685,20 @@ def request_container( assert container_system in CONTAINER_SYSTEMS assert platform in CONTAINER_PLATFORMS + conda_bytes = conda_file.read_bytes() + cache_key = (hashlib.sha256(conda_bytes).hexdigest(), container_system, platform) + with cls._build_cache_lock: + cached_entry = cls._build_cache.get(cache_key) + if cached_entry is not None: + log.debug(f"Reusing cached {container_system}/{platform} build for identical environment.yml") + return cached_entry + # Submit the build via the Wave HTTP API (POST /v1alpha2/container). # `freeze` with no buildRepository pushes to the public community registry. payload: dict = { "packages": { "type": "CONDA", - "environment": base64.b64encode(conda_file.read_bytes()).decode(), + "environment": base64.b64encode(conda_bytes).decode(), }, "containerPlatform": platform, "freeze": True, @@ -642,7 +762,10 @@ def request_container( f"https://{ContainerRegistryUrls.SEQERA_SINGULARITY.value}/blobs/sha256/{digest[:2]}/{digest}/data" ) - return ContainerEntry(name=image, build_id=build_id, scan_id=scan_id, https=https_url) + entry = ContainerEntry(name=image, build_id=build_id, scan_id=scan_id, https=https_url) + with cls._build_cache_lock: + cls._build_cache[cache_key] = entry + return entry @classmethod def request_image_inspect(cls, image: str) -> dict: diff --git a/tests/modules/test_bump_versions.py b/tests/modules/test_bump_versions.py index 63e6eb9c2c..5736047c9b 100644 --- a/tests/modules/test_bump_versions.py +++ b/tests/modules/test_bump_versions.py @@ -1,20 +1,24 @@ import re import tempfile from pathlib import Path +from types import SimpleNamespace +from unittest import mock import pytest import ruamel.yaml import nf_core.modules.bump_versions from nf_core import __version__ -from nf_core.modules.modules_utils import ModuleExceptionError +from nf_core.modules.containers import ModuleContainers +from nf_core.modules.modules_utils import MetaYmlContainers, ModuleExceptionError from nf_core.utils import NFCoreYamlConfig from ..test_modules import TestModules class TestModulesBumpVersions(TestModules): - def test_modules_bump_versions_single_module(self): + @mock.patch.object(nf_core.modules.bump_versions.ModuleVersionBumper, "_build_wave_containers") + def test_modules_bump_versions_single_module(self, mock_build): """Test updating a single module""" # Change the bpipe/test version to an older version env_yml_path = Path(self.nfcore_modules, "modules", "nf-core", "bpipe", "test", "environment.yml") @@ -24,17 +28,35 @@ def test_modules_bump_versions_single_module(self): with open(env_yml_path, "w") as fh: fh.write(new_content) version_bumper = nf_core.modules.bump_versions.ModuleVersionBumper(pipeline_dir=self.nfcore_modules) + # mock_build keeps the Wave container rebuild from shelling out to the `wave` CLI modules = version_bumper.bump_versions(module="bpipe/test") assert len(version_bumper.failed) == 0 assert [m.component_name for m in modules] == ["bpipe/test"] - def test_modules_bump_versions_all_modules(self): + @mock.patch.object(nf_core.modules.bump_versions.ModuleVersionBumper, "_build_wave_containers") + def test_modules_bump_versions_all_modules(self, mock_build): """Test updating all modules""" version_bumper = nf_core.modules.bump_versions.ModuleVersionBumper(pipeline_dir=self.nfcore_modules) modules = version_bumper.bump_versions(all_modules=True) assert len(version_bumper.failed) == 0 assert [m.component_name for m in modules] == ["bpipe/test"] + @mock.patch.object(ModuleContainers, "create", return_value=(MetaYmlContainers(), False)) + def test_build_wave_containers(self, mock_create): + """Test building Wave containers and recording failed modules.""" + module_containers = ModuleContainers("bpipe/test", directory=self.nfcore_modules) + module = module_containers.nfcore_component + assert module is not None + version_bumper = nf_core.modules.bump_versions.ModuleVersionBumper(pipeline_dir=self.nfcore_modules) + + with mock.patch.dict("os.environ", {"TOWER_ACCESS_TOKEN": ""}): + version_bumper._build_wave_containers([module]) + + # ModuleContainers and its batch progress logic are real; only the external build is mocked. + mock_create.assert_called_once() + assert "TOWER_ACCESS_TOKEN is not set" in self.caplog.text + assert version_bumper.failed == [("Container build with Wave failed", "bpipe/test")] + @staticmethod def _mock_nf_core_yml(root_dir: Path) -> None: """Mock the .nf_core.yml""" @@ -87,6 +109,191 @@ def test_modules_bump_versions_submodules(self): out_modules = version_bumper.bump_versions(module="fgbio", dry_run=True) assert sorted([m.component_name for m in out_modules]) == sorted(in_modules) + def test_containers_built_for_version(self): + """Check-2: detect whether a module's conda locks already pin the current version.""" + # Bypass __init__ - the method only uses the passed module's component_dir + bumper = nf_core.modules.bump_versions.ModuleVersionBumper.__new__( + nf_core.modules.bump_versions.ModuleVersionBumper + ) + mod_dir = Path(tempfile.mkdtemp()) + meta_yml = mod_dir / "meta.yml" + module = SimpleNamespace(component_dir=mod_dir, component_name="samtools/sort", meta_yml=meta_yml) + + # No .conda-lock dir at all -> not Wave-managed, treated as up to date (no rebuild) + assert bumper._containers_built_for_version(module, "samtools", "1.21") is True + + lock_dir = mod_dir / ".conda-lock" + lock_dir.mkdir() + # Empty .conda-lock dir -> a Wave build was started but interrupted before writing locks + assert bumper._containers_built_for_version(module, "samtools", "1.21") is False + + (lock_dir / "linux_amd64-bd-abc_1.txt").write_text( + "- conda: https://conda.anaconda.org/bioconda/noarch/samtools-1.21-h50ea8bc_0.conda\n" + ) + # Lock current but meta.yml missing its containers section (build interrupted before the + # final meta.yml write) -> rebuild + meta_yml.write_text("name: samtools_sort\n") + assert bumper._containers_built_for_version(module, "samtools", "1.21") is False + + # Lock current AND meta.yml carries a containers section -> already built, no rebuild + meta_yml.write_text("name: samtools_sort\ncontainers:\n docker:\n linux/amd64:\n name: img\n") + assert bumper._containers_built_for_version(module, "samtools", "1.21") is True + # Trailing dash anchors the match so 1.21 does not also match 1.210 + assert bumper._containers_built_for_version(module, "samtools", "1.2") is False + # Lock pins an older version (e.g. interrupted build left stale locks) -> rebuild + assert bumper._containers_built_for_version(module, "samtools", "1.22") is False + + @mock.patch.object(nf_core.modules.bump_versions.ModuleVersionBumper, "_build_wave_containers") + @mock.patch("nf_core.utils.anaconda_package") + def test_modules_bump_versions_stale_containers_rebuild(self, mock_anaconda, mock_build): + """Check-2 integration: version is current but the conda locks are stale -> rebuild queued. + + Mirrors an earlier run that bumped environment.yml but was interrupted before the Wave + build finished, leaving conda locks pinned to the previous version. + """ + # bpipe/test pins bioconda::bpipe=0.9.13; report that as the latest so check-1 is a no-op + mock_anaconda.return_value = {"versions": ["0.9.13"], "latest_version": "0.9.13"} + + # Leave behind a stale conda lock (older version) for the module + lock_dir = Path(self.nfcore_modules, "modules", "nf-core", "bpipe", "test", ".conda-lock") + lock_dir.mkdir(parents=True, exist_ok=True) + (lock_dir / "linux_amd64-bd-stale_1.txt").write_text( + "- conda: https://conda.anaconda.org/bioconda/noarch/bpipe-0.9.12-hdfd78af_0.conda\n" + ) + + version_bumper = nf_core.modules.bump_versions.ModuleVersionBumper(pipeline_dir=self.nfcore_modules) + version_bumper.bump_versions(module="bpipe/test") + + assert len(version_bumper.failed) == 0 + mock_build.assert_called_once() + assert [m.component_name for m in mock_build.call_args.args[0]] == ["bpipe/test"] + assert any("Containers out of date" in msg for msg, _ in version_bumper.updated) + + @mock.patch.object(nf_core.modules.bump_versions.ModuleVersionBumper, "_build_wave_containers") + @mock.patch("nf_core.utils.anaconda_package") + def test_modules_bump_versions_interrupted_build_rebuild(self, mock_anaconda, mock_build): + """Check-2 integration: version current, empty .conda-lock dir (interrupted build) -> rebuild.""" + mock_anaconda.return_value = {"versions": ["0.9.13"], "latest_version": "0.9.13"} + + # An interrupted build created the .conda-lock dir but wrote no locks + lock_dir = Path(self.nfcore_modules, "modules", "nf-core", "bpipe", "test", ".conda-lock") + lock_dir.mkdir(parents=True, exist_ok=True) + + version_bumper = nf_core.modules.bump_versions.ModuleVersionBumper(pipeline_dir=self.nfcore_modules) + version_bumper.bump_versions(module="bpipe/test") + + assert len(version_bumper.failed) == 0 + mock_build.assert_called_once() + assert [m.component_name for m in mock_build.call_args.args[0]] == ["bpipe/test"] + + @mock.patch.object(nf_core.modules.bump_versions.ModuleVersionBumper, "_build_wave_containers") + @mock.patch("nf_core.utils.anaconda_package") + def test_modules_bump_versions_missing_meta_containers_rebuild(self, mock_anaconda, mock_build): + """Check-2 integration: locks current but meta.yml has no containers section -> rebuild. + + Mirrors a build interrupted after writing the conda locks but before meta.yml/main.nf. + """ + mock_anaconda.return_value = {"versions": ["0.9.13"], "latest_version": "0.9.13"} + + module_dir = Path(self.nfcore_modules, "modules", "nf-core", "bpipe", "test") + # Current-version lock present... + lock_dir = module_dir / ".conda-lock" + lock_dir.mkdir(parents=True, exist_ok=True) + (lock_dir / "linux_amd64-bd-current_1.txt").write_text( + "- conda: https://conda.anaconda.org/bioconda/noarch/bpipe-0.9.13-hdfd78af_0.conda\n" + ) + # ...but the containers section never got written (build interrupted before meta.yml) + meta_path = module_dir / "meta.yml" + yaml = ruamel.yaml.YAML() + with open(meta_path) as fh: + meta = yaml.load(fh) + meta.pop("containers", None) + with open(meta_path, "w") as fh: + yaml.dump(meta, fh) + + version_bumper = nf_core.modules.bump_versions.ModuleVersionBumper(pipeline_dir=self.nfcore_modules) + version_bumper.bump_versions(module="bpipe/test") + + assert len(version_bumper.failed) == 0 + mock_build.assert_called_once() + assert [m.component_name for m in mock_build.call_args.args[0]] == ["bpipe/test"] + + @mock.patch.object(nf_core.modules.bump_versions.ModuleVersionBumper, "_build_wave_containers") + @mock.patch("nf_core.utils.anaconda_package") + def test_modules_bump_versions_current_containers_no_rebuild(self, mock_anaconda, mock_build): + """Check-2 integration: version current, locks match AND meta has containers -> no rebuild.""" + mock_anaconda.return_value = {"versions": ["0.9.13"], "latest_version": "0.9.13"} + + module_dir = Path(self.nfcore_modules, "modules", "nf-core", "bpipe", "test") + # Conda lock already pins the current version + lock_dir = module_dir / ".conda-lock" + lock_dir.mkdir(parents=True, exist_ok=True) + (lock_dir / "linux_amd64-bd-current_1.txt").write_text( + "- conda: https://conda.anaconda.org/bioconda/noarch/bpipe-0.9.13-hdfd78af_0.conda\n" + ) + # ...and meta.yml carries a containers section, so the build is considered complete + meta_path = module_dir / "meta.yml" + yaml = ruamel.yaml.YAML() + with open(meta_path) as fh: + meta = yaml.load(fh) + meta["containers"] = {"docker": {"linux/amd64": {"name": "img"}}} + with open(meta_path, "w") as fh: + yaml.dump(meta, fh) + + version_bumper = nf_core.modules.bump_versions.ModuleVersionBumper(pipeline_dir=self.nfcore_modules) + version_bumper.bump_versions(module="bpipe/test") + + assert len(version_bumper.failed) == 0 + mock_build.assert_not_called() + assert any("up to date" in msg for msg, _ in version_bumper.up_to_date) + + @mock.patch("nf_core.utils.anaconda_package") + def test_modules_bump_versions_multi_package(self, mock_anaconda): + """Multi-package ('mulled') modules are now bumped, not skipped, and YAML comments survive.""" + mock_anaconda.return_value = {"versions": ["1.21", "1.23.1"], "latest_version": "1.23.1"} + + mod_dir = Path(tempfile.mkdtemp()) + env_yml = mod_dir / "environment.yml" + env_yml.write_text( + "channels:\n" + " - conda-forge\n" + " - bioconda\n" + "dependencies:\n" + " # renovate: datasource=conda depName=bioconda/htslib\n" + " - bioconda::htslib=1.21\n" + " # renovate: datasource=conda depName=bioconda/samtools\n" + " - bioconda::samtools=1.21\n" + ) + + # Bypass __init__ - bump_module_version only needs the result lists, tools_config and directory + bumper = nf_core.modules.bump_versions.ModuleVersionBumper.__new__( + nf_core.modules.bump_versions.ModuleVersionBumper + ) + bumper.failed = [] + bumper.ignored = [] + bumper.updated = [] + bumper.up_to_date = [] + bumper.directory = mod_dir + bumper.tools_config = SimpleNamespace() + module = SimpleNamespace( + component_name="samtools/cat", + component_dir=mod_dir, + environment_yml=env_yml, + meta_yml=None, + ) + + assert bumper.bump_module_version(module) is True + assert bumper.failed == [] + assert len(bumper.updated) == 2 + + new_content = env_yml.read_text() + # Both bioconda packages were bumped... + assert "bioconda::htslib=1.23.1" in new_content + assert "bioconda::samtools=1.23.1" in new_content + # ...and the renovate comments were preserved (no yaml round-trip) + assert "# renovate: datasource=conda depName=bioconda/htslib" in new_content + assert "# renovate: datasource=conda depName=bioconda/samtools" in new_content + def test_modules_bump_versions_fail(self): """Fail updating a module with wrong name""" version_bumper = nf_core.modules.bump_versions.ModuleVersionBumper(pipeline_dir=self.nfcore_modules) diff --git a/tests/modules/test_containers.py b/tests/modules/test_containers.py index 8b137a5196..b48b75b018 100644 --- a/tests/modules/test_containers.py +++ b/tests/modules/test_containers.py @@ -19,6 +19,10 @@ def setUp(self): super().setUp() self.environment_yml = self.bpipe_test_module_path / "environment.yml" self.module_containers = ModuleContainers("bpipe/test", directory=self.nfcore_modules) + # Avoid a build/lock cached by one test being reused by another (all fixtures share + # the same environment.yml content / build_id). + ModuleContainers._build_cache.clear() + ModuleContainers._conda_lock_paths.clear() def _write_meta(self, meta: dict) -> None: (self.bpipe_test_module_path / "meta.yml").write_text(yaml.safe_dump(meta), encoding="utf-8") @@ -377,33 +381,75 @@ def _create_local_module(self, module_name: str = "testmodule") -> Path: def test_init_pipeline_sets_local_module_paths(self): """ModuleContainers should resolve paths into modules/local/ for a pipeline repo""" module_dir = self._create_local_module("testmodule") - manager = ModuleContainers("testmodule", directory=self.pipeline_dir) + module_containers = ModuleContainers("testmodule", directory=self.pipeline_dir) - assert manager.repo_type == "pipeline" - assert manager.module_directory == module_dir - assert manager.environment_yml == module_dir / "environment.yml" - assert manager.meta_yml == module_dir / "meta.yml" + assert module_containers.repo_type == "pipeline" + assert module_containers.module_directory == module_dir + assert module_containers.environment_yml == module_dir / "environment.yml" + assert module_containers.meta_yml == module_dir / "meta.yml" def test_update_containers_in_meta_pipeline(self): """update_containers_in_meta writes containers to the local module's meta.yml""" module_dir = self._create_local_module("testmodule") - manager = ModuleContainers("testmodule", directory=self.pipeline_dir) + module_containers = ModuleContainers("testmodule", directory=self.pipeline_dir) containers = MetaYmlContainers( docker={p: ContainerEntry(name=f"docker-{p}") for p in CONTAINER_PLATFORMS}, singularity={p: ContainerEntry(name=f"sif-{p}") for p in CONTAINER_PLATFORMS}, conda={p: CondaEntry(lock_file=f"/lock/{p}.txt") for p in CONTAINER_PLATFORMS}, ) - manager.containers = containers + module_containers.containers = containers - with mock.patch.object(manager, "create") as mock_create: - manager.update_containers_in_meta() + with mock.patch.object(module_containers, "create") as mock_create: + module_containers.update_containers_in_meta() mock_create.assert_not_called() meta = yaml.safe_load((module_dir / "meta.yml").read_text(encoding="utf-8")) assert meta["containers"] == containers.dump_for_meta_yml() +class TestBuildContainersWithProgress(TestModules): + """Tests for the ``ModuleContainers.build_containers_with_progress`` method. + + ``create`` is mocked throughout so the tests cover the batch/aggregation logic + regardless of how containers are actually built (Wave API vs CLI). + """ + + def setUp(self): + super().setUp() + self.module_containers = ModuleContainers("bpipe/test", directory=self.nfcore_modules) + self.component = self.module_containers.nfcore_component + self.module_name = self.component.component_name + + def test_success_returns_no_failures(self): + with mock.patch.object(ModuleContainers, "create", return_value=(MetaYmlContainers(), True)) as mock_create: + failed = self.module_containers.build_containers_with_progress(hide_progress=True) + assert failed == [] + mock_create.assert_called_once() + + def test_build_failure_is_reported(self): + """A module whose create() returns success=False is reported as failed.""" + with mock.patch.object(ModuleContainers, "create", return_value=(MetaYmlContainers(), False)): + failed = self.module_containers.build_containers_with_progress(hide_progress=True) + assert failed == [self.module_name] + + def test_exception_during_build_is_caught(self): + """A RuntimeError from create() is caught and the module is reported as failed.""" + with mock.patch.object(ModuleContainers, "create", side_effect=RuntimeError("boom")): + failed = self.module_containers.build_containers_with_progress(hide_progress=True) + assert failed == [self.module_name] + + def test_all_modules_reconstructs_per_module_containers(self): + """In batch mode a fresh per-module instance is built, reusing the scanned component list.""" + all_module_containers = ModuleContainers( + module=None, directory=self.nfcore_modules, all_modules=True, components=[self.component] + ) + with mock.patch.object(ModuleContainers, "create", return_value=(MetaYmlContainers(), True)) as mock_create: + failed = all_module_containers.build_containers_with_progress(hide_progress=True) + assert failed == [] + mock_create.assert_called_once() + + class TestModuleContainersDockerfile(TestModuleContainersPipeline): """Tests for ModuleContainers behaviour when a module uses a Dockerfile instead of environment.yml""" From 8bf8e72a92c356e20695fa076aefa945dff9a287 Mon Sep 17 00:00:00 2001 From: Damon-Lee Pointon <51855558+DLBPointon@users.noreply.github.com> Date: Fri, 17 Jul 2026 09:28:07 +0100 Subject: [PATCH 104/135] 4250 meta key linting (#4280) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber Co-authored-by: mashehu --- CHANGELOG.md | 1 + nf_core/modules/lint/main_nf.py | 56 +++++++++++++----------------- tests/modules/lint/test_main_nf.py | 14 +++----- 3 files changed, 31 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f437aa8a1..fde275e9dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - accept `process_low_memory` as a standard module label ([#4264](https://github.com/nf-core/tools/pull/4264)) - improve linting for `modules.json` to add support for only installing subworkflows from a repository and provide more explicit error messages ([#4287](https://github.com/nf-core/tools/pull/4287)) - improve singularity_tag linting check (add skip, handle exceptions correctly, check against oras) ([#4358](https://github.com/nf-core/tools/pull/4358)) +- make regex for meta keys more specific to avoid false positives ([#4280](https://github.com/nf-core/tools/pull/4280)) ### Modules diff --git a/nf_core/modules/lint/main_nf.py b/nf_core/modules/lint/main_nf.py index 04b669a275..699de45abe 100644 --- a/nf_core/modules/lint/main_nf.py +++ b/nf_core/modules/lint/main_nf.py @@ -393,7 +393,7 @@ def check_script_section(self, lines): permitted_meta_keys = {"id", "single_end"} invalid_meta_keys = [ f"{prefix}{key}" - for prefix, key in re.findall(r"\b(meta\d*\??\.)(\w+)\b(?!\()", script) + for prefix, key in re.findall(r"(? Date: Fri, 17 Jul 2026 11:06:03 +0200 Subject: [PATCH 105/135] Pipeline template: New pre-commit hooks (large files, merge conflicts) (#3935) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: nf-core-bot Co-authored-by: Matthias Hörtenhuber Co-authored-by: mashehu --- CHANGELOG.md | 1 + .../.hooks/block_pipeline_outdir.sh | 44 +++++++++++++++++++ .../pipeline-template/.pre-commit-config.yaml | 17 +++++++ .../pipelines/create/template_features.yml | 1 + 4 files changed, 63 insertions(+) create mode 100755 nf_core/pipeline-template/.hooks/block_pipeline_outdir.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index fde275e9dd..2f316c89b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ ### Template +- New pre-commit hooks blocking large files and merge markers in pipeline template ([#3935](https://github.com/nf-core/tools/pull/3935)) - add `process_low_memory` resource label to `base.config` ([#4264](https://github.com/nf-core/tools/pull/4264)) - fix dead link ([#4307](https://github.com/nf-core/tools/pull/4307)) - remove date placeholder from changelog title ([#4333](https://github.com/nf-core/tools/pull/4333)) diff --git a/nf_core/pipeline-template/.hooks/block_pipeline_outdir.sh b/nf_core/pipeline-template/.hooks/block_pipeline_outdir.sh new file mode 100755 index 0000000000..e9ba4f9338 --- /dev/null +++ b/nf_core/pipeline-template/.hooks/block_pipeline_outdir.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# This hook is used to block commits if they include staged files inside a directory +# which also contains a subdirectory called `pipeline_info`. The purpose of this is to +# prevent users from inadvertently committing output from pipeline test runs inside the +# development directory. + +set -e + +status=0 +seen_dirs="" + +while IFS= read -r file; do + # The offending output bundle's root is the ancestor directory that has + # `pipeline_info` as an immediate child, so callers can restore it in one go. + if [[ "$file" == pipeline_info/* ]]; then + top_dir="pipeline_info" + elif [[ "$file" == */pipeline_info/* ]]; then + top_dir="${file%%/pipeline_info/*}" + else + top_dir="" + dir=$(dirname "$file") + while [[ "$dir" != "." && "$dir" != "/" ]]; do + if [[ -d "$dir/pipeline_info" ]]; then + top_dir="$dir" + break + fi + dir=$(dirname "$dir") + done + fi + + if [[ -n "$top_dir" ]]; then + echo "❌ Commit blocked: Please do not commit output from pipeline test runs to the pipeline code itself: $file" + status=1 + case "$seen_dirs" in + *"|$top_dir|"*) ;; + *) + echo "Run 'git restore --staged $top_dir' to remove the whole output folder from the staging area." + seen_dirs="$seen_dirs|$top_dir|" + ;; + esac + fi +done < <(git diff --cached --name-only) + +exit "$status" diff --git a/nf_core/pipeline-template/.pre-commit-config.yaml b/nf_core/pipeline-template/.pre-commit-config.yaml index a6d370f4bd..a136ace058 100644 --- a/nf_core/pipeline-template/.pre-commit-config.yaml +++ b/nf_core/pipeline-template/.pre-commit-config.yaml @@ -25,9 +25,26 @@ repos: subworkflows/(?!local/).*| .*\.snap$ )$ + - id: check-added-large-files + args: [--maxkb=5000] + exclude: | + (?x)^( + .*ro-crate-metadata.json$| + .*\.snap$| + lib/nfcore_external_java_deps.jar$| + docs/.*\.(svg|pdf)$| + assets/.*$ + )$ + - id: check-merge-conflict - repo: https://github.com/seqeralabs/nf-lint-pre-commit rev: v0.3.0 hooks: - id: nextflow-lint files: '\.nf$|nextflow\.config$' args: ["-output", "json"] + - repo: local + hooks: + - id: block-pipeline-outdir + name: Prevent committing output from pipeline test runs to the pipeline code itself + entry: ./.hooks/block_pipeline_outdir.sh + language: script diff --git a/nf_core/pipelines/create/template_features.yml b/nf_core/pipelines/create/template_features.yml index 6c5036a9d3..d5678f65b1 100644 --- a/nf_core/pipelines/create/template_features.yml +++ b/nf_core/pipelines/create/template_features.yml @@ -434,6 +434,7 @@ code_quality: - ".prettierignore" - ".prettierrc.yml" - ".github/workflows/fix-linting.yml" + - ".hooks/block_pipeline_outdir.sh" short_description: "Use code linters" description: "The pipeline will include code linters and CI tests to lint your code: pre-commit, editor-config and prettier." help_text: | From 353f0aaf0805061c05f619721934578bf90cdfcd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 17 Jul 2026 09:21:54 +0000 Subject: [PATCH 106/135] Update actions/setup-java digest to 03ad4de (#4397) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/nextflow-source-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index 55b77eac15..465a6510ab 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -20,7 +20,7 @@ jobs: path: nextflow - name: Set up Java - uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5 + uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5 with: distribution: "temurin" architecture: x64 From 4a51a69daf20d617facd7c70d0e121b710e1d821 Mon Sep 17 00:00:00 2001 From: Maxime U Garcia Date: Fri, 17 Jul 2026 11:35:50 +0200 Subject: [PATCH 107/135] Simpler test data path in tests/nextflow.config (#4285) Co-authored-by: mashehu --- .github/workflows/codspeed.yml | 8 ++++++-- CHANGELOG.md | 1 + nf_core/pipeline-template/tests/nextflow.config | 5 +++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index dc3c222bea..dfeeaee85e 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -5,9 +5,13 @@ on: branches: - main - dev + paths: + - codspeed.yml + - nf_core/**/*.py pull_request: - # `workflow_dispatch` allows CodSpeed to trigger backtest - # performance analysis in order to generate initial data. + paths: + - codspeed.yml + - nf_core/**/*.py workflow_dispatch: # Cancel if a newer run with the same workflow name is queued diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f316c89b8..fd8eb908a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - New pre-commit hooks blocking large files and merge markers in pipeline template ([#3935](https://github.com/nf-core/tools/pull/3935)) - add `process_low_memory` resource label to `base.config` ([#4264](https://github.com/nf-core/tools/pull/4264)) +- Simpler test data path in `tests/nextflow.config` ([#4285](https://github.com/nf-core/tools/pull/4285)) - fix dead link ([#4307](https://github.com/nf-core/tools/pull/4307)) - remove date placeholder from changelog title ([#4333](https://github.com/nf-core/tools/pull/4333)) - correct always-true `nf-core pipelines lint` condition in the linting workflow and fix doc typos (broken `#lint-tests` anchor, duplicate word, stray code-span space) ([#4324](https://github.com/nf-core/tools/pull/4324)) diff --git a/nf_core/pipeline-template/tests/nextflow.config b/nf_core/pipeline-template/tests/nextflow.config index f867b22761..37a508dfb2 100644 --- a/nf_core/pipeline-template/tests/nextflow.config +++ b/nf_core/pipeline-template/tests/nextflow.config @@ -8,7 +8,8 @@ // Or any resources requirements params { modules_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/' - pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/{{ short_name }}/' + pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/{{ short_name }}/' } -aws.client.anonymous = true // fixes S3 access issues on self-hosted runners +// Fixes S3 access issues on self-hosted runners +aws.client.anonymous = true From b2493f5a518e885c3928e54365d566db1ea02ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Fri, 17 Jul 2026 11:57:08 +0200 Subject: [PATCH 108/135] switch to more secure split PR comment approach (#4342) --- .github/workflows/branch.yml | 62 +++++++++++------ .github/workflows/codspeed.yml | 2 +- .github/workflows/pr-comment.yml | 66 ++++++++++++++++++ .github/workflows/test_offline_configs.yml | 8 +-- .prettierignore | 2 + CHANGELOG.md | 1 + .../.github/actions/nf-test/action.yml | 2 +- .../.github/workflows/branch.yml | 60 ++++++++++------ .../.github/workflows/linting.yml | 20 +++++- .../.github/workflows/linting_comment.yml | 28 -------- .../.github/workflows/pr-comment.yml | 68 +++++++++++++++++++ .../workflows/release-announcements.yml | 2 +- .../workflows/template-version-comment.yml | 56 +++++++++------ .../pipelines/create/template_features.yml | 4 +- nf_core/pipelines/lint/files_exist.py | 4 +- nf_core/pipelines/lint/files_unchanged.py | 4 +- 16 files changed, 282 insertions(+), 107 deletions(-) create mode 100644 .github/workflows/pr-comment.yml delete mode 100644 nf_core/pipeline-template/.github/workflows/linting_comment.yml create mode 100644 nf_core/pipeline-template/.github/workflows/pr-comment.yml diff --git a/.github/workflows/branch.yml b/.github/workflows/branch.yml index addbc7bcbd..260954884c 100644 --- a/.github/workflows/branch.yml +++ b/.github/workflows/branch.yml @@ -2,8 +2,11 @@ name: nf-core branch protection # This workflow is triggered on PRs to main branch on the repository # It fails when someone tries to make a PR against the nf-core `main` branch instead of `dev` on: - pull_request_target: - branches: [main] + pull_request: + branches: + - main + +permissions: {} jobs: test: @@ -12,32 +15,47 @@ jobs: # PRs to the nf-core repo main branch are only ok if coming from the nf-core repo `dev` or any `patch` branches - name: Check PRs if: github.repository == 'nf-core/tools' + env: + HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} run: | - { [[ ${{github.event.pull_request.head.repo.full_name}} == nf-core/tools ]] && [[ $GITHUB_HEAD_REF == "dev" ]]; } || [[ $GITHUB_HEAD_REF == "patch" ]] + { [[ "$HEAD_REPO" == "nf-core/tools" ]] && [[ "$GITHUB_HEAD_REF" == "dev" ]]; } || [[ "$GITHUB_HEAD_REF" == "patch" ]] - # If the above check failed, post a comment on the PR explaining the failure - - name: Post PR comment + # If the above check failed, build a comment to be posted by the shared poster workflow + - name: Build PR comment if: failure() - uses: mshick/add-pr-comment@ec328af66588ab8f77cdeb2c264f14aba45bbf59 # v3 - with: - message: | - ## This PR is against the `main` branch :x: + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + BASE_REF: ${{ github.event.pull_request.base.ref }} + HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} + PR_USER: ${{ github.event.pull_request.user.login }} + run: | + mkdir -p pr-comment + echo "$PR_NUMBER" > pr-comment/pr_number.txt + echo "branch" > pr-comment/header.txt + cat > pr-comment/comment.md <> "$GITHUB_OUTPUT" + echo "header=$header" >> "$GITHUB_OUTPUT" + echo "post=true" >> "$GITHUB_OUTPUT" + + - name: Post PR comment + if: steps.meta.outputs.post == 'true' + uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + number: ${{ steps.meta.outputs.pr_number }} + header: ${{ steps.meta.outputs.header }} + path: pr-comment/comment.md diff --git a/.github/workflows/test_offline_configs.yml b/.github/workflows/test_offline_configs.yml index f0ce39e681..61cb532304 100644 --- a/.github/workflows/test_offline_configs.yml +++ b/.github/workflows/test_offline_configs.yml @@ -67,28 +67,28 @@ jobs: fetch-depth: "0" - name: Check the correct default config base of the nf-core configs id: check_default_config - uses: GuillaumeFalourd/assert-command-line-output@2cd32f7751887b5ef1886521de68ea2ec3e2aee7 # v2 + uses: GuillaumeFalourd/assert-command-line-output@63ad23408d758ee7f09b4557cc0901d6ae4f3f76 # v2.4 with: command_line: nextflow config -value params.custom_config_base . contains: https://raw.githubusercontent.com/nf-core/configs/master expected_result: PASSED - name: Check the correct inclusion of an existing institutional profile id: check_profile_inclusion - uses: GuillaumeFalourd/assert-command-line-output@2cd32f7751887b5ef1886521de68ea2ec3e2aee7 # v2 + uses: GuillaumeFalourd/assert-command-line-output@63ad23408d758ee7f09b4557cc0901d6ae4f3f76 # v2.4 with: command_line: nextflow config -profile google -o flat . contains: "The nf-core framework" # Part of CITATION.cff, should always be printed if profile is included expected_result: PASSED - name: Check the failed inclusion of a non-existing institutional profile id: check_nonexistent_profile - uses: GuillaumeFalourd/assert-command-line-output@2cd32f7751887b5ef1886521de68ea2ec3e2aee7 # v2 + uses: GuillaumeFalourd/assert-command-line-output@63ad23408d758ee7f09b4557cc0901d6ae4f3f76 # v2.4 with: command_line: nextflow config -profile GLaDOS -o flat . contains: "Unknown configuration profile: 'GLaDOS'" expected_result: PASSED - name: Check that offline prevents inclusion of nf-core configs id: check_offline_mode - uses: GuillaumeFalourd/assert-command-line-output@2cd32f7751887b5ef1886521de68ea2ec3e2aee7 # v2 + uses: GuillaumeFalourd/assert-command-line-output@63ad23408d758ee7f09b4557cc0901d6ae4f3f76 # v2.4 env: NXF_OFFLINE: true with: diff --git a/.prettierignore b/.prettierignore index f2983fc968..61ff2bcca6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,7 +6,9 @@ nf_core/pipeline-template/nextflow_schema.json nf_core/pipeline-template/modules.json nf_core/pipeline-template/tower.yml nf_core/pipeline-template/.github/ISSUE_TEMPLATE/bug_report.yml +nf_core/pipeline-template/.github/workflows/branch.yml nf_core/pipeline-template/.github/workflows/nf-test.yml +nf_core/pipeline-template/.github/workflows/pr-comment.yml tests/data/pipeline_create_template_skip.yml # don't run on things handled by ruff *.py diff --git a/CHANGELOG.md b/CHANGELOG.md index fd8eb908a6..622987cc5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ - remove date placeholder from changelog title ([#4333](https://github.com/nf-core/tools/pull/4333)) - correct always-true `nf-core pipelines lint` condition in the linting workflow and fix doc typos (broken `#lint-tests` anchor, duplicate word, stray code-span space) ([#4324](https://github.com/nf-core/tools/pull/4324)) - Fix publishDir configuration in modules.config for multiqc ([#4347](https://github.com/nf-core/tools/pull/4347)) +- Switch to a more secure approach for PR comments by splitting the GitHub Actions workflow ([#4342](https://github.com/nf-core/tools/pull/4342)) ### Download diff --git a/nf_core/pipeline-template/.github/actions/nf-test/action.yml b/nf_core/pipeline-template/.github/actions/nf-test/action.yml index 90397426f6..0d1583b9ef 100644 --- a/nf_core/pipeline-template/.github/actions/nf-test/action.yml +++ b/nf_core/pipeline-template/.github/actions/nf-test/action.yml @@ -37,7 +37,7 @@ runs: - name: Setup apptainer if: contains(inputs.profile, 'singularity') - uses: eWaterCycle/setup-apptainer@3f706d898c9db585b1d741b4692e66755f3a1b40 # v2 + uses: eWaterCycle/setup-apptainer@4bb22c52d4f63406c49e94c804632975787312b3 # v2.0.0 - name: Set up Singularity if: contains(inputs.profile, 'singularity') diff --git a/nf_core/pipeline-template/.github/workflows/branch.yml b/nf_core/pipeline-template/.github/workflows/branch.yml index 7677c6f9e5..cbbc75e096 100644 --- a/nf_core/pipeline-template/.github/workflows/branch.yml +++ b/nf_core/pipeline-template/.github/workflows/branch.yml @@ -2,11 +2,13 @@ name: nf-core branch protection # This workflow is triggered on PRs to `main`/`master` branch on the repository # It fails when someone tries to make a PR against the nf-core `main`/`master` branch instead of `dev` on: - pull_request_target: + pull_request: branches: - main - master +permissions: {} + jobs: test: runs-on: ubuntu-latest @@ -14,33 +16,47 @@ jobs: # PRs to the nf-core repo main/master branch are only ok if coming from the nf-core repo `dev` or any `patch` branches - name: Check PRs if: github.repository == '{{ name }}' + env: + HEAD_REPO: {% raw %}${{ github.event.pull_request.head.repo.full_name }}{% endraw %} run: | - { [[ {% raw %}${{github.event.pull_request.head.repo.full_name }}{% endraw %} == {{ name }} ]] && [[ $GITHUB_HEAD_REF == "dev" ]]; } || [[ $GITHUB_HEAD_REF == "patch" ]] + { [[ "$HEAD_REPO" == {{ name }} ]] && [[ $GITHUB_HEAD_REF == "dev" ]]; } || [[ $GITHUB_HEAD_REF == "patch" ]] - # If the above check failed, post a comment on the PR explaining the failure {%- raw %} - # NOTE - this doesn't currently work if the PR is coming from a fork, due to limitations in GitHub actions secrets - - name: Post PR comment + # If the above check failed, build a comment to be posted by the shared poster workflow + - name: Build PR comment if: failure() - uses: mshick/add-pr-comment@ec328af66588ab8f77cdeb2c264f14aba45bbf59 # v3 - with: - message: | - ## This PR is against the `${{github.event.pull_request.base.ref}}` branch :x: + env:{% raw %} + PR_NUMBER: ${{ github.event.pull_request.number }} + BASE_REF: ${{ github.event.pull_request.base.ref }} + HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} + PR_USER: ${{ github.event.pull_request.user.login }}{% endraw %} + run: | + mkdir -p pr-comment + echo "$PR_NUMBER" > pr-comment/pr_number.txt + echo "branch" > pr-comment/header.txt + cat > pr-comment/comment.md < pr-comment/pr_number.txt + echo "lint" > pr-comment/header.txt + [ -f lint_results.md ] && cp lint_results.md pr-comment/comment.md || true + + - name: Upload PR comment artifact + if: ${{ always() }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: pr-comment + path: pr-comment/{%- endraw %} diff --git a/nf_core/pipeline-template/.github/workflows/linting_comment.yml b/nf_core/pipeline-template/.github/workflows/linting_comment.yml deleted file mode 100644 index c2923041b3..0000000000 --- a/nf_core/pipeline-template/.github/workflows/linting_comment.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: nf-core linting comment -# This workflow is triggered after the linting action is complete -# It posts an automated comment to the PR, even if the PR is coming from a fork {%- raw %} - -on: - workflow_run: - workflows: ["nf-core linting"] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - name: Download lint results - uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 - with: - workflow: linting.yml - workflow_conclusion: completed - - - name: Get PR number - id: pr_number - run: echo "pr_number=$(cat linting-logs/PR_number.txt)" >> $GITHUB_OUTPUT - - - name: Post PR comment - uses: marocchino/sticky-pull-request-comment@70d2764d1a7d5d9560b100cbea0077fc8f633987 # v3 - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - number: ${{ steps.pr_number.outputs.pr_number }} - path: linting-logs/lint_results.md {%- endraw %} diff --git a/nf_core/pipeline-template/.github/workflows/pr-comment.yml b/nf_core/pipeline-template/.github/workflows/pr-comment.yml new file mode 100644 index 0000000000..38accbf251 --- /dev/null +++ b/nf_core/pipeline-template/.github/workflows/pr-comment.yml @@ -0,0 +1,68 @@ +name: Post PR comment +# Shared, privileged comment poster. +# +# This is the single workflow that runs with a write token. It is triggered +# after any of the listed "producer" workflows complete on a pull request. +# Each producer runs untrusted PR code (if any) with a read-only token and +# uploads a `pr-comment` artifact describing the comment to post; this workflow +# only ever reads that plain-text artifact, so no PR code is executed here. +# +# Artifact contract (uploaded by producers under the name `pr-comment`): +# pr_number.txt - the pull request number +# header.txt - sticky-comment identifier (keeps comment types separate) +# comment.md - the Markdown body (omit the file to post nothing) + +on: + workflow_run: + workflows: + - "nf-core linting" + - "nf-core template version comment" + - "nf-core branch protection" + +permissions: + actions: read + contents: read + pull-requests: write + +jobs: + post-comment: + runs-on: ubuntu-latest + # Only act on runs that were triggered by a pull request. + if: github.event.workflow_run.event == 'pull_request' + steps: + - name: Download PR comment artifact + uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 + with:{% raw %} + run_id: ${{ github.event.workflow_run.id }} + name: pr-comment + if_no_artifact_found: ignore + + - name: Read comment metadata + id: meta + run: | + # No comment body means there is nothing to post. + [ -f pr-comment/comment.md ] || exit 0 + + pr_number=$(cat pr-comment/pr_number.txt) + header=$(cat pr-comment/header.txt) + + # Guard against anything unexpected ending up in the PR number. + case "$pr_number" in + ''|*[!0-9]*) + echo "Invalid PR number: '$pr_number'" + exit 1 + ;; + esac + + echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT" + echo "header=$header" >> "$GITHUB_OUTPUT" + echo "post=true" >> "$GITHUB_OUTPUT" + + - name: Post PR comment + if: steps.meta.outputs.post == 'true' + uses: marocchino/sticky-pull-request-comment@5770ad5eb8f42dd2c4f34da00c94c5381e49af88 # v3.0.5 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + number: ${{ steps.meta.outputs.pr_number }} + header: ${{ steps.meta.outputs.header }} + path: pr-comment/comment.md{%- endraw %} diff --git a/nf_core/pipeline-template/.github/workflows/release-announcements.yml b/nf_core/pipeline-template/.github/workflows/release-announcements.yml index d1ad2cf01f..e027b6bcc4 100644 --- a/nf_core/pipeline-template/.github/workflows/release-announcements.yml +++ b/nf_core/pipeline-template/.github/workflows/release-announcements.yml @@ -18,7 +18,7 @@ jobs: id: get_description run: | echo "description=$(curl -s https://nf-co.re/pipelines.json | jq -r '.remote_workflows[] | select(.full_name == "${{ github.repository }}") | .description')" >> $GITHUB_OUTPUT - - uses: rzr/fediverse-action@563159eb8d45f70ab6aaba36ed55cd037e51f441 # master + - uses: rzr/fediverse-action@66c2cbb5b1997666b0e28d597631b6a4f09a2719 # v0.0.6 with: access-token: ${{ secrets.MASTODON_ACCESS_TOKEN }} host: "mstdn.science" # custom host if not "mastodon.social" (default) diff --git a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml index d87f339566..e45cde0576 100644 --- a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml +++ b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml @@ -2,10 +2,13 @@ name: nf-core template version comment # This workflow is triggered on PRs to check if the pipeline template version matches the latest nf-core version. # It posts a comment to the PR, even if it comes from a fork.{%- raw %} -on: pull_request_target +on: + pull_request: + +permissions: {} jobs: - template_version: + check_template_version: runs-on: ubuntu-latest steps: - name: Check out pipeline code @@ -22,25 +25,36 @@ jobs: - name: Install nf-core run: | python -m pip install --upgrade pip - pip install nf-core==${{ steps.read_yml.outputs['nf_core_version'] }} + pip install nf-core + + - name: Build PR comment if template is outdated + # The fork-controlled version is passed via the environment and only ever + # used as quoted shell data (never interpolated into a command), so it + # cannot be used for script injection. + env: + PR_VERSION: ${{ steps.read_yml.outputs['nf_core_version'] }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + mkdir -p pr-comment + echo "$PR_NUMBER" > pr-comment/pr_number.txt + echo "template-version" > pr-comment/header.txt + + latest_version=$(nf-core --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1) - - name: Check nf-core outdated - id: nf_core_outdated - run: echo "OUTPUT=$(pip list --outdated | grep nf-core)" >> ${GITHUB_ENV} + if [ -n "$PR_VERSION" ] && [ -n "$latest_version" ] && [ "$PR_VERSION" != "$latest_version" ]; then + cat > pr-comment/comment.md < [!WARNING] + > Newer version of the nf-core template is available. + > + > Your pipeline is using an old version of the nf-core template: ${PR_VERSION}. + > Please update your pipeline to the latest version. + > + > For more documentation on how to update your pipeline, please see the [Synchronisation documentation](https://nf-co.re/docs/developing/template-syncs/overview). + EOF + fi{% endraw %} - - name: Post nf-core template version comment - uses: mshick/add-pr-comment@ec328af66588ab8f77cdeb2c264f14aba45bbf59 # v3 - if: | - contains(env.OUTPUT, 'nf-core') + - name: Upload PR comment artifact + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: - repo-token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} - allow-repeats: false - message: | - > [!WARNING] - > Newer version of the nf-core template is available. - > - > Your pipeline is using an old version of the nf-core template: ${{ steps.read_yml.outputs['nf_core_version'] }}. - > Please update your pipeline to the latest version. - > - > For more documentation on how to update your pipeline, please see the [Synchronisation documentation](https://nf-co.re/docs/developing/template-syncs/overview). - #{%- endraw %} + name: pr-comment + path: pr-comment/ diff --git a/nf_core/pipelines/create/template_features.yml b/nf_core/pipelines/create/template_features.yml index d5678f65b1..eedd517933 100644 --- a/nf_core/pipelines/create/template_features.yml +++ b/nf_core/pipelines/create/template_features.yml @@ -29,7 +29,7 @@ repository_setup: - ".github/ISSUE_TEMPLATE/feature_request.yml" - ".github/PULL_REQUEST_TEMPLATE.md" - ".github/workflows/branch.yml" - - ".github/workflows/linting_comment.yml" + - ".github/workflows/pr-comment.yml" - ".github/workflows/linting.yml" - ".github/.dockstore.yml" readme: @@ -117,7 +117,7 @@ continuous_integration_testing: - ".github/workflows/nf-test.yml" - ".github/actions/get-shards/action.yml" - ".github/actions/nf-test/action.yml" - - ".github/workflows/linting_comment.yml" + - ".github/workflows/pr-comment.yml" - ".github/workflows/linting.yml" nfcore_pipelines: False custom_pipelines: True diff --git a/nf_core/pipelines/lint/files_exist.py b/nf_core/pipelines/lint/files_exist.py index 9fb55ccedb..8e3c6f567e 100644 --- a/nf_core/pipelines/lint/files_exist.py +++ b/nf_core/pipelines/lint/files_exist.py @@ -34,7 +34,7 @@ def files_exist(self) -> dict[str, list[str]]: .github/workflows/nf-test.yml .github/actions/get-shards/action.yml .github/actions/nf-test/action.yml - .github/workflows/linting_comment.yml + .github/workflows/pr-comment.yml .github/workflows/linting.yml [LICENSE, LICENSE.md, LICENCE, LICENCE.md] # NB: British / American spelling assets/email_template.html @@ -149,7 +149,7 @@ def files_exist(self) -> dict[str, list[str]]: [Path(".github", "workflows", "nf-test.yml")], [Path(".github", "actions", "get-shards", "action.yml")], [Path(".github", "actions", "nf-test", "action.yml")], - [Path(".github", "workflows", "linting_comment.yml")], + [Path(".github", "workflows", "pr-comment.yml")], [Path(".github", "workflows", "linting.yml")], [Path("assets", "email_template.html")], [Path("assets", "email_template.txt")], diff --git a/nf_core/pipelines/lint/files_unchanged.py b/nf_core/pipelines/lint/files_unchanged.py index 20cef65ae5..3d5f87c266 100644 --- a/nf_core/pipelines/lint/files_unchanged.py +++ b/nf_core/pipelines/lint/files_unchanged.py @@ -28,7 +28,7 @@ def files_unchanged(self) -> dict[str, list[str] | bool]: .github/ISSUE_TEMPLATE/feature_request.yml .github/PULL_REQUEST_TEMPLATE.md .github/workflows/branch.yml - .github/workflows/linting_comment.yml + .github/workflows/pr-comment.yml .github/workflows/linting.yml assets/email_template.html assets/email_template.txt @@ -92,7 +92,7 @@ def files_unchanged(self) -> dict[str, list[str] | bool]: [Path(".github", "ISSUE_TEMPLATE", "feature_request.yml")], [Path(".github", "PULL_REQUEST_TEMPLATE.md")], [Path(".github", "workflows", "branch.yml")], - [Path(".github", "workflows", "linting_comment.yml")], + [Path(".github", "workflows", "pr-comment.yml")], [Path(".github", "workflows", "linting.yml")], [Path("assets", "email_template.html")], [Path("assets", "email_template.txt")], From b559ed46f837bf740d270fe56a4f6202c256f206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Fri, 17 Jul 2026 12:53:35 +0200 Subject: [PATCH 109/135] make CLI startup faster (#4383) --- .pre-commit-config.yaml | 6 + CHANGELOG.md | 12 +- nf_core/__main__.py | 206 +++--- nf_core/commands_pipelines.py | 3 +- nf_core/commands_test_datasets.py | 8 +- nf_core/components/components_completion.py | 10 +- nf_core/components/components_differ.py | 20 +- nf_core/github_api.py | 189 ++++++ nf_core/pipelines/__init__.py | 10 +- nf_core/pipelines/download/download.py | 2 +- nf_core/pipelines/download/singularity.py | 20 +- nf_core/pipelines/launch.py | 26 +- nf_core/pipelines/lint_utils.py | 5 +- nf_core/pipelines/list.py | 8 +- nf_core/pipelines/sync.py | 3 +- nf_core/pydantic_models.py | 211 ++++++ nf_core/subworkflows/__init__.py | 24 +- nf_core/synced_repo.py | 31 +- nf_core/utils.py | 673 ++++++-------------- nf_core/version_updater.py | 38 ++ tests/pipelines/test_launch.py | 2 +- tests/subworkflows/test_patch.py | 4 +- tests/test_version_updater.py | 63 ++ 23 files changed, 952 insertions(+), 622 deletions(-) create mode 100644 nf_core/github_api.py create mode 100644 nf_core/pydantic_models.py create mode 100644 nf_core/version_updater.py create mode 100644 tests/test_version_updater.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8cf05e0725..cf88e0d39d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,6 +4,7 @@ repos: hooks: - id: ruff-check # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix + priority: 10 - id: ruff-format # formatter - repo: https://github.com/pre-commit/mirrors-prettier rev: "v3.1.0" @@ -17,6 +18,7 @@ repos: hooks: - id: trailing-whitespace args: [--markdown-linebreak-ext=md] + priority: 10 exclude: | (?x)^( .*\.snap$| @@ -25,6 +27,7 @@ repos: tests/pipelines/__snapshots__/.* )$ - id: end-of-file-fixer + priority: 10 exclude: | (?x)^( .*\.snap$| @@ -37,6 +40,7 @@ repos: hooks: - id: mypy args: [--ignore-missing-imports, --scripts-are-modules, -n4] + priority: 20 additional_dependencies: - types-PyYAML - types-requests @@ -48,10 +52,12 @@ repos: rev: 0.11.19 hooks: - id: uv-lock + priority: 20 - repo: local hooks: - id: lint-test-docstrings name: Check lint test names are documented in docstrings language: system entry: python3 docs/api/check_lint_docstrings.py + priority: 20 files: ^nf_core/(modules|subworkflows)/lint/.*\.py$ diff --git a/CHANGELOG.md b/CHANGELOG.md index 622987cc5a..33399c7b72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,11 @@ ### General -- Update pre-commit hook pre-commit/mirrors-mypy to v2 ([#4270](https://github.com/nf-core/tools/pull/4270)) - container configs: use correct key for conda configs ([#4269](https://github.com/nf-core/tools/pull/4269)) - Coerce launch params_out to Path to fix AttributeError (#4299) ([#4317](https://github.com/nf-core/tools/pull/4317)) - generate valid Markdown when piping schema docs to file ([#4319](https://github.com/nf-core/tools/pull/4319)) - fix API docs bug in pydantic autodoc ([#4320](https://github.com/nf-core/tools/pull/4320)) -- Update pre-commit npm dependencies to v3.8.4 ([#4335](https://github.com/nf-core/tools/pull/4335)) +- Improve CLI startup speed ([#4383](https://github.com/nf-core/tools/pull/4383)) ### Linting @@ -21,12 +20,10 @@ ### Modules - `modules info`: handle one element channels correctly ([#4268](https://github.com/nf-core/tools/pull/4268)) -- feat: module lint for module name granularity ([#4325](https://github.com/nf-core/tools/pull/4325)) +- `module` lint for module name matching against nf-core module naming specifications ([#4325](https://github.com/nf-core/tools/pull/4325)) - Clarify execution context of nf-core modules test command ([#4346](https://github.com/nf-core/tools/pull/4346)) - Add `nf-core modules containers create` to build module containers via Seqera Wave and record them in the `containers:` section of `meta.yml` ([#3954](https://github.com/nf-core/tools/pull/3954)) -- Container linting now validates the `containers:` section of `meta.yml` (Wave modules). The legacy `main.nf` container checks (URL reachability, registry prefix, docker/singularity tag match) have been removed; modules still using the old container syntax get a `deprecated_container_syntax` warning instead ([#3954](https://github.com/nf-core/tools/pull/3954)) - -### Subworkflows +- Add a log hint in `modules create` for `create containers` and switch `modules bump-versions` to use Seqera containers ([#4374](https://github.com/nf-core/tools/pull/4374)) ### Template @@ -45,6 +42,9 @@ #### Version updates +- Update pre-commit hook pre-commit/mirrors-mypy to v2 ([#4270](https://github.com/nf-core/tools/pull/4270)) +- Update pre-commit npm dependencies to v3.8.4 ([#4335](https://github.com/nf-core/tools/pull/4335)) + ## [v4.0.2 - Bold Boa Patch 2](https://github.com/nf-core/tools/releases/tag/4.0.2) - [2026-04-30] ### General diff --git a/nf_core/__main__.py b/nf_core/__main__.py index e05bfa0b43..bdf60b8cda 100644 --- a/nf_core/__main__.py +++ b/nf_core/__main__.py @@ -6,96 +6,55 @@ import sys from pathlib import Path -import requests -import rich.console -import rich.logging -import rich.panel -import rich.traceback import rich_click as click import rich_click.rich_click as rc -from trogon import tui from nf_core import __version__ -from nf_core.commands_modules import ( - modules_bump_versions, - modules_containers_conda_lock, - modules_containers_create, - modules_containers_list, - modules_create, - modules_info, - modules_install, - modules_lint, - modules_list_local, - modules_list_remote, - modules_patch, - modules_remove, - modules_test, - modules_update, -) -from nf_core.commands_pipelines import ( - pipelines_bump_version, - pipelines_create, - pipelines_create_logo, - pipelines_create_params_file, - pipelines_download, - pipelines_launch, - pipelines_lint, - pipelines_list, - pipelines_rocrate, - pipelines_schema_build, - pipelines_schema_docs, - pipelines_schema_lint, - pipelines_schema_validate, - pipelines_sync, -) -from nf_core.commands_subworkflows import ( - subworkflows_create, - subworkflows_info, - subworkflows_install, - subworkflows_lint, - subworkflows_list_local, - subworkflows_list_remote, - subworkflows_remove, - subworkflows_test, - subworkflows_update, -) -from nf_core.commands_test_datasets import test_datasets_list_branches, test_datasets_list_remote, test_datasets_search -from nf_core.components.components_completion import autocomplete_modules, autocomplete_subworkflows from nf_core.components.constants import NF_CORE_MODULES_REMOTE -from nf_core.pipelines.download.download import DownloadError -from nf_core.pipelines.list import autocomplete_pipelines -from nf_core.utils import check_if_outdated, nfcore_logo, rich_force_colors, setup_nfcore_dir +from nf_core.utils import check_if_outdated, nfcore_logo, stderr + + +def autocomplete_pipelines(ctx, param, incomplete): + from nf_core.pipelines.list import autocomplete_pipelines as complete + + return complete(ctx, param, incomplete) + + +def autocomplete_modules(ctx, param, incomplete): + from nf_core.components.components_completion import autocomplete_modules as complete + + return complete(ctx, param, incomplete) + + +def autocomplete_subworkflows(ctx, param, incomplete): + from nf_core.components.components_completion import autocomplete_subworkflows as complete + + return complete(ctx, param, incomplete) + # Set up logging as the root logger # Submodules should all traverse back to this log = logging.getLogger() -# Set up .nfcore directory for storing files between sessions -setup_nfcore_dir() - # Set up nicer formatting of click cli help messages rc.MAX_WIDTH = 100 rc.USE_RICH_MARKUP = True rc.COMMANDS_BEFORE_OPTIONS = True -# Set up rich stderr console -stderr = rich.console.Console(stderr=True, force_terminal=rich_force_colors()) -stdout = rich.console.Console(force_terminal=rich_force_colors()) - -# Set up the rich traceback -rich.traceback.install(console=stderr, width=200, word_wrap=True, extra_lines=1) - - # Define exceptions for which no traceback should be printed, # because they are actually preliminary, but intended program terminations. # (Custom exceptions are cleaner than `sys.exit(1)`, which we used before) def selective_traceback_hook(exctype, value, traceback): + from nf_core.pipelines.download.download import DownloadError + if exctype in {DownloadError, UserWarning, ValueError}: # extend set as needed log.error(value) else: + from rich.traceback import Traceback + # print the colored traceback for all other exceptions with rich as usual - stderr.print(rich.traceback.Traceback.from_exception(exctype, value, traceback)) + stderr.print(Traceback.from_exception(exctype, value, traceback, width=200, extra_lines=1)) sys.excepthook = selective_traceback_hook @@ -120,21 +79,17 @@ def run_nf_core(): f"\n[grey39] nf-core/tools version {__version__} - [link=https://nf-co.re]https://nf-co.re[/]", highlight=False, ) - try: - is_outdated, _, remote_vers = check_if_outdated() - if is_outdated: - stderr.print( - f"[bold bright_yellow] There is a new version of nf-core/tools available! ({remote_vers})", - highlight=False, - ) - except requests.exceptions.RequestException as e: - log.debug(f"Could not check latest version: {e}") + is_outdated, _, remote_vers = check_if_outdated() + if is_outdated: + stderr.print( + f"[bold bright_yellow] There is a new version of nf-core/tools available! ({remote_vers})", + highlight=False, + ) stderr.print("\n") # Launch the click cli nf_core_cli(auto_envvar_prefix="NFCORE") -@tui(command="interface", help="Launch the nf-core interface") @click.group(context_settings={"help_option_names": ["-h", "--help"]}) @click.version_option(__version__) @click.option( @@ -164,10 +119,12 @@ def nf_core_cli(ctx, verbose, hide_progress, log_file): # Set up logs to the console - use the shared console so log output # coordinates with progress spinners (avoids output on the same line) - from nf_core.pipelines.lint_utils import console as shared_console + from rich.logging import RichHandler + + from nf_core.utils import stdout as shared_console log.addHandler( - rich.logging.RichHandler( + RichHandler( level=logging.DEBUG if verbose else logging.INFO, console=shared_console, show_time=False, @@ -197,6 +154,15 @@ def nf_core_cli(ctx, verbose, hide_progress, log_file): } +# nf-core interface (registered by hand so trogon is only imported when run) +@nf_core_cli.command("interface", help="Launch the nf-core interface") +@click.pass_context +def interface(ctx): + from trogon import Trogon + + Trogon(nf_core_cli, app_name=None, command_name="interface", click_context=ctx).run() + + # nf-core pipelines subcommands @nf_core_cli.group(aliases=["p", "pipeline"]) @click.command_panel("For users", commands=["download", "create-params-file", "launch", "list"]) @@ -238,6 +204,8 @@ def command_pipelines_create(ctx, name, description, author, version, force, out """ Create a new pipeline using the nf-core template. """ + from nf_core.commands_pipelines import pipelines_create + pipelines_create(ctx, name, description, author, version, force, outdir, template_yaml, organisation) @@ -321,6 +289,8 @@ def command_pipelines_lint( """ Check pipeline code against nf-core guidelines. """ + from nf_core.commands_pipelines import pipelines_lint + pipelines_lint( ctx, directory, release, fix, key, show_passed, fail_ignored, fail_warned, markdown, json, sort_by, plain_text ) @@ -420,6 +390,8 @@ def command_pipelines_download( """ Download a pipeline, nf-core/configs and pipeline singularity images. """ + from nf_core.commands_pipelines import pipelines_download + pipelines_download( ctx, pipeline, @@ -469,6 +441,8 @@ def command_pipelines_create_params_file(ctx, pipeline, revision, output, force, """ Build a parameter file for a pipeline. """ + from nf_core.commands_pipelines import pipelines_create_params_file + pipelines_create_params_file(ctx, pipeline, revision, output, force, show_hidden, no_prompts) @@ -541,6 +515,8 @@ def command_pipelines_launch( """ Launch a pipeline using a web GUI or command line prompts. """ + from nf_core.commands_pipelines import pipelines_launch + pipelines_launch( ctx, pipeline, launch_id, revision, command_only, params_in, params_out, save_all, show_hidden, url, no_prompts ) @@ -563,6 +539,8 @@ def command_pipelines_list(ctx, keywords, sort, json, show_archived): """ List available nf-core pipelines with local info. """ + from nf_core.commands_pipelines import pipelines_list + pipelines_list(ctx, keywords, sort, json, show_archived) @@ -601,6 +579,8 @@ def rocrate( """ Make an Research Object Crate """ + from nf_core.commands_pipelines import pipelines_rocrate + pipelines_rocrate(ctx, pipeline_dir, json_path, zip_path, pipeline_version) @@ -654,6 +634,8 @@ def command_pipelines_sync( """ Sync a pipeline [cyan i]TEMPLATE[/] branch with the nf-core template. """ + from nf_core.commands_pipelines import pipelines_sync + pipelines_sync( ctx, directory, @@ -691,6 +673,8 @@ def command_pipelines_bump_version(ctx, new_version, directory, nextflow): """ Update nf-core pipeline version number with `nf-core pipelines bump-version`. """ + from nf_core.commands_pipelines import pipelines_bump_version + pipelines_bump_version(ctx, new_version, directory, nextflow) @@ -737,6 +721,8 @@ def command_pipelines_create_logo(logo_text, directory, name, theme, width, img_ """ Generate a logo with the nf-core logo template. """ + from nf_core.commands_pipelines import pipelines_create_logo + pipelines_create_logo(logo_text, directory, name, theme, width, img_format, force) @@ -777,6 +763,8 @@ def command_pipelines_schema_validate(directory, pipeline, params): # this is a local pipeline pipeline = Path(directory, pipeline) + from nf_core.commands_pipelines import pipelines_schema_validate + pipelines_schema_validate(pipeline, params) @@ -810,6 +798,8 @@ def command_pipelines_schema_build(directory, no_prompts, web_only, url): """ Interactively build a pipeline schema from Nextflow params. """ + from nf_core.commands_pipelines import pipelines_schema_build + pipelines_schema_build(directory, no_prompts, web_only, url) @@ -833,6 +823,8 @@ def command_pipelines_schema_lint(directory, schema_file): """ Check that a given pipeline schema is valid. """ + from nf_core.commands_pipelines import pipelines_schema_lint + pipelines_schema_lint(Path(directory, schema_file)) @@ -881,6 +873,8 @@ def command_pipelines_schema_docs(directory, schema_file, output, output_format, """ Outputs parameter documentation for a pipeline schema. """ + from nf_core.commands_pipelines import pipelines_schema_docs + pipelines_schema_docs(Path(directory, schema_file), output, output_format, force, columns) @@ -943,6 +937,8 @@ def command_modules_list_remote(ctx, keywords, json): """ List modules in a remote GitHub repo [dim i](e.g [link=https://github.com/nf-core/modules]nf-core/modules[/])[/]. """ + from nf_core.commands_modules import modules_list_remote + modules_list_remote(ctx, keywords, json) @@ -963,6 +959,8 @@ def command_modules_list_local(ctx, keywords, json, directory): # pylint: disab """ List modules installed locally in a pipeline """ + from nf_core.commands_modules import modules_list_local + modules_list_local(ctx, keywords, json, directory) @@ -1004,6 +1002,8 @@ def command_modules_install(ctx, tool, directory, prompt, force, sha): """ Install DSL2 modules within a pipeline. """ + from nf_core.commands_modules import modules_install + modules_install(ctx, tool, directory, prompt, force, sha) @@ -1095,6 +1095,8 @@ def command_modules_update( """ Update DSL2 modules within a pipeline. """ + from nf_core.commands_modules import modules_update + modules_update( ctx, tool, directory, force, prompt, sha, install_all, preview, save_diff, update_deps, limit_output, skip_deps ) @@ -1124,6 +1126,8 @@ def command_modules_patch(ctx, tool, directory, remove): """ Create a patch file for minor changes in a module """ + from nf_core.commands_modules import modules_patch + modules_patch(ctx, tool, directory, remove) @@ -1157,6 +1161,8 @@ def command_modules_remove(ctx, directory, tool, force): """ Remove a module from a pipeline. """ + from nf_core.commands_modules import modules_remove + modules_remove(ctx, directory, tool, force) @@ -1237,6 +1243,8 @@ def command_modules_create( """ Create a new DSL2 module from the nf-core template. """ + from nf_core.commands_modules import modules_create + modules_create( ctx, tool, @@ -1305,6 +1313,8 @@ def command_modules_test(ctx, tool, directory, no_prompts, update, once, profile """ if verbose: ctx.obj["verbose"] = verbose + from nf_core.commands_modules import modules_test + modules_test(ctx, tool, directory, no_prompts, update, once, profile) @@ -1372,6 +1382,8 @@ def command_modules_lint( """ Lint one or more modules in a directory. """ + from nf_core.commands_modules import modules_lint + modules_lint( ctx, tool, @@ -1412,6 +1424,8 @@ def command_modules_info(ctx, tool, directory): """ Show developer usage information about a given module. """ + from nf_core.commands_modules import modules_info + modules_info(ctx, tool, directory) @@ -1442,6 +1456,8 @@ def command_modules_bump_versions(ctx, tool, directory, all_modules, show_all, d Bump versions for one or more modules in a clone of the nf-core/modules repo. """ + from nf_core.commands_modules import modules_bump_versions + modules_bump_versions(ctx, tool, directory, all_modules, show_all, dry_run) @@ -1449,8 +1465,10 @@ def command_modules_bump_versions(ctx, tool, directory, all_modules, show_all, d @click.pass_context def modules_containers(ctx): """Manage module container builds and metadata [yellow](beta)[/].""" + from rich.panel import Panel + stderr.print( - rich.panel.Panel( + Panel( "The [bold]nf-core modules containers[/] commands are still in beta.\n" "Their behaviour and output may change in future releases.\n" "Best to always use the latest dev version.", @@ -1492,6 +1510,8 @@ def command_modules_containers_create(ctx, module: str, directory: Path, force: """ Build docker and singularity container files for linux/arm64 and linux/amd64 with wave from environment.yml and create container config file. """ + from nf_core.commands_modules import modules_containers_create + modules_containers_create(ctx, module, directory, force) @@ -1509,6 +1529,8 @@ def command_modules_containers_conda_lock(ctx, module: str) -> None: """ Build a Docker linux/arm64 container and fetch the conda lock file for a module. """ + from nf_core.commands_modules import modules_containers_conda_lock + modules_containers_conda_lock(ctx, module) @@ -1534,6 +1556,8 @@ def command_modules_containers_list(ctx, module, plain_text): """ Print containers defined in a module meta.yml. """ + from nf_core.commands_modules import modules_containers_list + modules_containers_list(ctx, module, plain_text) @@ -1600,6 +1624,8 @@ def command_subworkflows_create(ctx, subworkflow, directory, author, force): """ Create a new subworkflow from the nf-core template. """ + from nf_core.commands_subworkflows import subworkflows_create + subworkflows_create(ctx, subworkflow, directory, author, force) @@ -1647,6 +1673,8 @@ def command_subworkflows_test(ctx, subworkflow, directory, no_prompts, update, o """ Run nf-test for a subworkflow. """ + from nf_core.commands_subworkflows import subworkflows_test + subworkflows_test(ctx, subworkflow, directory, no_prompts, update, once, profile) @@ -1669,6 +1697,8 @@ def command_subworkflows_list_remote(ctx, keywords, json): """ List subworkflows in a remote GitHub repo [dim i](e.g [link=https://github.com/nf-core/modules]nf-core/modules[/])[/]. """ + from nf_core.commands_subworkflows import subworkflows_list_remote + subworkflows_list_remote(ctx, keywords, json) @@ -1689,6 +1719,8 @@ def command_subworkflows_list_local(ctx, keywords, json, directory): # pylint: """ List subworkflows installed locally in a pipeline """ + from nf_core.commands_subworkflows import subworkflows_list_local + subworkflows_list_local(ctx, keywords, json, directory) @@ -1751,6 +1783,8 @@ def command_subworkflows_lint( """ Lint one or more subworkflows in a directory. """ + from nf_core.commands_subworkflows import subworkflows_lint + subworkflows_lint( ctx, subworkflow, @@ -1790,6 +1824,8 @@ def command_subworkflows_info(ctx, subworkflow, directory): """ Show developer usage information about a given subworkflow. """ + from nf_core.commands_subworkflows import subworkflows_info + subworkflows_info(ctx, subworkflow, directory) @@ -1843,6 +1879,8 @@ def command_subworkflows_install(ctx, subworkflow, directory, prompt, force, sha """ Install DSL2 subworkflow within a pipeline. """ + from nf_core.commands_subworkflows import subworkflows_install + subworkflows_install(ctx, subworkflow, directory, prompt, force, sha, skip_deps) @@ -1921,6 +1959,8 @@ def command_subworkflows_remove(ctx, directory, subworkflow, force): """ Remove a subworkflow from a pipeline. """ + from nf_core.commands_subworkflows import subworkflows_remove + subworkflows_remove(ctx, directory, subworkflow, force) @@ -2019,6 +2059,8 @@ def command_subworkflows_update( """ Update DSL2 subworkflow within a pipeline. """ + from nf_core.commands_subworkflows import subworkflows_update + subworkflows_update( ctx, subworkflow, @@ -2071,6 +2113,8 @@ def command_test_dataset_search(ctx, branch, generate_nf_path, generate_dl_url, Search files filtered by QUERY on a specified branch in the nf-core/test-datasets repository. If no QUERY is given or QUERY is ambiguous, an auto-completion form is shown. """ + from nf_core.commands_test_datasets import test_datasets_search + test_datasets_search(ctx, branch, generate_nf_path, generate_dl_url, query) @@ -2096,6 +2140,8 @@ def command_test_dataset_list_remote(ctx, branch, generate_nf_path, generate_dl_ """ List files on a specified branch in the nf-core/test-datasets repository. """ + from nf_core.commands_test_datasets import test_datasets_list_remote + test_datasets_list_remote(ctx, branch, generate_nf_path, generate_dl_url) @@ -2106,6 +2152,8 @@ def command_test_datasets_list_branches(ctx): """ List remote branches with test data in the nf-core/test-dataset repository. """ + from nf_core.commands_test_datasets import test_datasets_list_branches + test_datasets_list_branches(ctx) diff --git a/nf_core/commands_pipelines.py b/nf_core/commands_pipelines.py index 535ed074ca..1384540f6d 100644 --- a/nf_core/commands_pipelines.py +++ b/nf_core/commands_pipelines.py @@ -5,7 +5,6 @@ import rich import nf_core.utils -from nf_core.pipelines.params_file import ParamsFileBuilder from nf_core.utils import rich_force_colors log = logging.getLogger(__name__) @@ -226,6 +225,8 @@ def pipelines_create_params_file(ctx, pipeline, revision, output, force, show_hi Run using a remote pipeline name (such as GitHub `user/repo` or a URL), a local pipeline directory. """ + from nf_core.pipelines.params_file import ParamsFileBuilder + builder = ParamsFileBuilder(pipeline, revision, no_prompts) if not builder.write_params_file(Path(output), show_hidden=show_hidden, force=force): diff --git a/nf_core/commands_test_datasets.py b/nf_core/commands_test_datasets.py index b9a2688cd3..a6b94ae7d1 100644 --- a/nf_core/commands_test_datasets.py +++ b/nf_core/commands_test_datasets.py @@ -3,8 +3,6 @@ import click import rich -from nf_core.test_datasets.list import list_dataset_branches, list_datasets -from nf_core.test_datasets.search import search_datasets from nf_core.utils import rich_force_colors log = logging.getLogger(__name__) @@ -17,6 +15,8 @@ def test_datasets_list_branches(ctx: click.Context) -> None: Only lists test data and module test data based on the curated list of pipeline names [on the website](https://raw.githubusercontent.com/nf-core/website/refs/heads/main/public/pipeline_names.json). """ + from nf_core.test_datasets.list import list_dataset_branches + list_dataset_branches() @@ -25,6 +25,8 @@ def test_datasets_list_remote(ctx: click.Context, branch: str, generate_nf_path: List all files on a given branch in the remote nf-core/testdatasets repository on github. The resulting files can be parsed as a nextflow path or a url for downloading. """ + from nf_core.test_datasets.list import list_datasets + list_datasets(branch, generate_nf_path, generate_dl_url) @@ -37,4 +39,6 @@ def test_datasets_search( Specifying a branch is required. The resulting file can optionally be parsed as a nextflow path or a url for downloading """ + from nf_core.test_datasets.search import search_datasets + search_datasets(branch, generate_nf_path=generate_nf_path, generate_dl_url=generate_dl_url, query=query) diff --git a/nf_core/components/components_completion.py b/nf_core/components/components_completion.py index 8abecb4649..4f2179c837 100644 --- a/nf_core/components/components_completion.py +++ b/nf_core/components/components_completion.py @@ -1,13 +1,11 @@ import sys -import git from click.shell_completion import CompletionItem -from nf_core.modules.list import ModuleList -from nf_core.subworkflows.list import SubworkflowList - def autocomplete_components(ctx, param, incomplete: str, component_type: str, list_class): + import git + # Defaults modules_repo_url = "https://github.com/nf-core/modules" modules_repo_branch = "master" @@ -31,8 +29,12 @@ def autocomplete_components(ctx, param, incomplete: str, component_type: str, li def autocomplete_modules(ctx, param, incomplete: str): + from nf_core.modules.list import ModuleList + return autocomplete_components(ctx, param, incomplete, "modules", ModuleList) def autocomplete_subworkflows(ctx, param, incomplete: str): + from nf_core.subworkflows.list import SubworkflowList + return autocomplete_components(ctx, param, incomplete, "subworkflows", SubworkflowList) diff --git a/nf_core/components/components_differ.py b/nf_core/components/components_differ.py index b028b55626..5024478d48 100644 --- a/nf_core/components/components_differ.py +++ b/nf_core/components/components_differ.py @@ -235,16 +235,16 @@ def append_modules_json_diff(diff_path, old_modules_json, new_modules_json, modu @staticmethod def print_diff( - component, - repo_path, - from_dir, - to_dir, - current_version=None, - new_version=None, - dsp_from_dir=None, - dsp_to_dir=None, - limit_output=False, - ): + component: str, + repo_path: str, + from_dir: str | Path, + to_dir: str | Path, + current_version: str | None = None, + new_version: str | None = None, + dsp_from_dir: str | Path | None = None, + dsp_to_dir: str | Path | None = None, + limit_output: bool = False, + ) -> None: """ Prints the diffs between two component versions to the terminal diff --git a/nf_core/github_api.py b/nf_core/github_api.py new file mode 100644 index 0000000000..2228c7d33f --- /dev/null +++ b/nf_core/github_api.py @@ -0,0 +1,189 @@ +"""GitHub API session handling for the nf-core python package. + +Kept separate from nf_core.utils so that requests_cache is only +imported when the GitHub API is actually used. +""" + +import json +import logging +import os +import random +import re +import sys +import time +from pathlib import Path + +import requests.auth +import requests_cache +import rich.console +import rich.markup +import yaml + +from nf_core.utils import rich_force_colors, setup_requests_cachedir + +log = logging.getLogger(__name__) + + +class GitHubAPISession(requests_cache.CachedSession): + """ + Class to provide a single session for interacting with the GitHub API for a run. + Inherits the requests_cache.CachedSession and adds additional functionality, + such as automatically setting up GitHub authentication if we can. + """ + + def __init__(self) -> None: + self.auth_mode: str | None = None + self.return_ok: list[int] = [200, 201] + self.return_retry: list[int] = [403] + self.return_unauthorised: list[int] = [401] + self.has_init: bool = False + + def lazy_init(self) -> None: + """ + Initialise the object. + + Only do this when it's actually being used (due to global import) + """ + log.debug("Initialising GitHub API requests session") + cache_config = setup_requests_cachedir() + super().__init__(**cache_config) + self.setup_github_auth() + self.has_init = True + + def setup_github_auth(self, auth=None): + """ + Try to automatically set up GitHub authentication + """ + if auth is not None: + self.auth = auth + self.auth_mode = "supplied to function" + + # Class for Bearer token authentication + # https://stackoverflow.com/a/58055668/713980 + class BearerAuth(requests.auth.AuthBase): + def __init__(self, token): + self.token = token + + def __call__(self, r): + r.headers["authorization"] = f"Bearer {self.token}" + return r + + # Default auth if we're running and the gh CLI tool is installed + gh_cli_config_fn = Path.home() / ".config" / "gh" / "hosts.yml" + if self.auth is None and gh_cli_config_fn.exists(): + try: + with open(gh_cli_config_fn) as fh: + gh_cli_config = yaml.safe_load(fh) + self.auth = requests.auth.HTTPBasicAuth( + gh_cli_config["github.com"]["user"], + gh_cli_config["github.com"]["oauth_token"], + ) + self.auth_mode = f"gh CLI config: {gh_cli_config['github.com']['user']}" + except (OSError, KeyError, yaml.YAMLError): + ex_type, ex_value, _ = sys.exc_info() + if ex_type is not None: + output = rich.markup.escape(f"{ex_type.__name__}: {ex_value}") + log.debug(f"Couldn't auto-auth with GitHub CLI auth from '{gh_cli_config_fn}': [red]{output}") + + # Default auth if we have a GitHub Token (eg. GitHub Actions CI) + if os.environ.get("GITHUB_TOKEN") is not None and self.auth is None: + self.auth_mode = "Bearer token with GITHUB_TOKEN" + self.auth = BearerAuth(os.environ["GITHUB_TOKEN"]) + else: + log.warning("Could not find GitHub authentication token. Some API requests may fail.") + + log.debug(f"Using GitHub auth: {self.auth_mode}") + + def log_content_headers(self, request, post_data=None): + """ + Try to dump everything to the console, useful when things go wrong. + """ + log.debug(f"Requested URL: {request.url}") + log.debug(f"From requests cache: {request.from_cache}") + log.debug(f"Request status code: {request.status_code}") + log.debug(f"Request reason: {request.reason}") + if post_data is None: + post_data = {} + try: + log.debug(json.dumps(dict(request.headers), indent=4)) + log.debug(json.dumps(request.json(), indent=4)) + log.debug(json.dumps(post_data, indent=4)) + except (json.JSONDecodeError, TypeError) as e: + log.debug(f"Could not parse JSON response from GitHub API! {e}") + log.debug(request.headers) + log.debug(request.content) + log.debug(post_data) + + def safe_get(self, url): + """ + Run a GET request, raise a nice exception with lots of logging if it fails. + """ + if not self.has_init: + self.lazy_init() + request = self.get(url) + if request.status_code in self.return_retry: + stderr = rich.console.Console(stderr=True, force_terminal=rich_force_colors()) + try: + r = self.request_retry(url) + except Exception as e: + stderr.print_exception() + raise e + else: + return r + elif request.status_code in self.return_unauthorised: + raise RuntimeError("GitHub API PR failed, probably due to an expired GITHUB_TOKEN.") + + return request + + def get(self, url, **kwargs): + """ + Initialise the session if we haven't already, then call the superclass get method. + """ + if not self.has_init: + self.lazy_init() + return super().get(url, **kwargs) + + def request_retry(self, url, post_data=None): + """ + Try to fetch a URL, keep retrying if we get a certain return code. + + Used in nf-core pipelines sync code because we get 403 errors: too many simultaneous requests + See https://github.com/nf-core/tools/issues/911 + """ + if not self.has_init: + self.lazy_init() + + # Start the loop for a retry mechanism + while True: + # GET request + if post_data is None: + log.debug(f"Sending GET request to {url}") + r = self.get(url=url) + # POST request + else: + log.debug(f"Sending POST request to {url}") + r = self.post(url=url, json=post_data) + + # Failed but expected - try again + if r.status_code in self.return_retry: + self.log_content_headers(r, post_data) + log.debug(f"GitHub API PR failed - got return code {r.status_code}") + wait_time = float(re.sub("[^0-9]", "", str(r.headers.get("Retry-After", 0)))) + if wait_time == 0: + log.debug("Couldn't find 'Retry-After' header, guessing a length of time to wait") + wait_time = random.randrange(10, 60) + log.warning(f"Got API return code {r.status_code}. Trying again after {wait_time} seconds..") + time.sleep(wait_time) + + # Unexpected error - raise + elif r.status_code not in self.return_ok: + self.log_content_headers(r, post_data) + raise RuntimeError(f"GitHub API PR failed - got return code {r.status_code} from {url}") + + # Success! + else: + return r + + +# Single session object to use for entire codebase. Not sure if there's a better way to do this? +gh_api = GitHubAPISession() diff --git a/nf_core/pipelines/__init__.py b/nf_core/pipelines/__init__.py index bc981c449f..55c151c56f 100644 --- a/nf_core/pipelines/__init__.py +++ b/nf_core/pipelines/__init__.py @@ -1 +1,9 @@ -from .create import PipelineCreateApp +from nf_core.utils import lazy_attrs + +# Lazy imports to keep CLI start-up fast +__getattr__, __dir__ = lazy_attrs( + globals(), + { + "PipelineCreateApp": "nf_core.pipelines.create", + }, +) diff --git a/nf_core/pipelines/download/download.py b/nf_core/pipelines/download/download.py index 5006847d23..ef3b84dfcf 100644 --- a/nf_core/pipelines/download/download.py +++ b/nf_core/pipelines/download/download.py @@ -20,6 +20,7 @@ import nf_core import nf_core.pipelines.list import nf_core.utils +from nf_core.github_api import gh_api from nf_core.pipelines.download.container_fetcher import ContainerFetcher from nf_core.pipelines.download.docker import DockerFetcher from nf_core.pipelines.download.singularity import SINGULARITY_CACHE_DIR_ENV_VAR, SingularityFetcher @@ -29,7 +30,6 @@ NF_INSPECT_MIN_NF_VERSION, NFCORE_VER_LAST_WITHOUT_NF_INSPECT, check_nextflow_version, - gh_api, pretty_nf_version, run_cmd, set_wd_tempdir, diff --git a/nf_core/pipelines/download/singularity.py b/nf_core/pipelines/download/singularity.py index c0ecb5f8f5..98d4b5981a 100644 --- a/nf_core/pipelines/download/singularity.py +++ b/nf_core/pipelines/download/singularity.py @@ -60,6 +60,24 @@ def get_container_library_dir(container_system: str) -> str: raise KeyError(f"Container engine: {container_system} is unknown.") +class SingularityCacheFilePathValidator(questionary.Validator): + """ + Validator for file path specified as --singularity-cache-index argument in nf-core pipelines download + """ + + def validate(self, value): + if len(value.text): + if Path(value.text).is_file(): + return True + else: + raise questionary.ValidationError( + message="Invalid remote cache index file", + cursor_position=len(value.text), + ) + else: + return True + + class SingularityProgress(ContainerProgress): def get_task_types_and_columns(self): task_types_and_columns = super().get_task_types_and_columns() @@ -385,7 +403,7 @@ def prompt_cachedir_remote(cache_dir_env_var: str = SINGULARITY_CACHE_DIR_ENV_VA while cachedir_index is None: prompt_cachedir_index = questionary.path( "Specify a list of the container images that are already present on the remote system:", - validate=nf_core.utils.SingularityCacheFilePathValidator, + validate=SingularityCacheFilePathValidator, style=nf_core.utils.nfcore_question_style, ).unsafe_ask() if prompt_cachedir_index == "": diff --git a/nf_core/pipelines/launch.py b/nf_core/pipelines/launch.py index 7329985c1b..8b4aba1a81 100644 --- a/nf_core/pipelines/launch.py +++ b/nf_core/pipelines/launch.py @@ -26,17 +26,17 @@ class Launch: def __init__( self, - pipeline=None, - revision=None, - command_only=False, - params_in=None, - params_out=None, - save_all=False, - show_hidden=False, - url=None, - web_id=None, - no_prompts=False, - ): + pipeline: str | None = None, + revision: str | None = None, + command_only: bool = False, + params_in: str | Path | None = None, + params_out: str | Path | None = None, + save_all: bool = False, + show_hidden: bool = False, + url: str | None = None, + web_id: str | None = None, + no_prompts: bool = False, + ) -> None: """Initialise the Launcher class Args: @@ -94,8 +94,8 @@ def __init__( }, } } - self.nxf_flags = {} - self.params_user = {} + self.nxf_flags: dict[str, str | bool] = {} + self.params_user: dict[str, str] = {} self.cli_launch = True def launch_pipeline(self): diff --git a/nf_core/pipelines/lint_utils.py b/nf_core/pipelines/lint_utils.py index d2dc56f67a..65aafdb293 100644 --- a/nf_core/pipelines/lint_utils.py +++ b/nf_core/pipelines/lint_utils.py @@ -7,19 +7,16 @@ import git import rich import yaml -from rich.console import Console from rich.table import Table import nf_core.utils from nf_core import __version__ from nf_core.utils import plural_s as _s +from nf_core.utils import stdout as console from nf_core.utils import strip_ansi_codes log = logging.getLogger(__name__) -# Create a console used by all lint tests -console = Console(force_terminal=nf_core.utils.rich_force_colors()) - def print_results_plain_text(results_list, directory=None, component_type=None): """Print lint results in plain text format. diff --git a/nf_core/pipelines/list.py b/nf_core/pipelines/list.py index bc9bf30205..cb5d22d444 100644 --- a/nf_core/pipelines/list.py +++ b/nf_core/pipelines/list.py @@ -8,8 +8,6 @@ from datetime import datetime from pathlib import Path -import git -import requests import rich.table from click.shell_completion import CompletionItem @@ -52,6 +50,8 @@ def _resolve_wf_path(path: Path) -> Path: bare_dir = path / "bare" if clones_dir.is_dir(): if bare_dir.is_dir(): + import git + try: sha = git.Repo(bare_dir).head.commit.hexsha clone = clones_dir / sha @@ -169,6 +169,8 @@ def get_remote_workflows(self): Remote workflows are stored in :attr:`self.remote_workflows` list. """ + import requests + # List all repositories at nf-core log.debug("Fetching list of nf-core workflows") nfcore_url = "https://nf-co.re/pipelines.json" @@ -421,6 +423,8 @@ def get_local_nf_workflow_details(self): # Pull information from the local git repository if self.local_path is not None: + import git + log.debug(f"Pulling git info from {self.local_path}") try: repo = git.Repo(self.local_path) diff --git a/nf_core/pipelines/sync.py b/nf_core/pipelines/sync.py index 003880491d..1cd1a51794 100644 --- a/nf_core/pipelines/sync.py +++ b/nf_core/pipelines/sync.py @@ -18,6 +18,7 @@ import nf_core import nf_core.pipelines.create.create import nf_core.utils +from nf_core.github_api import gh_api from nf_core.pipelines.lint_utils import dump_yaml_with_prettier log = logging.getLogger(__name__) @@ -120,7 +121,7 @@ def __init__( ) # Set up the API auth if supplied on the command line - self.gh_api = nf_core.utils.gh_api + self.gh_api = gh_api self.gh_api.lazy_init() if self.gh_username and "GITHUB_AUTH_TOKEN" in os.environ: log.debug(f"Authenticating sync as {self.gh_username}") diff --git a/nf_core/pydantic_models.py b/nf_core/pydantic_models.py new file mode 100644 index 0000000000..ffdcebc0fb --- /dev/null +++ b/nf_core/pydantic_models.py @@ -0,0 +1,211 @@ +"""Pydantic models for the `.nf-core.yml` configuration file. + +Kept separate from nf_core.utils so that pydantic is only imported +when the config file is actually parsed. +""" + +from pathlib import Path +from typing import Any, Literal + +from pydantic import BaseModel, ConfigDict, Field, field_validator + + +class NFCoreTemplateConfig(BaseModel): + """Template configuration schema""" + + org: str | None = None + """ Organisation name """ + name: str | None = None + """ Pipeline name """ + description: str | None = None + """ Pipeline description """ + author: str | None = None + """ Pipeline author """ + version: str | None = None + """ Pipeline version """ + force: bool | None = True + """ Force overwrite of existing files """ + outdir: str | Path | None = None + """ Output directory """ + skip_features: list | None = None + """ Skip features. See https://nf-co.re/docs/nf-core-tools/pipelines/create for a list of features. """ + is_nfcore: bool | None = None + """ Whether the pipeline is an nf-core pipeline. """ + + # convert outdir to str + @field_validator("outdir") + @classmethod + def outdir_to_str(cls, v: str | Path | None) -> str | None: + if v is not None: + v = str(v) + return v + + def __getitem__(self, item: str) -> Any: + if self is None: + return None + return getattr(self, item) + + def get(self, item: str, default: Any = None) -> Any: + return getattr(self, item, default) + + +class NFCoreYamlLintConfig(BaseModel): + """ + schema for linting config in `.nf-core.yml` should cover: + + .. code-block:: yaml + + files_unchanged: + - .github/workflows/branch.yml + modules_config: False + modules_config: + - fastqc + # merge_markers: False + merge_markers: + - docs/my_pdf.pdf + nextflow_config: False + nextflow_config: + - manifest.name + - config_defaults: + - params.annotation_db + - params.multiqc_comment_headers + - params.custom_table_headers + # multiqc_config: False + multiqc_config: + - report_section_order + - report_comment + files_exist: + - CITATIONS.md + template_strings: False + template_strings: + - docs/my_pdf.pdf + nfcore_components: False + # nf_test_content: False + nf_test_content: + - tests/.nf.test + - tests/nextflow.config + - nf-test.config + """ + + files_unchanged: bool | list[str] | None = None + """ List of files that should not be changed """ + modules_config: bool | list[str] | None = None + """ List of modules that should not be changed """ + merge_markers: bool | list[str] | None = None + """ List of files that should not contain merge markers """ + nextflow_config: bool | list[str | dict[str, list[str]]] | None = None + """ List of Nextflow config files that should not be changed """ + nf_test_content: bool | list[str] | None = None + """ List of nf-test content that should not be changed """ + multiqc_config: bool | list[str] | None = None + """ List of MultiQC config options that be changed """ + files_exist: bool | list[str] | None = None + """ List of files that can not exist """ + template_strings: bool | list[str] | None = None + """ List of files that can contain template strings """ + readme: bool | list[str] | None = None + """ Lint the README.md file """ + nfcore_components: bool | None = None + """ Lint all required files to use nf-core modules and subworkflows """ + actions_nf_test: bool | None = None + """ Lint all required files to use GitHub Actions CI """ + actions_awstest: bool | None = None + """ Lint all required files to run tests on AWS """ + actions_awsfulltest: bool | None = None + """ Lint all required files to run full tests on AWS """ + pipeline_todos: bool | None = None + """ Lint for TODOs statements""" + pipeline_if_empty_null: bool | None = None + """ Lint for ifEmpty(null) statements""" + plugin_includes: bool | None = None + """ Lint for nextflow plugin """ + pipeline_name_conventions: bool | None = None + """ Lint for pipeline name conventions """ + schema_lint: bool | None = None + """ Lint nextflow_schema.json file""" + schema_params: bool | None = None + """ Lint schema for all params """ + system_exit: bool | None = None + """ Lint for System.exit calls in groovy/nextflow code """ + schema_description: bool | None = None + """ Check that every parameter in the schema has a description. """ + actions_schema_validation: bool | None = None + """ Lint GitHub Action workflow files with schema""" + modules_json: bool | None = None + """ Lint modules.json file """ + modules_structure: bool | None = None + """ Lint modules structure """ + base_config: bool | None = None + """ Lint base.config file """ + nfcore_yml: bool | None = None + """ Lint nf-core.yml """ + version_consistency: bool | None = None + """ Lint for version consistency """ + included_configs: bool | None = None + """ Lint for included configs """ + local_component_structure: bool | None = None + """ Lint local components use correct structure mirroring remote""" + container_configs: bool | None = None + """ Lint that container configuration files in conf/ are up to date """ + rocrate_readme_sync: bool | None = None + """ Lint for README.md and rocrate.json sync """ + + def __getitem__(self, item: str) -> Any: + return getattr(self, item) + + def get(self, item: str, default: Any = None) -> Any: + if getattr(self, item, default) is None: + return default + return getattr(self, item, default) + + def __setitem__(self, item: str, value: Any) -> None: + setattr(self, item, value) + + +class NFCoreYamlConfig(BaseModel): + """.nf-core.yml configuration file schema""" + + model_config = ConfigDict(populate_by_name=True) + + repository_type: Literal["pipeline", "modules"] | None = None + """ Type of repository """ + nf_core_version: str | None = None + """ Version of nf-core/tools used to create/update the pipeline """ + org_path: str | None = None + """ Path to the organisation's modules repository (used for modules repo_type only) """ + lint: NFCoreYamlLintConfig | None = None + """ Pipeline linting configuration, see https://nf-co.re/docs/nf-core-tools/pipelines/lint#linting-config for examples and documentation """ + template: NFCoreTemplateConfig | None = None + """ Pipeline template configuration """ + bump_version: dict[str, bool] | None = None + """ Disable bumping of the version for a module/subworkflow (when repository_type is modules). See https://nf-co.re/docs/nf-core-tools/modules/bump-versions for more information. """ + update: dict[str, str | bool | dict[str, str | dict[str, str | bool]]] | None = None + """ Disable updating specific modules/subworkflows (when repository_type is pipeline). See https://nf-co.re/docs/nf-core-tools/modules/update for more information. """ + container_registry: list[str] | None = Field(default=None, alias="container-registry") + """ Additional container registry prefixes allowed when linting container directives. """ + + def __getitem__(self, item: str) -> Any: + return getattr(self, item) + + def get(self, item: str, default: Any = None) -> Any: + return getattr(self, item, default) + + def __setitem__(self, item: str, value: Any) -> None: + setattr(self, item, value) + + def model_dump(self, **kwargs) -> dict[str, Any]: + # Get the initial data + config = super().model_dump(**kwargs) + + if self.repository_type == "modules": + # Fields to exclude for modules + fields_to_exclude = ["template", "update"] + else: # pipeline + # Fields to exclude for pipeline + fields_to_exclude = ["bump_version", "org_path"] + + # Remove the fields based on repository_type + for field in fields_to_exclude: + config.pop(field, None) + + return config diff --git a/nf_core/subworkflows/__init__.py b/nf_core/subworkflows/__init__.py index 8e3c85a271..3ca23d0f30 100644 --- a/nf_core/subworkflows/__init__.py +++ b/nf_core/subworkflows/__init__.py @@ -1,8 +1,16 @@ -from .create import SubworkflowCreate -from .info import SubworkflowInfo -from .install import SubworkflowInstall -from .lint import SubworkflowLint -from .list import SubworkflowList -from .patch import SubworkflowPatch -from .remove import SubworkflowRemove -from .update import SubworkflowUpdate +from nf_core.utils import lazy_attrs + +# Lazy imports to keep CLI start-up fast +__getattr__, __dir__ = lazy_attrs( + globals(), + { + "SubworkflowCreate": "nf_core.subworkflows.create", + "SubworkflowInfo": "nf_core.subworkflows.info", + "SubworkflowInstall": "nf_core.subworkflows.install", + "SubworkflowLint": "nf_core.subworkflows.lint", + "SubworkflowList": "nf_core.subworkflows.list", + "SubworkflowPatch": "nf_core.subworkflows.patch", + "SubworkflowRemove": "nf_core.subworkflows.remove", + "SubworkflowUpdate": "nf_core.subworkflows.update", + }, +) diff --git a/nf_core/synced_repo.py b/nf_core/synced_repo.py index 72b5cf34b3..dc79e9a759 100644 --- a/nf_core/synced_repo.py +++ b/nf_core/synced_repo.py @@ -227,36 +227,22 @@ def checkout_branch(self): """ Checks out the specified branch of the repository """ - try: - self.repo.git.checkout(self.branch) - except GitCommandError as e: - if ( - self.fullname - and "modules" in self.fullname - and "Your local changes to the following files would be overwritten by checkout" in str(e) - ): - log.debug(f"Overwriting local changes in '{self.local_repo_dir}'") - self.repo.git.checkout(self.branch, force=True) - else: - raise e + self.checkout(self.branch) def checkout(self, commit): """ - Checks out the repository at the requested commit + Checks out the repository at the requested commit (or branch) Args: - commit (str): Git SHA of the commit + commit (str): Git SHA of the commit, or a branch name """ try: self.repo.git.checkout(commit) except GitCommandError as e: - if ( - self.fullname - and "modules" in self.fullname - and "Your local changes to the following files would be overwritten by checkout" in str(e) - ): - log.debug(f"Overwriting local changes in '{self.local_repo_dir}'") - self.repo.git.checkout(self.branch, force=True) + if self.fullname and "modules" in self.fullname and "would be overwritten by checkout" in str(e): + log.debug(f"Discarding local changes in '{self.local_repo_dir}'") + self.repo.git.clean("-df") + self.repo.git.checkout(commit, force=True) else: raise e @@ -305,7 +291,8 @@ def install_component(self, component_name: str, install_dir: str | Path, commit # Check out the repository at the requested ref try: self.checkout(commit) - except git.GitCommandError: + except git.GitCommandError as e: + log.error(f"Could not check out '{commit}' in the modules cache '{self.local_repo_dir}':\n{e}") return False # Check if the module/subworkflow exists in the branch diff --git a/nf_core/utils.py b/nf_core/utils.py index 0e751d4c52..e53744bb88 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -3,48 +3,32 @@ """ import ast -import concurrent.futures import datetime import errno import fnmatch -import hashlib +import functools +import importlib import io import json import logging -import mimetypes import os -import random import re -import shlex -import subprocess import sys -import tempfile import time from collections.abc import Callable, Generator from contextlib import contextmanager, suppress from enum import Enum from functools import lru_cache from pathlib import Path -from typing import TYPE_CHECKING, Any, Literal - -import git -import git.exc -import prompt_toolkit.styles -import questionary -import requests.auth -import requests_cache -import rich -import rich.markup -import yaml -from packaging.version import Version -from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator -from rich.live import Live -from rich.spinner import Spinner +from typing import TYPE_CHECKING, Any + +from rich.console import Console import nf_core if TYPE_CHECKING: from nf_core.pipelines.schema import PipelineSchema + from nf_core.pydantic_models import NFCoreYamlConfig log = logging.getLogger(__name__) @@ -57,38 +41,83 @@ r"[green] `._,._,'", ] -# Custom style for questionary -nfcore_question_style = prompt_toolkit.styles.Style( - [ - ("qmark", "fg:ansiblue bold"), # token in front of the question - ("question", "bold"), # question text - ( - "answer", - "fg:ansigreen nobold bg:", - ), # submitted answer text behind the question - ( - "pointer", - "fg:ansiyellow bold", - ), # pointer used in select and checkbox prompts - ( - "highlighted", - "fg:ansiblue bold", - ), # pointed-at choice in select and checkbox prompts - ( - "selected", - "fg:ansiyellow noreverse bold", - ), # style for a selected item of a checkbox - ("separator", "fg:ansiblack"), # separator in lists - ("instruction", ""), # user instructions for select, rawselect, checkbox - ("text", ""), # plain text - ( - "disabled", - "fg:gray italic", - ), # disabled choices for select and checkbox prompts - ("choice-default", "fg:ansiblack"), - ("choice-default-changed", "fg:ansiyellow"), - ("choice-required", "fg:ansired"), - ] + +def lazy_attrs(module_globals: dict, mapping: dict[str, "str | Callable"]): + """Build module-level ``__getattr__`` and ``__dir__`` for lazy attributes (PEP 562). + + Each attribute maps either to the dotted path of the module to import it + from, or to a zero-argument callable that builds it. Resolved attributes + are cached in the module's globals, so the hook only fires once per name. + + Usage:: + + __getattr__, __dir__ = lazy_attrs(globals(), {"PipelineCreateApp": "nf_core.pipelines.create"}) + """ + + def module_getattr(name): + target = mapping.get(name) + if target is None: + raise AttributeError(f"module {module_globals['__name__']!r} has no attribute {name!r}") + value = target() if callable(target) else getattr(importlib.import_module(target), name) + module_globals[name] = value + return value + + def module_dir(): + return sorted(set(module_globals) | set(mapping)) + + return module_getattr, module_dir + + +# Custom style for questionary (built lazily to keep CLI start-up fast) +@functools.cache +def _nfcore_question_style(): + import prompt_toolkit.styles + + return prompt_toolkit.styles.Style( + [ + ("qmark", "fg:ansiblue bold"), # token in front of the question + ("question", "bold"), # question text + ( + "answer", + "fg:ansigreen nobold bg:", + ), # submitted answer text behind the question + ( + "pointer", + "fg:ansiyellow bold", + ), # pointer used in select and checkbox prompts + ( + "highlighted", + "fg:ansiblue bold", + ), # pointed-at choice in select and checkbox prompts + ( + "selected", + "fg:ansiyellow noreverse bold", + ), # style for a selected item of a checkbox + ("separator", "fg:ansiblack"), # separator in lists + ("instruction", ""), # user instructions for select, rawselect, checkbox + ("text", ""), # plain text + ( + "disabled", + "fg:gray italic", + ), # disabled choices for select and checkbox prompts + ("choice-default", "fg:ansiblack"), + ("choice-default-changed", "fg:ansiyellow"), + ("choice-required", "fg:ansired"), + ] + ) + + +# Lazy imports to keep CLI start-up fast +__getattr__, __dir__ = lazy_attrs( + globals(), + { + "nfcore_question_style": _nfcore_question_style, + "GitHubAPISession": "nf_core.github_api", + "gh_api": "nf_core.github_api", + "NFCoreTemplateConfig": "nf_core.pydantic_models", + "NFCoreYamlLintConfig": "nf_core.pydantic_models", + "NFCoreYamlConfig": "nf_core.pydantic_models", + }, ) @@ -98,7 +127,7 @@ def is_interactive() -> bool: NFCORE_CACHE_DIR = Path( - os.environ.get("XDG_CACHE_HOME", Path(os.getenv("HOME") or "", ".cache")), + os.environ.get("XDG_CACHE_HOME") or Path(os.getenv("HOME") or "") / ".cache", "nfcore", ) NFCORE_DIR = Path( @@ -149,10 +178,60 @@ def unquote(s: str) -> str: return s -def fetch_remote_version(source_url): - response = requests.get(source_url, timeout=3) - remote_version = re.sub(r"[^0-9\.]", "", response.text) - return remote_version +# The version check never fetches on the hot path (update-notifier pattern): +# it only reads the cached remote version, and refreshes the cache in a +# detached background process so that no run ever blocks on the network. +REMOTE_VERSION_CACHE = Path(NFCORE_CACHE_DIR, "latest_version.json") +REMOTE_VERSION_CACHE_EXPIRY = 60 * 60 * 24 # refresh at most once a day +REMOTE_VERSION_REFRESH_BACKOFF = 60 * 10 # wait at least this long between refresh attempts + + +def _load_version_cache() -> dict: + try: + with open(REMOTE_VERSION_CACHE) as fh: + cached = json.load(fh) + if isinstance(cached, dict): + return cached + except (OSError, ValueError): + pass + return {} + + +def _load_cached_remote_version() -> str | None: + from packaging.version import InvalidVersion, Version + + cached = _load_version_cache() + try: + if time.time() - cached["timestamp"] < REMOTE_VERSION_CACHE_EXPIRY: + Version(cached["version"]) # guard against a corrupted cache + return cached["version"] + except (KeyError, TypeError, InvalidVersion): + pass + return None + + +def _spawn_remote_version_refresh(source_url: str) -> None: + """Kick off a detached background process to refresh the remote version cache.""" + import subprocess + + try: + cached = _load_version_cache() + if time.time() - float(cached.get("attempted_at") or 0) < REMOTE_VERSION_REFRESH_BACKOFF: + return + # Record the attempt up front, so failed refreshes back off instead of respawning every run + cached["attempted_at"] = time.time() + setup_nfcore_cachedir() + with open(REMOTE_VERSION_CACHE, "w") as fh: + json.dump(cached, fh) + subprocess.Popen( + [sys.executable, "-m", "nf_core.version_updater", source_url, str(REMOTE_VERSION_CACHE)], + stdin=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + start_new_session=True, + ) + except (OSError, ValueError, TypeError, subprocess.SubprocessError) as e: + log.debug(f"Could not start background version check: {e}") def check_if_outdated( @@ -165,7 +244,10 @@ def check_if_outdated( """ # Exit immediately if disabled via ENV var if os.environ.get("NFCORE_NO_VERSION_CHECK", False): - return (True, "", "") + return (False, "", "") + + from packaging.version import Version + # Set and clean up the current version string if current_version is None: current_version = nf_core.__version__ @@ -176,12 +258,10 @@ def check_if_outdated( # check if we have a newer version without blocking the rest of the script is_outdated = False if remote_version is None: # we set it manually for tests - try: - with concurrent.futures.ThreadPoolExecutor() as executor: - future = executor.submit(fetch_remote_version, source_url) - remote_version = future.result() - except requests.exceptions.RequestException as e: - log.debug(f"Could not check for nf-core updates: {e}") + remote_version = _load_cached_remote_version() + if remote_version is None: + # No fresh cache - refresh it in the background for the next run + _spawn_remote_version_refresh(source_url) if remote_version is not None and Version(remote_version) > Version(current_version): is_outdated = True return (is_outdated, current_version, remote_version) @@ -196,6 +276,10 @@ def rich_force_colors(): return None +stdout = Console(force_terminal=rich_force_colors()) +stderr = Console(stderr=True, force_terminal=rich_force_colors()) + + class Pipeline: """Object to hold information about a local pipeline. @@ -216,6 +300,8 @@ class Pipeline: def __init__(self, wf_path: Path) -> None: """Initialise pipeline object""" + import git + self.conda_config: dict = {} self.conda_package_info: dict = {} self.nf_config: dict = {} @@ -248,6 +334,8 @@ def _load(self) -> bool: def _load_conda_environment(self) -> bool: """Try to load the pipeline environment.yml file, if it exists""" + import yaml + try: with open(Path(self.wf_path, "environment.yml")) as fh: self.conda_config = yaml.safe_load(fh) @@ -262,6 +350,8 @@ def _fp(self, fn: str | Path) -> Path: def list_files(self) -> list[Path]: """Get a list of all files in the pipeline""" + import subprocess + files = [] try: # First, try to get the list of files using git @@ -336,6 +426,8 @@ def pretty_nf_version(version: tuple[int, int, int, bool]) -> str: @lru_cache(maxsize=1) def get_nf_version() -> tuple[int, int, int, bool] | None: """Get the version of Nextflow installed on the system. Cached for the lifetime of the process.""" + import subprocess + try: cmd_out = run_cmd("nextflow", "-v") if cmd_out is None: @@ -412,6 +504,8 @@ def fetch_wf_config(wf_path: Path, cache_config: bool = True) -> dict: dict: Workflow configuration settings. """ + import hashlib + log.debug(f"Got '{wf_path}' as path") wf_path = Path(wf_path) config: dict[str, Any] = {} @@ -503,6 +597,9 @@ def fetch_wf_config(wf_path: Path, cache_config: bool = True) -> dict: def run_cmd(executable: str, cmd: str) -> tuple[bytes, bytes] | None: """Run a specified command and capture the output. Handle errors nicely.""" + import shlex + import subprocess + full_cmd = f"{executable} {cmd}" log.debug(f"Running command: {full_cmd}") try: @@ -529,16 +626,6 @@ def run_cmd(executable: str, cmd: str) -> tuple[bytes, bytes] | None: return (proc.stdout, proc.stderr) -def setup_nfcore_dir() -> bool: - """Creates a directory for files that need to be kept between sessions - - Currently only used for keeping local copies of modules repos - """ - if not NFCORE_DIR.exists(): - NFCORE_DIR.mkdir(parents=True) - return True - - def setup_requests_cachedir() -> dict[str, Path | datetime.timedelta | str]: """Sets up local caching for faster remote HTTP requests. @@ -560,14 +647,16 @@ def setup_requests_cachedir() -> dict[str, Path | datetime.timedelta | str]: return config -def setup_nfcore_cachedir(cache_fn: str | Path) -> Path: - """Sets up local caching for caching files between sessions.""" +def setup_nfcore_cachedir(cache_fn: str | Path | None = None) -> Path: + """Sets up local caching for caching files between sessions. - cachedir = Path(NFCORE_CACHE_DIR, cache_fn) + Creates and returns a subdirectory of the nf-core cache directory, + or the cache directory itself if no subdirectory is given. + """ + cachedir = Path(NFCORE_CACHE_DIR, cache_fn) if cache_fn else NFCORE_CACHE_DIR try: - if not Path(cachedir).exists(): - Path(cachedir).mkdir(parents=True) + cachedir.mkdir(parents=True, exist_ok=True) except PermissionError: log.warning(f"Could not create cache directory: {cachedir}") @@ -587,6 +676,9 @@ def wait_cli_function(poll_func: Callable[[], bool], refresh_per_second: int = 2 Returns: None. Just sits in an infinite loop until the function returns True. """ + from rich.live import Live + from rich.spinner import Spinner + try: spinner = Spinner("dots2", "Use ctrl+c to stop waiting and force exit.") with Live(spinner, refresh_per_second=refresh_per_second): @@ -606,6 +698,9 @@ def poll_nfcore_web_api(api_url: str, post_data: dict | None = None) -> dict: Expects API response to be valid JSON and contain a top-level 'status' key. """ + import requests + import requests_cache + # Run without requests_cache so that we get the updated statuses with requests_cache.disabled(): try: @@ -647,171 +742,6 @@ def poll_nfcore_web_api(api_url: str, post_data: dict | None = None) -> dict: return web_response -class GitHubAPISession(requests_cache.CachedSession): - """ - Class to provide a single session for interacting with the GitHub API for a run. - Inherits the requests_cache.CachedSession and adds additional functionality, - such as automatically setting up GitHub authentication if we can. - """ - - def __init__(self) -> None: - self.auth_mode: str | None = None - self.return_ok: list[int] = [200, 201] - self.return_retry: list[int] = [403] - self.return_unauthorised: list[int] = [401] - self.has_init: bool = False - - def lazy_init(self) -> None: - """ - Initialise the object. - - Only do this when it's actually being used (due to global import) - """ - log.debug("Initialising GitHub API requests session") - cache_config = setup_requests_cachedir() - super().__init__(**cache_config) # type: ignore[arg-type] - self.setup_github_auth() - self.has_init = True - - def setup_github_auth(self, auth=None): - """ - Try to automatically set up GitHub authentication - """ - if auth is not None: - self.auth = auth - self.auth_mode = "supplied to function" - - # Class for Bearer token authentication - # https://stackoverflow.com/a/58055668/713980 - class BearerAuth(requests.auth.AuthBase): - def __init__(self, token): - self.token = token - - def __call__(self, r): - r.headers["authorization"] = f"Bearer {self.token}" - return r - - # Default auth if we're running and the gh CLI tool is installed - gh_cli_config_fn = Path.home() / ".config" / "gh" / "hosts.yml" - if self.auth is None and gh_cli_config_fn.exists(): - try: - with open(gh_cli_config_fn) as fh: - gh_cli_config = yaml.safe_load(fh) - self.auth = requests.auth.HTTPBasicAuth( - gh_cli_config["github.com"]["user"], - gh_cli_config["github.com"]["oauth_token"], - ) - self.auth_mode = f"gh CLI config: {gh_cli_config['github.com']['user']}" - except (OSError, KeyError, yaml.YAMLError): - ex_type, ex_value, _ = sys.exc_info() - if ex_type is not None: - output = rich.markup.escape(f"{ex_type.__name__}: {ex_value}") - log.debug(f"Couldn't auto-auth with GitHub CLI auth from '{gh_cli_config_fn}': [red]{output}") - - # Default auth if we have a GitHub Token (eg. GitHub Actions CI) - if os.environ.get("GITHUB_TOKEN") is not None and self.auth is None: - self.auth_mode = "Bearer token with GITHUB_TOKEN" - self.auth = BearerAuth(os.environ["GITHUB_TOKEN"]) - else: - log.warning("Could not find GitHub authentication token. Some API requests may fail.") - - log.debug(f"Using GitHub auth: {self.auth_mode}") - - def log_content_headers(self, request, post_data=None): - """ - Try to dump everything to the console, useful when things go wrong. - """ - log.debug(f"Requested URL: {request.url}") - log.debug(f"From requests cache: {request.from_cache}") - log.debug(f"Request status code: {request.status_code}") - log.debug(f"Request reason: {request.reason}") - if post_data is None: - post_data = {} - try: - log.debug(json.dumps(dict(request.headers), indent=4)) - log.debug(json.dumps(request.json(), indent=4)) - log.debug(json.dumps(post_data, indent=4)) - except (json.JSONDecodeError, TypeError) as e: - log.debug(f"Could not parse JSON response from GitHub API! {e}") - log.debug(request.headers) - log.debug(request.content) - log.debug(post_data) - - def safe_get(self, url): - """ - Run a GET request, raise a nice exception with lots of logging if it fails. - """ - if not self.has_init: - self.lazy_init() - request = self.get(url) - if request.status_code in self.return_retry: - stderr = rich.console.Console(stderr=True, force_terminal=rich_force_colors()) - try: - r = self.request_retry(url) - except Exception as e: - stderr.print_exception() - raise e - else: - return r - elif request.status_code in self.return_unauthorised: - raise RuntimeError("GitHub API PR failed, probably due to an expired GITHUB_TOKEN.") - - return request - - def get(self, url, params=None, **kwargs): - """ - Initialise the session if we haven't already, then call the superclass get method. - """ - if not self.has_init: - self.lazy_init() - return super().get(url, params=params, **kwargs) - - def request_retry(self, url, post_data=None): - """ - Try to fetch a URL, keep retrying if we get a certain return code. - - Used in nf-core pipelines sync code because we get 403 errors: too many simultaneous requests - See https://github.com/nf-core/tools/issues/911 - """ - if not self.has_init: - self.lazy_init() - - # Start the loop for a retry mechanism - while True: - # GET request - if post_data is None: - log.debug(f"Sending GET request to {url}") - r = self.get(url=url) - # POST request - else: - log.debug(f"Sending POST request to {url}") - r = self.post(url=url, json=post_data) - - # Failed but expected - try again - if r.status_code in self.return_retry: - self.log_content_headers(r, post_data) - log.debug(f"GitHub API PR failed - got return code {r.status_code}") - wait_time = float(re.sub("[^0-9]", "", str(r.headers.get("Retry-After", 0)))) - if wait_time == 0: - log.debug("Couldn't find 'Retry-After' header, guessing a length of time to wait") - wait_time = random.randrange(10, 60) - log.warning(f"Got API return code {r.status_code}. Trying again after {wait_time} seconds..") - time.sleep(wait_time) - - # Unexpected error - raise - elif r.status_code not in self.return_ok: - self.log_content_headers(r, post_data) - raise RuntimeError(f"GitHub API PR failed - got return code {r.status_code} from {url}") - - # Success! - else: - return r - - -# Single session object to use for entire codebase. Not sure if there's a better way to do this? -gh_api = GitHubAPISession() - - def anaconda_package(dep, dep_channels=None): """Query conda package information. @@ -825,6 +755,7 @@ def anaconda_package(dep, dep_channels=None): A LookupError, if the connection fails or times out or gives an unexpected status code A ValueError, if the package name can not be found (404) """ + import requests if dep_channels is None: dep_channels = ["conda-forge", "bioconda"] @@ -910,6 +841,8 @@ def pip_package(dep): A LookupError, if the connection fails or times out A ValueError, if the package name can not be found """ + import requests + pip_depname, _ = dep.split("=", 1) pip_api_url = f"https://pypi.python.org/pypi/{pip_depname}/json" try: @@ -938,6 +871,8 @@ def get_biocontainer_tag(package, version): A ValueError, if the package name can not be found (404) """ + import requests + biocontainers_api_url = f"https://api.biocontainers.pro/ga4gh/trs/v2/tools/{package}/versions/{package}-{version}" def get_tag_date(tag_date): @@ -1002,6 +937,7 @@ def get_tag_date(tag_date): def custom_yaml_dumper(): """Overwrite default PyYAML output to make Prettier YAML linting happy""" + import yaml class CustomDumper(yaml.Dumper): def represent_dict_preserve_order(self, data): @@ -1034,6 +970,8 @@ def write_line_break(self, data=None): def is_file_binary(path): """Check file path to see if it is a binary file""" + import mimetypes + binary_ftypes = ["image", "application/java-archive", "application/x-java-archive"] binary_extensions = [".jpeg", ".jpg", ".png", ".zip", ".gz", ".jar", ".tar"] @@ -1060,13 +998,17 @@ def prompt_remote_pipeline_name(wfs): Raises: AssertionError, if pipeline cannot be found """ + import questionary + import requests + + from nf_core.github_api import gh_api if not is_interactive(): raise UserWarning("No pipeline name provided and session is not interactive (no TTY detected).") pipeline = questionary.autocomplete( "Pipeline name:", choices=[wf.name for wf in wfs.remote_workflows], - style=nfcore_question_style, + style=_nfcore_question_style(), ).unsafe_ask() # Check nf-core repos @@ -1101,6 +1043,8 @@ def prompt_pipeline_release_branch( Returns: choice (questionary.Choice or bool): Selected release / branch or False if no releases / branches available """ + import questionary + # Prompt user for release tag, tag_set will contain all available. choices: list[questionary.Choice] = [] tag_set: list[str] = [] @@ -1132,30 +1076,21 @@ def prompt_pipeline_release_branch( if multiple: return ( - questionary.checkbox("Select release / branch:", choices=choices, style=nfcore_question_style).unsafe_ask(), + questionary.checkbox( + "Select release / branch:", choices=choices, style=_nfcore_question_style() + ).unsafe_ask(), tag_set, ) else: return ( - questionary.select("Select release / branch:", choices=choices, style=nfcore_question_style).unsafe_ask(), + questionary.select( + "Select release / branch:", choices=choices, style=_nfcore_question_style() + ).unsafe_ask(), tag_set, ) -class SingularityCacheFilePathValidator(questionary.Validator): - """ - Validator for file path specified as --singularity-cache-index argument in nf-core pipelines download - """ - - def validate(self, document) -> None: - if len(document.text) and not Path(document.text).is_file(): - raise questionary.ValidationError( - message="Invalid remote cache index file", - cursor_position=len(document.text), - ) - - def get_repo_releases_branches(pipeline, wfs): """Fetches details of a nf-core workflow to download. @@ -1169,6 +1104,7 @@ def get_repo_releases_branches(pipeline, wfs): Raises: LockupError, if the pipeline can not be found. """ + from nf_core.github_api import gh_api wf_releases = [] wf_branches = {} @@ -1247,6 +1183,7 @@ def get_repo_commit(pipeline, commit_id): Returns: commit_id: String or None """ + from nf_core.github_api import gh_api commit_response = gh_api.get( f"https://api.github.com/repos/{pipeline}/commits/{commit_id}", headers={"Accept": "application/vnd.github.sha"} @@ -1261,208 +1198,7 @@ def get_repo_commit(pipeline, commit_id): DEPRECATED_CONFIG_PATHS = [".nf-core-lint.yml", ".nf-core-lint.yaml"] -class NFCoreTemplateConfig(BaseModel): - """Template configuration schema""" - - org: str | None = None - """ Organisation name """ - name: str | None = None - """ Pipeline name """ - description: str | None = None - """ Pipeline description """ - author: str | None = None - """ Pipeline author """ - version: str | None = None - """ Pipeline version """ - force: bool | None = True - """ Force overwrite of existing files """ - outdir: str | Path | None = None - """ Output directory """ - skip_features: list | None = None - """ Skip features. See https://nf-co.re/docs/nf-core-tools/pipelines/create for a list of features. """ - is_nfcore: bool | None = None - """ Whether the pipeline is an nf-core pipeline. """ - - # convert outdir to str - @field_validator("outdir") - @classmethod - def outdir_to_str(cls, v: str | Path | None) -> str | None: - if v is not None: - v = str(v) - return v - - def __getitem__(self, item: str) -> Any: - if self is None: - return None - return getattr(self, item) - - def get(self, item: str, default: Any = None) -> Any: - return getattr(self, item, default) - - -class NFCoreYamlLintConfig(BaseModel): - """ - schema for linting config in `.nf-core.yml` should cover: - - .. code-block:: yaml - - files_unchanged: - - .github/workflows/branch.yml - modules_config: False - modules_config: - - fastqc - # merge_markers: False - merge_markers: - - docs/my_pdf.pdf - nextflow_config: False - nextflow_config: - - manifest.name - - config_defaults: - - params.annotation_db - - params.multiqc_comment_headers - - params.custom_table_headers - # multiqc_config: False - multiqc_config: - - report_section_order - - report_comment - files_exist: - - CITATIONS.md - template_strings: False - template_strings: - - docs/my_pdf.pdf - nfcore_components: False - # nf_test_content: False - nf_test_content: - - tests/.nf.test - - tests/nextflow.config - - nf-test.config - """ - - files_unchanged: bool | list[str] | None = None - """ List of files that should not be changed """ - modules_config: bool | list[str] | None = None - """ List of modules that should not be changed """ - merge_markers: bool | list[str] | None = None - """ List of files that should not contain merge markers """ - nextflow_config: bool | list[str | dict[str, list[str]]] | None = None - """ List of Nextflow config files that should not be changed """ - nf_test_content: bool | list[str] | None = None - """ List of nf-test content that should not be changed """ - multiqc_config: bool | list[str] | None = None - """ List of MultiQC config options that be changed """ - files_exist: bool | list[str] | None = None - """ List of files that can not exist """ - template_strings: bool | list[str] | None = None - """ List of files that can contain template strings """ - readme: bool | list[str] | None = None - """ Lint the README.md file """ - nfcore_components: bool | None = None - """ Lint all required files to use nf-core modules and subworkflows """ - actions_nf_test: bool | None = None - """ Lint all required files to use GitHub Actions CI """ - actions_awstest: bool | None = None - """ Lint all required files to run tests on AWS """ - actions_awsfulltest: bool | None = None - """ Lint all required files to run full tests on AWS """ - pipeline_todos: bool | None = None - """ Lint for TODOs statements""" - pipeline_if_empty_null: bool | None = None - """ Lint for ifEmpty(null) statements""" - plugin_includes: bool | None = None - """ Lint for nextflow plugin """ - pipeline_name_conventions: bool | None = None - """ Lint for pipeline name conventions """ - schema_lint: bool | None = None - """ Lint nextflow_schema.json file""" - schema_params: bool | None = None - """ Lint schema for all params """ - system_exit: bool | None = None - """ Lint for System.exit calls in groovy/nextflow code """ - schema_description: bool | None = None - """ Check that every parameter in the schema has a description. """ - actions_schema_validation: bool | None = None - """ Lint GitHub Action workflow files with schema""" - modules_json: bool | None = None - """ Lint modules.json file """ - modules_structure: bool | None = None - """ Lint modules structure """ - base_config: bool | None = None - """ Lint base.config file """ - nfcore_yml: bool | None = None - """ Lint nf-core.yml """ - version_consistency: bool | None = None - """ Lint for version consistency """ - included_configs: bool | None = None - """ Lint for included configs """ - local_component_structure: bool | None = None - """ Lint local components use correct structure mirroring remote""" - container_configs: bool | None = None - """ Lint that container configuration files in conf/ are up to date """ - rocrate_readme_sync: bool | None = None - """ Lint for README.md and rocrate.json sync """ - - def __getitem__(self, item: str) -> Any: - return getattr(self, item) - - def get(self, item: str, default: Any = None) -> Any: - if getattr(self, item, default) is None: - return default - return getattr(self, item, default) - - def __setitem__(self, item: str, value: Any) -> None: - setattr(self, item, value) - - -class NFCoreYamlConfig(BaseModel): - """.nf-core.yml configuration file schema""" - - model_config = ConfigDict(populate_by_name=True) - - repository_type: Literal["pipeline", "modules"] | None = None - """ Type of repository """ - nf_core_version: str | None = None - """ Version of nf-core/tools used to create/update the pipeline """ - org_path: str | None = None - """ Path to the organisation's modules repository (used for modules repo_type only) """ - lint: NFCoreYamlLintConfig | None = None - """ Pipeline linting configuration, see https://nf-co.re/docs/nf-core-tools/pipelines/lint#linting-config for examples and documentation """ - template: NFCoreTemplateConfig | None = None - """ Pipeline template configuration """ - bump_version: dict[str, bool] | None = None - """ Disable bumping of the version for a module/subworkflow (when repository_type is modules). See https://nf-co.re/docs/nf-core-tools/modules/bump-versions for more information. """ - update: dict[str, str | bool | dict[str, str | dict[str, str | bool]]] | None = None - """ Disable updating specific modules/subworkflows (when repository_type is pipeline). See https://nf-co.re/docs/nf-core-tools/modules/update for more information. """ - container_registry: list[str] | None = Field(default=None, alias="container-registry") - """ Additional container registry prefixes allowed when linting container directives. """ - - def __getitem__(self, item: str) -> Any: - return getattr(self, item) - - def get(self, item: str, default: Any = None) -> Any: - return getattr(self, item, default) - - def __setitem__(self, item: str, value: Any) -> None: - setattr(self, item, value) - - def model_dump(self, **kwargs) -> dict[str, Any]: - # Get the initial data - config = super().model_dump(**kwargs) - - if self.repository_type == "modules": - # Fields to exclude for modules - fields_to_exclude = ["template", "update"] - else: # pipeline - # Fields to exclude for pipeline - fields_to_exclude = ["bump_version", "org_path"] - - # Remove the fields based on repository_type - for field in fields_to_exclude: - config.pop(field, None) - - return config - - -def load_tools_config(directory: str | Path = ".") -> tuple[Path | None, NFCoreYamlConfig | None]: +def load_tools_config(directory: str | Path = ".") -> "tuple[Path | None, NFCoreYamlConfig | None]": """ Parse the nf-core.yml configuration file @@ -1473,6 +1209,11 @@ def load_tools_config(directory: str | Path = ".") -> tuple[Path | None, NFCoreY Returns the loaded config dict or False, if the file couldn't be loaded """ + import yaml + from pydantic import ValidationError + + from nf_core.pydantic_models import NFCoreTemplateConfig, NFCoreYamlConfig + tools_config = {} config_fn = get_first_available_path(directory, CONFIG_PATHS) @@ -1626,6 +1367,8 @@ def file_md5(fname): fname (str): Path to a local file. """ + import hashlib + # Calculate the md5 for the file on disk hash_md5 = hashlib.md5() with open(fname, "rb") as f: @@ -1717,6 +1460,8 @@ def set_wd_tempdir(base_dir: Path | None = None) -> Generator[Path, None, None]: Args: base_dir: Directory in which to create the tempdir. Defaults to the system temp location. """ + import tempfile + with tempfile.TemporaryDirectory(dir=base_dir) as tmp, set_wd(Path(tmp)): yield Path(tmp) diff --git a/nf_core/version_updater.py b/nf_core/version_updater.py new file mode 100644 index 0000000000..817cc379f8 --- /dev/null +++ b/nf_core/version_updater.py @@ -0,0 +1,38 @@ +"""Background updater for the cached nf-core version.""" + +import json +import re +import sys +import tempfile +import time +import urllib.request +from pathlib import Path + +from packaging.version import Version + + +def refresh_version_cache(source_url: str, cache_path: Path) -> None: + """Fetch and atomically cache the latest nf-core version.""" + with urllib.request.urlopen(source_url, timeout=10) as response: + remote_version = re.sub(r"[^0-9.]", "", response.read().decode()) + + # Do not replace a valid cache with a malformed response. + Version(remote_version) + + cache_path.parent.mkdir(parents=True, exist_ok=True) + with tempfile.TemporaryDirectory(dir=cache_path.parent) as temporary_dir: + temporary_path = Path(temporary_dir, cache_path.name) + temporary_path.write_text(json.dumps({"version": remote_version, "timestamp": time.time()})) + temporary_path.replace(cache_path) + + +def main() -> None: + """Run the background version updater.""" + if len(sys.argv) != 3: + raise SystemExit("usage: version_updater ") + + refresh_version_cache(sys.argv[1], Path(sys.argv[2])) + + +if __name__ == "__main__": + main() diff --git a/tests/pipelines/test_launch.py b/tests/pipelines/test_launch.py index 9cbee9ece7..419c618ac0 100644 --- a/tests/pipelines/test_launch.py +++ b/tests/pipelines/test_launch.py @@ -17,7 +17,7 @@ class TestLaunch(TestPipelines): def setUp(self) -> None: super().setUp() self.nf_params_fn = Path(self.pipeline_dir, "nf-params.json") - self.launcher = nf_core.pipelines.launch.Launch(self.pipeline_dir, params_out=self.nf_params_fn) + self.launcher = nf_core.pipelines.launch.Launch(str(self.pipeline_dir), params_out=self.nf_params_fn) @mock.patch.object(nf_core.pipelines.launch.Launch, "prompt_web_gui", side_effect=[True]) @mock.patch.object(nf_core.pipelines.launch.Launch, "launch_web_gui") diff --git a/tests/subworkflows/test_patch.py b/tests/subworkflows/test_patch.py index 884af41e83..62a39b3cb0 100644 --- a/tests/subworkflows/test_patch.py +++ b/tests/subworkflows/test_patch.py @@ -196,7 +196,7 @@ def test_create_patch_update_success(self): ) == Path("subworkflows", GITLAB_REPO, "bam_sort_stats_samtools", patch_fn) # Update the subworkflow - update_obj = nf_core.subworkflows.update.SubworkflowUpdate( + update_obj = nf_core.subworkflows.SubworkflowUpdate( self.pipeline_dir, sha=OLD_SHA, show_diff=False, @@ -256,7 +256,7 @@ def test_create_patch_update_fail(self): with open(swf_path / patch_fn) as fh: patch_contents = fh.read() - update_obj = nf_core.subworkflows.update.SubworkflowUpdate( + update_obj = nf_core.subworkflows.SubworkflowUpdate( self.pipeline_dir, sha=FAIL_SHA, show_diff=False, diff --git a/tests/test_version_updater.py b/tests/test_version_updater.py new file mode 100644 index 0000000000..5d938f5b20 --- /dev/null +++ b/tests/test_version_updater.py @@ -0,0 +1,63 @@ +"""Tests for the detached remote-version cache updater.""" + +import json +import subprocess +import sys +from unittest import mock + +import pytest +from packaging.version import InvalidVersion + +import nf_core.utils +from nf_core.version_updater import refresh_version_cache + + +def test_refresh_version_cache(tmp_path): + """A valid remote version is written to the cache atomically.""" + remote_version_path = tmp_path / "remote_version" + remote_version_path.write_text("4.1.0\n") + cache_path = tmp_path / "latest_version.json" + + refresh_version_cache(remote_version_path.as_uri(), cache_path) + + cached = json.loads(cache_path.read_text()) + assert cached["version"] == "4.1.0" + assert isinstance(cached["timestamp"], float) + + +def test_refresh_version_cache_rejects_invalid_version(tmp_path): + """A malformed response does not replace an existing valid cache.""" + remote_version_path = tmp_path / "remote_version" + remote_version_path.write_text("not a version") + cache_path = tmp_path / "latest_version.json" + original_cache = '{"version": "4.0.0", "timestamp": 123}' + cache_path.write_text(original_cache) + + with pytest.raises(InvalidVersion): + refresh_version_cache(remote_version_path.as_uri(), cache_path) + + assert cache_path.read_text() == original_cache + + +def test_spawn_remote_version_refresh_uses_updater_module(tmp_path, monkeypatch): + """The parent process launches the updater without embedding Python source.""" + cache_path = tmp_path / "latest_version.json" + monkeypatch.setattr(nf_core.utils, "NFCORE_CACHE_DIR", tmp_path) + monkeypatch.setattr(nf_core.utils, "REMOTE_VERSION_CACHE", cache_path) + + with mock.patch("subprocess.Popen") as popen: + nf_core.utils._spawn_remote_version_refresh("https://example.com/tools_version?v=4.0.0") + + popen.assert_called_once_with( + [ + sys.executable, + "-m", + "nf_core.version_updater", + "https://example.com/tools_version?v=4.0.0", + str(cache_path), + ], + stdin=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + start_new_session=True, + ) From f0eb0e2313a1539e29eafb75a69bd662cbd5b626 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:51:19 +0200 Subject: [PATCH 110/135] Update j178/prek-action digest to 5337cb9 (#4399) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/changelog.yml | 2 +- .github/workflows/deploy-pypi.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/lint-code.yml | 2 +- nf_core/pipeline-template/.github/workflows/fix_linting.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 2f67646b60..b5c82cec2b 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -65,7 +65,7 @@ jobs: python-version: "3.14" - name: Run pre-commit rules with prek - uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 + uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2 continue-on-error: true with: extra-args: --config .pre-commit-config.yaml --all-files diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index 1fd4c1fb07..7f8698bc16 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -34,6 +34,6 @@ jobs: - name: Publish dist to PyPI if: github.repository == 'nf-core/tools' - uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1 + uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # release/v1 with: password: ${{ secrets.pypi_password }} diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index dbb5c125cd..5a56315586 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -33,7 +33,7 @@ jobs: # Install and run prek - name: Run prek id: prek - uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 + uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2 with: extra-args: --config .pre-commit-config.yaml --all-files continue-on-error: true diff --git a/.github/workflows/lint-code.yml b/.github/workflows/lint-code.yml index 8b9714d762..fe5c64837a 100644 --- a/.github/workflows/lint-code.yml +++ b/.github/workflows/lint-code.yml @@ -22,6 +22,6 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - name: Run prek - uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 + uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2 with: extra-args: --config .pre-commit-config.yaml --all-files diff --git a/nf_core/pipeline-template/.github/workflows/fix_linting.yml b/nf_core/pipeline-template/.github/workflows/fix_linting.yml index 738038e8f8..829479b105 100644 --- a/nf_core/pipeline-template/.github/workflows/fix_linting.yml +++ b/nf_core/pipeline-template/.github/workflows/fix_linting.yml @@ -37,7 +37,7 @@ jobs: # Install and run prek - name: Run prek id: prek - uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 + uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2 continue-on-error: true # indication that the linting has finished diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 67f467a6e0..8ee7463f34 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -17,7 +17,7 @@ jobs: uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 - name: Run prek - uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2 + uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2 nf-core: runs-on: ubuntu-latest From bdaacf3866c26a4e4d5becd94762f04139fbdb2c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Jul 2026 11:08:21 +0000 Subject: [PATCH 111/135] Update dependency prettier to v3.9.5 (#4400) --- .pre-commit-config.yaml | 2 +- nf_core/.pre-commit-prettier-config.yaml | 2 +- nf_core/pipeline-template/.pre-commit-config.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cf88e0d39d..9616009073 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - id: prettier entry: prettier --experimental-cli --write --ignore-unknown --no-cache additional_dependencies: - - prettier@3.9.4 + - prettier@3.9.5 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: diff --git a/nf_core/.pre-commit-prettier-config.yaml b/nf_core/.pre-commit-prettier-config.yaml index b8cfe30d9f..30e0df0c14 100644 --- a/nf_core/.pre-commit-prettier-config.yaml +++ b/nf_core/.pre-commit-prettier-config.yaml @@ -4,4 +4,4 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.9.4 + - prettier@3.9.5 diff --git a/nf_core/pipeline-template/.pre-commit-config.yaml b/nf_core/pipeline-template/.pre-commit-config.yaml index a136ace058..e0cf82ab65 100644 --- a/nf_core/pipeline-template/.pre-commit-config.yaml +++ b/nf_core/pipeline-template/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.9.4 + - prettier@3.9.5 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: From 6752f5d326c866eb2507d3f39abde39a3b965a43 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 09:41:07 +0200 Subject: [PATCH 112/135] Update mcr.microsoft.com/devcontainers/miniconda Docker digest to 617c7e4 (#4402) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/build-devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/build-devcontainer/Dockerfile b/.devcontainer/build-devcontainer/Dockerfile index 7104411efd..e1a66c1181 100644 --- a/.devcontainer/build-devcontainer/Dockerfile +++ b/.devcontainer/build-devcontainer/Dockerfile @@ -1,6 +1,6 @@ # devcontainers/miniconda image based on debian (bookworm) # see tags and images: https://mcr.microsoft.com/en-us/artifact/mar/devcontainers/miniconda/tags -FROM mcr.microsoft.com/devcontainers/miniconda@sha256:68c1f6d7904f2d94ce54a43052155348bdcf1800d9f84e8b7fd367c85e688bf1 AS build +FROM mcr.microsoft.com/devcontainers/miniconda@sha256:617c7e42311066ac0bac3b7f0a3647daa9eec70fb8e3aeb8a5b083337a8a8687 AS build # copy this repo at current revision COPY . /root/nfcore-tools/ From 3afcd036201cb9fefe58df9dbe44079cf9ee1fcd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 09:41:22 +0200 Subject: [PATCH 113/135] Update python:3.14-slim Docker digest to cea0e60 (#4403) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 2a296e255f..6a7090ebce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.14-slim@sha256:b877e50bd90de10af8d82c57a022fc2e0dc731c5320d762a27986facfc3355c1 +FROM python:3.14-slim@sha256:cea0e6040540fb2b965b6e7fb5ffa00871e632eef63719f0ea54bca189ce14a6 LABEL authors="phil.ewels@seqera.io,erik.danielsson@scilifelab.se" \ description="Docker image containing requirements for nf-core/tools" From d17c641832951d88175ab63b6c2173eaea09f4af Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 10:38:54 +0200 Subject: [PATCH 114/135] Update dependency prettier to v3.9.6 (#4405) --- .pre-commit-config.yaml | 2 +- nf_core/.pre-commit-prettier-config.yaml | 2 +- nf_core/pipeline-template/.pre-commit-config.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9616009073..26eec9827e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - id: prettier entry: prettier --experimental-cli --write --ignore-unknown --no-cache additional_dependencies: - - prettier@3.9.5 + - prettier@3.9.6 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: diff --git a/nf_core/.pre-commit-prettier-config.yaml b/nf_core/.pre-commit-prettier-config.yaml index 30e0df0c14..5178d5a205 100644 --- a/nf_core/.pre-commit-prettier-config.yaml +++ b/nf_core/.pre-commit-prettier-config.yaml @@ -4,4 +4,4 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.9.5 + - prettier@3.9.6 diff --git a/nf_core/pipeline-template/.pre-commit-config.yaml b/nf_core/pipeline-template/.pre-commit-config.yaml index e0cf82ab65..e9503db161 100644 --- a/nf_core/pipeline-template/.pre-commit-config.yaml +++ b/nf_core/pipeline-template/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: prettier additional_dependencies: - - prettier@3.9.5 + - prettier@3.9.6 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: From e48481be495d215a2fe8de1db92a5420b324ea4f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 08:50:23 +0000 Subject: [PATCH 115/135] Update GitHub Actions (#4404) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/changelog.yml | 2 +- .github/workflows/codspeed.yml | 2 +- .github/workflows/create-lint-wf.yml | 2 +- .github/workflows/create-test-lint-wf-template.yml | 4 ++-- .github/workflows/create-test-wf.yml | 2 +- .github/workflows/deploy-pypi.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/lint-code.yml | 2 +- .github/workflows/nextflow-source-test.yml | 4 ++-- .github/workflows/push_dockerhub.yml | 2 +- .github/workflows/pytest.yml | 4 ++-- .github/workflows/sync.yml | 4 ++-- .github/workflows/test_offline_configs.yml | 4 ++-- .github/workflows/update-template-snapshots.yml | 6 +++--- .github/workflows/update-textual-snapshots.yml | 2 +- .../.github/workflows/download_pipeline.yml | 2 +- nf_core/pipeline-template/.github/workflows/fix_linting.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 4 ++-- nf_core/pipeline-template/.github/workflows/nf-test.yml | 4 ++-- .../.github/workflows/template-version-comment.yml | 2 +- 20 files changed, 29 insertions(+), 29 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index b5c82cec2b..d5186a2e84 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -18,7 +18,7 @@ jobs: reaction: "eyes" stable_branch: "dev" - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index b157d37c6a..74d8113216 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -28,7 +28,7 @@ jobs: name: Run start-up benchmarks runs-on: codspeed-macro steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 name: Check out source-code repository - name: Set up Python diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 5c43f71151..680261427d 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -42,7 +42,7 @@ jobs: export NXF_WORK=$(pwd) # Get the repo code - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out source-code repository # Set up nf-core/tools diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index 1b9ecfe1a1..9ccc7b54dc 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -32,7 +32,7 @@ jobs: all_features: ${{ steps.create_matrix.outputs.matrix }} steps: - name: checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Create Matrix id: create_matrix run: | @@ -56,7 +56,7 @@ jobs: steps: - name: Check out source-code repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Set up Python 3.14 uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index 85f9144f18..54d1e51617 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -41,7 +41,7 @@ jobs: cd create-test-wf export NXF_WORK=$(pwd) - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out source-code repository - name: Set up Python 3.14 diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index 7f8698bc16..6093fb0b5e 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out source-code repository - name: Set up Python 3.14 diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 5a56315586..4c0b2fd2a1 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -19,7 +19,7 @@ jobs: stable_branch: "dev" # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/.github/workflows/lint-code.yml b/.github/workflows/lint-code.yml index fe5c64837a..681c5563a5 100644 --- a/.github/workflows/lint-code.yml +++ b/.github/workflows/lint-code.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Run prek uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2 diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index 465a6510ab..d2e9ac015d 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Check out Nextflow - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: repository: nextflow-io/nextflow path: nextflow @@ -38,7 +38,7 @@ jobs: chmod +x $HOME/.local/bin/nextflow nextflow -version - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out nf-core/tools with: ref: dev diff --git a/.github/workflows/push_dockerhub.yml b/.github/workflows/push_dockerhub.yml index 7123d82ebb..162495c6e8 100644 --- a/.github/workflows/push_dockerhub.yml +++ b/.github/workflows/push_dockerhub.yml @@ -34,7 +34,7 @@ jobs: swap-storage: true - name: Check out code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Set up QEMU for multi-architecture build uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4 diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 1d43675eb2..7a2196e3a7 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -40,7 +40,7 @@ jobs: name: Get test file matrix runs-on: "ubuntu-latest" steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out source-code repository - name: List tests @@ -72,7 +72,7 @@ jobs: cd pytest export NXF_WORK=$(pwd) - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out source-code repository - name: Set up Python ${{ matrix.python-version }} diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index e2acb07ee0..ac8925f807 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -62,12 +62,12 @@ jobs: matrix: ${{fromJson(needs.get-pipelines.outputs.matrix)}} fail-fast: false steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out nf-core/tools with: ref: ${{ github.ref_name }} - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out nf-core/${{ matrix.pipeline }} with: repository: nf-core/${{ matrix.pipeline }} diff --git a/.github/workflows/test_offline_configs.yml b/.github/workflows/test_offline_configs.yml index 61cb532304..1e11f802db 100644 --- a/.github/workflows/test_offline_configs.yml +++ b/.github/workflows/test_offline_configs.yml @@ -53,11 +53,11 @@ jobs: matrix: ${{fromJson(needs.get-pipelines.outputs.matrix)}} fail-fast: false steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out nf-core/tools with: ref: ${{ github.ref_name }} - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 name: Check out nf-core/${{ matrix.pipeline }} with: repository: nf-core/${{ matrix.pipeline }} diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index 74bc47fd11..e32c73b93f 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -22,7 +22,7 @@ jobs: stable_branch: "dev" - name: checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Create Matrix id: create_matrix @@ -43,7 +43,7 @@ jobs: fail-fast: false steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} @@ -145,7 +145,7 @@ jobs: runs-on: ubuntu-latest if: always() && needs.update-snapshots.result != 'skipped' steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index 3a31d597da..40d70e691d 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -17,7 +17,7 @@ jobs: stable_branch: "dev" # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index 73ffac2441..23280b50b8 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -39,7 +39,7 @@ jobs: needs: configure steps: - name: Check out pipeline code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 diff --git a/nf_core/pipeline-template/.github/workflows/fix_linting.yml b/nf_core/pipeline-template/.github/workflows/fix_linting.yml index 829479b105..e417e863a9 100644 --- a/nf_core/pipeline-template/.github/workflows/fix_linting.yml +++ b/nf_core/pipeline-template/.github/workflows/fix_linting.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: # Use the @nf-core-bot token to check out so we can push later - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: token: ${{ secrets.nf_core_bot_auth_token }} diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 8ee7463f34..7f57d35fed 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -11,7 +11,7 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 diff --git a/nf_core/pipeline-template/.github/workflows/nf-test.yml b/nf_core/pipeline-template/.github/workflows/nf-test.yml index 5990330917..865fb218a2 100644 --- a/nf_core/pipeline-template/.github/workflows/nf-test.yml +++ b/nf_core/pipeline-template/.github/workflows/nf-test.yml @@ -41,7 +41,7 @@ jobs: rm -rf ./* || true rm -rf ./.??* || true ls -la ./ - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: fetch-depth: 0 @@ -87,7 +87,7 @@ jobs: TOTAL_SHARDS: ${{ needs.nf-test-changes.outputs.total_shards }} steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: fetch-depth: 0 diff --git a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml index e45cde0576..598d16f117 100644 --- a/nf_core/pipeline-template/.github/workflows/template-version-comment.yml +++ b/nf_core/pipeline-template/.github/workflows/template-version-comment.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out pipeline code - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: ref: ${{ github.event.pull_request.head.sha }} From 6d01b86f376689b29f05f0a5dec6718a6879c0f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 12:29:24 +0200 Subject: [PATCH 116/135] Update actions/setup-python action to v7 (#4401) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/changelog.yml | 4 ++-- .github/workflows/codspeed.yml | 2 +- .github/workflows/create-lint-wf.yml | 2 +- .github/workflows/create-test-lint-wf-template.yml | 2 +- .github/workflows/create-test-wf.yml | 2 +- .github/workflows/deploy-pypi.yml | 2 +- .github/workflows/nextflow-source-test.yml | 2 +- .github/workflows/pytest.yml | 2 +- .github/workflows/sync.yml | 2 +- .github/workflows/update-template-snapshots.yml | 2 +- .github/workflows/update-textual-snapshots.yml | 2 +- nf_core/pipeline-template/.github/actions/nf-test/action.yml | 2 +- .../pipeline-template/.github/workflows/download_pipeline.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index d5186a2e84..8f4242bfe4 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -31,7 +31,7 @@ jobs: PR_NUMBER="${{ github.event.issue.number }}" gh pr checkout $PR_NUMBER - - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" @@ -60,7 +60,7 @@ jobs: echo "changed=$file_changed" >> $GITHUB_OUTPUT - name: Set up Python 3.14 - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 74d8113216..c13facfee6 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -32,7 +32,7 @@ jobs: name: Check out source-code repository - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index 680261427d..f613a66237 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -47,7 +47,7 @@ jobs: # Set up nf-core/tools - name: Set up Python 3.14 - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index 9ccc7b54dc..aa5ed29547 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -59,7 +59,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Set up Python 3.14 - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index 54d1e51617..2e3c321877 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -45,7 +45,7 @@ jobs: name: Check out source-code repository - name: Set up Python 3.14 - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index 6093fb0b5e..2ebd3e12dc 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -17,7 +17,7 @@ jobs: name: Check out source-code repository - name: Set up Python 3.14 - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index d2e9ac015d..ec21e5a264 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -45,7 +45,7 @@ jobs: # Set up nf-core/tools - name: Set up Python 3.14 - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 7a2196e3a7..7b3fea2056 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -76,7 +76,7 @@ jobs: name: Check out source-code repository - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: ${{ matrix.python-version }} token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index ac8925f807..7740311e1a 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -77,7 +77,7 @@ jobs: fetch-depth: "0" - name: Set up Python 3.14 - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index e32c73b93f..9223af6b9b 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -56,7 +56,7 @@ jobs: # Install dependencies and run pytest - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index 40d70e691d..cae2eb29f3 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -37,7 +37,7 @@ jobs: # Install dependencies and run pytest - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/nf_core/pipeline-template/.github/actions/nf-test/action.yml b/nf_core/pipeline-template/.github/actions/nf-test/action.yml index 0d1583b9ef..abda901dd6 100644 --- a/nf_core/pipeline-template/.github/actions/nf-test/action.yml +++ b/nf_core/pipeline-template/.github/actions/nf-test/action.yml @@ -25,7 +25,7 @@ runs: version: "{% raw %}${{ env.NXF_VERSION }}" - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index 23280b50b8..a5750329df 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -47,7 +47,7 @@ jobs: - name: Disk space cleanup uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 - - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" architecture: "x64" diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index 7f57d35fed..f3740cf96a 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -28,7 +28,7 @@ jobs: - name: Install Nextflow uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 - - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: python-version: "3.14" architecture: "x64" From cb0ac1105a11247f485f0364fa800a499165e468 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 14:24:37 +0200 Subject: [PATCH 117/135] Update pre-commit hooks (#4359) Co-authored-by: mashehu --- .pre-commit-config.yaml | 6 +++--- nf_core/pipelines/download/docker.py | 8 +++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 26eec9827e..63fff74030 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.16 + rev: v0.15.22 hooks: - id: ruff-check # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix @@ -36,7 +36,7 @@ repos: tests/pipelines/__snapshots__/.* )$ - repo: https://github.com/pre-commit/mirrors-mypy - rev: "v2.1.0" + rev: "v2.3.0" hooks: - id: mypy args: [--ignore-missing-imports, --scripts-are-modules, -n4] @@ -49,7 +49,7 @@ repos: - types-setuptools - pydantic - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.11.19 + rev: 0.11.30 hooks: - id: uv-lock priority: 20 diff --git a/nf_core/pipelines/download/docker.py b/nf_core/pipelines/download/docker.py index 1b567f5cd9..247a1579ba 100644 --- a/nf_core/pipelines/download/docker.py +++ b/nf_core/pipelines/download/docker.py @@ -287,15 +287,17 @@ def _run_docker_command( # - read lines if there are any, # - check if we should kill it, # - update the progress bar + assert proc.stdout is not None + stdout = proc.stdout lines = [] while True: if self.kill_with_fire: proc.kill() raise KeyboardInterrupt("Docker command was cancelled by user") - rlist, _, _ = select.select([proc.stdout], [], [], 0.1) - if rlist and proc.stdout is not None: - line = proc.stdout.readline() + rlist, _, _ = select.select([stdout], [], [], 0.1) + if rlist: + line = stdout.readline() if line: lines.append(line) self.progress.update(progress_task, current_log=line.strip()) From b03c2306d48fa1f666caf3cdd961975a2f2bb0f6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2026 12:44:56 +0000 Subject: [PATCH 118/135] Update dependency textual to v8.2.7 (#4256) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matthias Hörtenhuber --- .../workflows/update-textual-snapshots.yml | 2 +- pyproject.toml | 2 +- .../test_github_exit_message.svg | 27 +- uv.lock | 2875 +++++++++-------- 4 files changed, 1597 insertions(+), 1309 deletions(-) diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index cae2eb29f3..ec5da6f216 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -52,7 +52,7 @@ jobs: - name: Run pytest to update snapshots id: pytest run: | - uv run python -m pytest tests/pipelines/test_create_app.py --snapshot-update --color=yes --durations=0 -n auto + uv run python -m pytest tests/pipelines/test_create_app.py --snapshot-update --color=yes --durations=0 -n logical continue-on-error: true # indication that the run has finished diff --git a/pyproject.toml b/pyproject.toml index 51f8c4d8ca..b576e68066 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ dependencies = [ "repo2rocrate", "setuptools<81", "tabulate", - "textual==8.2.4", + "textual==8.2.7", "trogon", "pdiff", "ruamel.yaml", diff --git a/tests/pipelines/__snapshots__/test_create_app/test_github_exit_message.svg b/tests/pipelines/__snapshots__/test_create_app/test_github_exit_message.svg index 27b33c8ab0..cfa48a410d 100644 --- a/tests/pipelines/__snapshots__/test_create_app/test_github_exit_message.svg +++ b/tests/pipelines/__snapshots__/test_create_app/test_github_exit_message.svg @@ -42,14 +42,13 @@ .terminal-r8 { fill: #57a5e2 } .terminal-r9 { fill: #ffc473 } .terminal-r10 { fill: #ffffff } -.terminal-r11 { fill: #d2d2d2 } -.terminal-r12 { fill: #345b7a } -.terminal-r13 { fill: #f4bc6e } -.terminal-r14 { fill: #7ae998 } -.terminal-r15 { fill: #55c076;font-weight: bold } -.terminal-r16 { fill: #008139 } -.terminal-r17 { fill: #ffa62b;font-weight: bold } -.terminal-r18 { fill: #495259 } +.terminal-r11 { fill: #345b7a } +.terminal-r12 { fill: #f4bc6e } +.terminal-r13 { fill: #7ae998 } +.terminal-r14 { fill: #55c076;font-weight: bold } +.terminal-r15 { fill: #008139 } +.terminal-r16 { fill: #ffa62b;font-weight: bold } +.terminal-r17 { fill: #495259 } @@ -213,7 +212,7 @@ - + nf-core pipelines create — Create a new pipeline with the nf-core pipeline templa… @@ -244,12 +243,12 @@ git push --all origin -💡 Note the --all flag: this is needed to push all branches to the remote. +💡 Note the --all flag: this is needed to push all branches to the remote. -▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Close  -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Close  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ @@ -264,7 +263,7 @@ - d Toggle dark mode  q Quit  a Toggle all ^p palette + d Toggle dark mode  q Quit  a Toggle all ^p palette diff --git a/uv.lock b/uv.lock index 3b2264a936..1af61632ae 100644 --- a/uv.lock +++ b/uv.lock @@ -10,16 +10,16 @@ resolution-markers = [ [[package]] name = "aiohappyeyeballs" -version = "2.6.1" +version = "2.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/f4/eec0465c2f67b2664688d0240b3212d5196fd89e741df67ddb81f8d35658/aiohappyeyeballs-2.7.1.tar.gz", hash = "sha256:065665c041c42a5938ed220bdcd7230f22527fbec085e1853d2402c8a3615d9d", size = 24757, upload-time = "2026-07-01T17:11:55.501Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, + { url = "https://files.pythonhosted.org/packages/71/43/1947f06babed6b3f1d7f38b0c767f52df66bfb2bc10b468c4a7de9eceff2/aiohappyeyeballs-2.7.1-py3-none-any.whl", hash = "sha256:9243213661e29250eb41368e5daa826fc017156c3b8a11440826b2e3ed376472", size = 15038, upload-time = "2026-07-01T17:11:54.055Z" }, ] [[package]] name = "aiohttp" -version = "3.13.5" +version = "3.14.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -29,112 +29,129 @@ dependencies = [ { name = "frozenlist" }, { name = "multidict" }, { name = "propcache" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/9a/152096d4808df8e4268befa55fba462f440f14beab85e8ad9bf990516918/aiohttp-3.13.5.tar.gz", hash = "sha256:9d98cc980ecc96be6eb4c1994ce35d28d8b1f5e5208a23b421187d1209dbb7d1", size = 7858271, upload-time = "2026-03-31T22:01:03.343Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/85/cebc47ee74d8b408749073a1a46c6fcba13d170dc8af7e61996c6c9394ac/aiohttp-3.13.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:02222e7e233295f40e011c1b00e3b0bd451f22cf853a0304c3595633ee47da4b", size = 750547, upload-time = "2026-03-31T21:56:30.024Z" }, - { url = "https://files.pythonhosted.org/packages/05/98/afd308e35b9d3d8c9ec54c0918f1d722c86dc17ddfec272fcdbcce5a3124/aiohttp-3.13.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bace460460ed20614fa6bc8cb09966c0b8517b8c58ad8046828c6078d25333b5", size = 503535, upload-time = "2026-03-31T21:56:31.935Z" }, - { url = "https://files.pythonhosted.org/packages/6f/4d/926c183e06b09d5270a309eb50fbde7b09782bfd305dec1e800f329834fb/aiohttp-3.13.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f546a4dc1e6a5edbb9fd1fd6ad18134550e096a5a43f4ad74acfbd834fc6670", size = 497830, upload-time = "2026-03-31T21:56:33.654Z" }, - { url = "https://files.pythonhosted.org/packages/e4/d6/f47d1c690f115a5c2a5e8938cce4a232a5be9aac5c5fb2647efcbbbda333/aiohttp-3.13.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c86969d012e51b8e415a8c6ce96f7857d6a87d6207303ab02d5d11ef0cad2274", size = 1682474, upload-time = "2026-03-31T21:56:35.513Z" }, - { url = "https://files.pythonhosted.org/packages/01/44/056fd37b1bb52eac760303e5196acc74d9d546631b035704ae5927f7b4ac/aiohttp-3.13.5-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b6f6cd1560c5fa427e3b6074bb24d2c64e225afbb7165008903bd42e4e33e28a", size = 1655259, upload-time = "2026-03-31T21:56:37.843Z" }, - { url = "https://files.pythonhosted.org/packages/91/9f/78eb1a20c1c28ae02f6a3c0f4d7b0dcc66abce5290cadd53d78ce3084175/aiohttp-3.13.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:636bc362f0c5bbc7372bc3ae49737f9e3030dbce469f0f422c8f38079780363d", size = 1736204, upload-time = "2026-03-31T21:56:39.822Z" }, - { url = "https://files.pythonhosted.org/packages/de/6c/d20d7de23f0b52b8c1d9e2033b2db1ac4dacbb470bb74c56de0f5f86bb4f/aiohttp-3.13.5-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6a7cbeb06d1070f1d14895eeeed4dac5913b22d7b456f2eb969f11f4b3993796", size = 1826198, upload-time = "2026-03-31T21:56:41.378Z" }, - { url = "https://files.pythonhosted.org/packages/2f/86/a6f3ff1fd795f49545a7c74b2c92f62729135d73e7e4055bf74da5a26c82/aiohttp-3.13.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca9ef7517fd7874a1a08970ae88f497bf5c984610caa0bf40bd7e8450852b95", size = 1681329, upload-time = "2026-03-31T21:56:43.374Z" }, - { url = "https://files.pythonhosted.org/packages/fb/68/84cd3dab6b7b4f3e6fe9459a961acb142aaab846417f6e8905110d7027e5/aiohttp-3.13.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:019a67772e034a0e6b9b17c13d0a8fe56ad9fb150fc724b7f3ffd3724288d9e5", size = 1560023, upload-time = "2026-03-31T21:56:45.031Z" }, - { url = "https://files.pythonhosted.org/packages/41/2c/db61b64b0249e30f954a65ab4cb4970ced57544b1de2e3c98ee5dc24165f/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f34ecee82858e41dd217734f0c41a532bd066bcaab636ad830f03a30b2a96f2a", size = 1652372, upload-time = "2026-03-31T21:56:47.075Z" }, - { url = "https://files.pythonhosted.org/packages/25/6f/e96988a6c982d047810c772e28c43c64c300c943b0ed5c1c0c4ce1e1027c/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4eac02d9af4813ee289cd63a361576da36dba57f5a1ab36377bc2600db0cbb73", size = 1662031, upload-time = "2026-03-31T21:56:48.835Z" }, - { url = "https://files.pythonhosted.org/packages/b7/26/a56feace81f3d347b4052403a9d03754a0ab23f7940780dada0849a38c92/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4beac52e9fe46d6abf98b0176a88154b742e878fdf209d2248e99fcdf73cd297", size = 1708118, upload-time = "2026-03-31T21:56:50.833Z" }, - { url = "https://files.pythonhosted.org/packages/78/6e/b6173a8ff03d01d5e1a694bc06764b5dad1df2d4ed8f0ceec12bb3277936/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:c180f480207a9b2475f2b8d8bd7204e47aec952d084b2a2be58a782ffcf96074", size = 1548667, upload-time = "2026-03-31T21:56:52.81Z" }, - { url = "https://files.pythonhosted.org/packages/16/13/13296ffe2c132d888b3fe2c195c8b9c0c24c89c3fa5cc2c44464dc23b22e/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2837fb92951564d6339cedae4a7231692aa9f73cbc4fb2e04263b96844e03b4e", size = 1724490, upload-time = "2026-03-31T21:56:54.541Z" }, - { url = "https://files.pythonhosted.org/packages/7a/b4/1f1c287f4a79782ef36e5a6e62954c85343bc30470d862d30bd5f26c9fa2/aiohttp-3.13.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9010032a0b9710f58012a1e9c222528763d860ba2ee1422c03473eab47703e7", size = 1667109, upload-time = "2026-03-31T21:56:56.21Z" }, - { url = "https://files.pythonhosted.org/packages/ef/42/8461a2aaf60a8f4ea4549a4056be36b904b0eb03d97ca9a8a2604681a500/aiohttp-3.13.5-cp310-cp310-win32.whl", hash = "sha256:7c4b6668b2b2b9027f209ddf647f2a4407784b5d88b8be4efcc72036f365baf9", size = 439478, upload-time = "2026-03-31T21:56:58.292Z" }, - { url = "https://files.pythonhosted.org/packages/e5/71/06956304cb5ee439dfe8d86e1b2e70088bd88ed1ced1f42fb29e5d855f0e/aiohttp-3.13.5-cp310-cp310-win_amd64.whl", hash = "sha256:cd3db5927bf9167d5a6157ddb2f036f6b6b0ad001ac82355d43e97a4bde76d76", size = 462047, upload-time = "2026-03-31T21:57:00.257Z" }, - { url = "https://files.pythonhosted.org/packages/d6/f5/a20c4ac64aeaef1679e25c9983573618ff765d7aa829fa2b84ae7573169e/aiohttp-3.13.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7ab7229b6f9b5c1ba4910d6c41a9eb11f543eadb3f384df1b4c293f4e73d44d6", size = 757513, upload-time = "2026-03-31T21:57:02.146Z" }, - { url = "https://files.pythonhosted.org/packages/75/0a/39fa6c6b179b53fcb3e4b3d2b6d6cad0180854eda17060c7218540102bef/aiohttp-3.13.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8f14c50708bb156b3a3ca7230b3d820199d56a48e3af76fa21c2d6087190fe3d", size = 506748, upload-time = "2026-03-31T21:57:04.275Z" }, - { url = "https://files.pythonhosted.org/packages/87/ec/e38ce072e724fd7add6243613f8d1810da084f54175353d25ccf9f9c7e5a/aiohttp-3.13.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7d2f8616f0ff60bd332022279011776c3ac0faa0f1b463f7bb12326fbc97a1c", size = 501673, upload-time = "2026-03-31T21:57:06.208Z" }, - { url = "https://files.pythonhosted.org/packages/ba/ba/3bc7525d7e2beaa11b309a70d48b0d3cfc3c2089ec6a7d0820d59c657053/aiohttp-3.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2567b72e1ffc3ab25510db43f355b29eeada56c0a622e58dcdb19530eb0a3cb", size = 1763757, upload-time = "2026-03-31T21:57:07.882Z" }, - { url = "https://files.pythonhosted.org/packages/5e/ab/e87744cf18f1bd78263aba24924d4953b41086bd3a31d22452378e9028a0/aiohttp-3.13.5-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fb0540c854ac9c0c5ad495908fdfd3e332d553ec731698c0e29b1877ba0d2ec6", size = 1720152, upload-time = "2026-03-31T21:57:09.946Z" }, - { url = "https://files.pythonhosted.org/packages/6b/f3/ed17a6f2d742af17b50bae2d152315ed1b164b07a5fd5cc1754d99e4dfa5/aiohttp-3.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c9883051c6972f58bfc4ebb2116345ee2aa151178e99c3f2b2bbe2af712abd13", size = 1818010, upload-time = "2026-03-31T21:57:12.157Z" }, - { url = "https://files.pythonhosted.org/packages/53/06/ecbc63dc937192e2a5cb46df4d3edb21deb8225535818802f210a6ea5816/aiohttp-3.13.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2294172ce08a82fb7c7273485895de1fa1186cc8294cfeb6aef4af42ad261174", size = 1907251, upload-time = "2026-03-31T21:57:14.023Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a5/0521aa32c1ddf3aa1e71dcc466be0b7db2771907a13f18cddaa45967d97b/aiohttp-3.13.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3a807cabd5115fb55af198b98178997a5e0e57dead43eb74a93d9c07d6d4a7dc", size = 1759969, upload-time = "2026-03-31T21:57:16.146Z" }, - { url = "https://files.pythonhosted.org/packages/f6/78/a38f8c9105199dd3b9706745865a8a59d0041b6be0ca0cc4b2ccf1bab374/aiohttp-3.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aa6d0d932e0f39c02b80744273cd5c388a2d9bc07760a03164f229c8e02662f6", size = 1616871, upload-time = "2026-03-31T21:57:17.856Z" }, - { url = "https://files.pythonhosted.org/packages/6f/41/27392a61ead8ab38072105c71aa44ff891e71653fe53d576a7067da2b4e8/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:60869c7ac4aaabe7110f26499f3e6e5696eae98144735b12a9c3d9eae2b51a49", size = 1739844, upload-time = "2026-03-31T21:57:19.679Z" }, - { url = "https://files.pythonhosted.org/packages/6e/55/5564e7ae26d94f3214250009a0b1c65a0c6af4bf88924ccb6fdab901de28/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:26d2f8546f1dfa75efa50c3488215a903c0168d253b75fba4210f57ab77a0fb8", size = 1731969, upload-time = "2026-03-31T21:57:22.006Z" }, - { url = "https://files.pythonhosted.org/packages/6d/c5/705a3929149865fc941bcbdd1047b238e4a72bcb215a9b16b9d7a2e8d992/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1162a1492032c82f14271e831c8f4b49f2b6078f4f5fc74de2c912fa225d51d", size = 1795193, upload-time = "2026-03-31T21:57:24.256Z" }, - { url = "https://files.pythonhosted.org/packages/a6/19/edabed62f718d02cff7231ca0db4ef1c72504235bc467f7b67adb1679f48/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:8b14eb3262fad0dc2f89c1a43b13727e709504972186ff6a99a3ecaa77102b6c", size = 1606477, upload-time = "2026-03-31T21:57:26.364Z" }, - { url = "https://files.pythonhosted.org/packages/de/fc/76f80ef008675637d88d0b21584596dc27410a990b0918cb1e5776545b5b/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ca9ac61ac6db4eb6c2a0cd1d0f7e1357647b638ccc92f7e9d8d133e71ed3c6ac", size = 1813198, upload-time = "2026-03-31T21:57:28.316Z" }, - { url = "https://files.pythonhosted.org/packages/e5/67/5b3ac26b80adb20ea541c487f73730dc8fa107d632c998f25bbbab98fcda/aiohttp-3.13.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7996023b2ed59489ae4762256c8516df9820f751cf2c5da8ed2fb20ee50abab3", size = 1752321, upload-time = "2026-03-31T21:57:30.549Z" }, - { url = "https://files.pythonhosted.org/packages/88/06/e4a2e49255ea23fa4feeb5ab092d90240d927c15e47b5b5c48dff5a9ce29/aiohttp-3.13.5-cp311-cp311-win32.whl", hash = "sha256:77dfa48c9f8013271011e51c00f8ada19851f013cde2c48fca1ba5e0caf5bb06", size = 439069, upload-time = "2026-03-31T21:57:32.388Z" }, - { url = "https://files.pythonhosted.org/packages/c0/43/8c7163a596dab4f8be12c190cf467a1e07e4734cf90eebb39f7f5d53fc6a/aiohttp-3.13.5-cp311-cp311-win_amd64.whl", hash = "sha256:d3a4834f221061624b8887090637db9ad4f61752001eae37d56c52fddade2dc8", size = 462859, upload-time = "2026-03-31T21:57:34.455Z" }, - { url = "https://files.pythonhosted.org/packages/be/6f/353954c29e7dcce7cf00280a02c75f30e133c00793c7a2ed3776d7b2f426/aiohttp-3.13.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:023ecba036ddd840b0b19bf195bfae970083fd7024ce1ac22e9bba90464620e9", size = 748876, upload-time = "2026-03-31T21:57:36.319Z" }, - { url = "https://files.pythonhosted.org/packages/f5/1b/428a7c64687b3b2e9cd293186695affc0e1e54a445d0361743b231f11066/aiohttp-3.13.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15c933ad7920b7d9a20de151efcd05a6e38302cbf0e10c9b2acb9a42210a2416", size = 499557, upload-time = "2026-03-31T21:57:38.236Z" }, - { url = "https://files.pythonhosted.org/packages/29/47/7be41556bfbb6917069d6a6634bb7dd5e163ba445b783a90d40f5ac7e3a7/aiohttp-3.13.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab2899f9fa2f9f741896ebb6fa07c4c883bfa5c7f2ddd8cf2aafa86fa981b2d2", size = 500258, upload-time = "2026-03-31T21:57:39.923Z" }, - { url = "https://files.pythonhosted.org/packages/67/84/c9ecc5828cb0b3695856c07c0a6817a99d51e2473400f705275a2b3d9239/aiohttp-3.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60eaa2d440cd4707696b52e40ed3e2b0f73f65be07fd0ef23b6b539c9c0b0b4", size = 1749199, upload-time = "2026-03-31T21:57:41.938Z" }, - { url = "https://files.pythonhosted.org/packages/f0/d3/3c6d610e66b495657622edb6ae7c7fd31b2e9086b4ec50b47897ad6042a9/aiohttp-3.13.5-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:55b3bdd3292283295774ab585160c4004f4f2f203946997f49aac032c84649e9", size = 1721013, upload-time = "2026-03-31T21:57:43.904Z" }, - { url = "https://files.pythonhosted.org/packages/49/a0/24409c12217456df0bae7babe3b014e460b0b38a8e60753d6cb339f6556d/aiohttp-3.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c2b2355dc094e5f7d45a7bb262fe7207aa0460b37a0d87027dcf21b5d890e7d5", size = 1781501, upload-time = "2026-03-31T21:57:46.285Z" }, - { url = "https://files.pythonhosted.org/packages/98/9d/b65ec649adc5bccc008b0957a9a9c691070aeac4e41cea18559fef49958b/aiohttp-3.13.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b38765950832f7d728297689ad78f5f2cf79ff82487131c4d26fe6ceecdc5f8e", size = 1878981, upload-time = "2026-03-31T21:57:48.734Z" }, - { url = "https://files.pythonhosted.org/packages/57/d8/8d44036d7eb7b6a8ec4c5494ea0c8c8b94fbc0ed3991c1a7adf230df03bf/aiohttp-3.13.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b18f31b80d5a33661e08c89e202edabf1986e9b49c42b4504371daeaa11b47c1", size = 1767934, upload-time = "2026-03-31T21:57:51.171Z" }, - { url = "https://files.pythonhosted.org/packages/31/04/d3f8211f273356f158e3464e9e45484d3fb8c4ce5eb2f6fe9405c3273983/aiohttp-3.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:33add2463dde55c4f2d9635c6ab33ce154e5ecf322bd26d09af95c5f81cfa286", size = 1566671, upload-time = "2026-03-31T21:57:53.326Z" }, - { url = "https://files.pythonhosted.org/packages/41/db/073e4ebe00b78e2dfcacff734291651729a62953b48933d765dc513bf798/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:327cc432fdf1356fb4fbc6fe833ad4e9f6aacb71a8acaa5f1855e4b25910e4a9", size = 1705219, upload-time = "2026-03-31T21:57:55.385Z" }, - { url = "https://files.pythonhosted.org/packages/48/45/7dfba71a2f9fd97b15c95c06819de7eb38113d2cdb6319669195a7d64270/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7c35b0bf0b48a70b4cb4fc5d7bed9b932532728e124874355de1a0af8ec4bc88", size = 1743049, upload-time = "2026-03-31T21:57:57.341Z" }, - { url = "https://files.pythonhosted.org/packages/18/71/901db0061e0f717d226386a7f471bb59b19566f2cae5f0d93874b017271f/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:df23d57718f24badef8656c49743e11a89fd6f5358fa8a7b96e728fda2abf7d3", size = 1749557, upload-time = "2026-03-31T21:57:59.626Z" }, - { url = "https://files.pythonhosted.org/packages/08/d5/41eebd16066e59cd43728fe74bce953d7402f2b4ddfdfef2c0e9f17ca274/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:02e048037a6501a5ec1f6fc9736135aec6eb8a004ce48838cb951c515f32c80b", size = 1558931, upload-time = "2026-03-31T21:58:01.972Z" }, - { url = "https://files.pythonhosted.org/packages/30/e6/4a799798bf05740e66c3a1161079bda7a3dd8e22ca392481d7a7f9af82a6/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31cebae8b26f8a615d2b546fee45d5ffb76852ae6450e2a03f42c9102260d6fe", size = 1774125, upload-time = "2026-03-31T21:58:04.007Z" }, - { url = "https://files.pythonhosted.org/packages/84/63/7749337c90f92bc2cb18f9560d67aa6258c7060d1397d21529b8004fcf6f/aiohttp-3.13.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:888e78eb5ca55a615d285c3c09a7a91b42e9dd6fc699b166ebd5dee87c9ccf14", size = 1732427, upload-time = "2026-03-31T21:58:06.337Z" }, - { url = "https://files.pythonhosted.org/packages/98/de/cf2f44ff98d307e72fb97d5f5bbae3bfcb442f0ea9790c0bf5c5c2331404/aiohttp-3.13.5-cp312-cp312-win32.whl", hash = "sha256:8bd3ec6376e68a41f9f95f5ed170e2fcf22d4eb27a1f8cb361d0508f6e0557f3", size = 433534, upload-time = "2026-03-31T21:58:08.712Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ca/eadf6f9c8fa5e31d40993e3db153fb5ed0b11008ad5d9de98a95045bed84/aiohttp-3.13.5-cp312-cp312-win_amd64.whl", hash = "sha256:110e448e02c729bcebb18c60b9214a87ba33bac4a9fa5e9a5f139938b56c6cb1", size = 460446, upload-time = "2026-03-31T21:58:10.945Z" }, - { url = "https://files.pythonhosted.org/packages/78/e9/d76bf503005709e390122d34e15256b88f7008e246c4bdbe915cd4f1adce/aiohttp-3.13.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5029cc80718bbd545123cd8fe5d15025eccaaaace5d0eeec6bd556ad6163d61", size = 742930, upload-time = "2026-03-31T21:58:13.155Z" }, - { url = "https://files.pythonhosted.org/packages/57/00/4b7b70223deaebd9bb85984d01a764b0d7bd6526fcdc73cca83bcbe7243e/aiohttp-3.13.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4bb6bf5811620003614076bdc807ef3b5e38244f9d25ca5fe888eaccea2a9832", size = 496927, upload-time = "2026-03-31T21:58:15.073Z" }, - { url = "https://files.pythonhosted.org/packages/9c/f5/0fb20fb49f8efdcdce6cd8127604ad2c503e754a8f139f5e02b01626523f/aiohttp-3.13.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a84792f8631bf5a94e52d9cc881c0b824ab42717165a5579c760b830d9392ac9", size = 497141, upload-time = "2026-03-31T21:58:17.009Z" }, - { url = "https://files.pythonhosted.org/packages/3b/86/b7c870053e36a94e8951b803cb5b909bfbc9b90ca941527f5fcafbf6b0fa/aiohttp-3.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:57653eac22c6a4c13eb22ecf4d673d64a12f266e72785ab1c8b8e5940d0e8090", size = 1732476, upload-time = "2026-03-31T21:58:18.925Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e5/4e161f84f98d80c03a238671b4136e6530453d65262867d989bbe78244d0/aiohttp-3.13.5-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5e5f7debc7a57af53fdf5c5009f9391d9f4c12867049d509bf7bb164a6e295b", size = 1706507, upload-time = "2026-03-31T21:58:21.094Z" }, - { url = "https://files.pythonhosted.org/packages/d4/56/ea11a9f01518bd5a2a2fcee869d248c4b8a0cfa0bb13401574fa31adf4d4/aiohttp-3.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c719f65bebcdf6716f10e9eff80d27567f7892d8988c06de12bbbd39307c6e3a", size = 1773465, upload-time = "2026-03-31T21:58:23.159Z" }, - { url = "https://files.pythonhosted.org/packages/eb/40/333ca27fb74b0383f17c90570c748f7582501507307350a79d9f9f3c6eb1/aiohttp-3.13.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d97f93fdae594d886c5a866636397e2bcab146fd7a132fd6bb9ce182224452f8", size = 1873523, upload-time = "2026-03-31T21:58:25.59Z" }, - { url = "https://files.pythonhosted.org/packages/f0/d2/e2f77eef1acb7111405433c707dc735e63f67a56e176e72e9e7a2cd3f493/aiohttp-3.13.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3df334e39d4c2f899a914f1dba283c1aadc311790733f705182998c6f7cae665", size = 1754113, upload-time = "2026-03-31T21:58:27.624Z" }, - { url = "https://files.pythonhosted.org/packages/fb/56/3f653d7f53c89669301ec9e42c95233e2a0c0a6dd051269e6e678db4fdb0/aiohttp-3.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fe6970addfea9e5e081401bcbadf865d2b6da045472f58af08427e108d618540", size = 1562351, upload-time = "2026-03-31T21:58:29.918Z" }, - { url = "https://files.pythonhosted.org/packages/ec/a6/9b3e91eb8ae791cce4ee736da02211c85c6f835f1bdfac0594a8a3b7018c/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7becdf835feff2f4f335d7477f121af787e3504b48b449ff737afb35869ba7bb", size = 1693205, upload-time = "2026-03-31T21:58:32.214Z" }, - { url = "https://files.pythonhosted.org/packages/98/fc/bfb437a99a2fcebd6b6eaec609571954de2ed424f01c352f4b5504371dd3/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:676e5651705ad5d8a70aeb8eb6936c436d8ebbd56e63436cb7dd9bb36d2a9a46", size = 1730618, upload-time = "2026-03-31T21:58:34.728Z" }, - { url = "https://files.pythonhosted.org/packages/e4/b6/c8534862126191a034f68153194c389addc285a0f1347d85096d349bbc15/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:9b16c653d38eb1a611cc898c41e76859ca27f119d25b53c12875fd0474ae31a8", size = 1745185, upload-time = "2026-03-31T21:58:36.909Z" }, - { url = "https://files.pythonhosted.org/packages/0b/93/4ca8ee2ef5236e2707e0fd5fecb10ce214aee1ff4ab307af9c558bda3b37/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:999802d5fa0389f58decd24b537c54aa63c01c3219ce17d1214cbda3c2b22d2d", size = 1557311, upload-time = "2026-03-31T21:58:39.38Z" }, - { url = "https://files.pythonhosted.org/packages/57/ae/76177b15f18c5f5d094f19901d284025db28eccc5ae374d1d254181d33f4/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ec707059ee75732b1ba130ed5f9580fe10ff75180c812bc267ded039db5128c6", size = 1773147, upload-time = "2026-03-31T21:58:41.476Z" }, - { url = "https://files.pythonhosted.org/packages/01/a4/62f05a0a98d88af59d93b7fcac564e5f18f513cb7471696ac286db970d6a/aiohttp-3.13.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d6d44a5b48132053c2f6cd5c8cb14bc67e99a63594e336b0f2af81e94d5530c", size = 1730356, upload-time = "2026-03-31T21:58:44.049Z" }, - { url = "https://files.pythonhosted.org/packages/e4/85/fc8601f59dfa8c9523808281f2da571f8b4699685f9809a228adcc90838d/aiohttp-3.13.5-cp313-cp313-win32.whl", hash = "sha256:329f292ed14d38a6c4c435e465f48bebb47479fd676a0411936cc371643225cc", size = 432637, upload-time = "2026-03-31T21:58:46.167Z" }, - { url = "https://files.pythonhosted.org/packages/c0/1b/ac685a8882896acf0f6b31d689e3792199cfe7aba37969fa91da63a7fa27/aiohttp-3.13.5-cp313-cp313-win_amd64.whl", hash = "sha256:69f571de7500e0557801c0b51f4780482c0ec5fe2ac851af5a92cfce1af1cb83", size = 458896, upload-time = "2026-03-31T21:58:48.119Z" }, - { url = "https://files.pythonhosted.org/packages/5d/ce/46572759afc859e867a5bc8ec3487315869013f59281ce61764f76d879de/aiohttp-3.13.5-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:eb4639f32fd4a9904ab8fb45bf3383ba71137f3d9d4ba25b3b3f3109977c5b8c", size = 745721, upload-time = "2026-03-31T21:58:50.229Z" }, - { url = "https://files.pythonhosted.org/packages/13/fe/8a2efd7626dbe6049b2ef8ace18ffda8a4dfcbe1bcff3ac30c0c7575c20b/aiohttp-3.13.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:7e5dc4311bd5ac493886c63cbf76ab579dbe4641268e7c74e48e774c74b6f2be", size = 497663, upload-time = "2026-03-31T21:58:52.232Z" }, - { url = "https://files.pythonhosted.org/packages/9b/91/cc8cc78a111826c54743d88651e1687008133c37e5ee615fee9b57990fac/aiohttp-3.13.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:756c3c304d394977519824449600adaf2be0ccee76d206ee339c5e76b70ded25", size = 499094, upload-time = "2026-03-31T21:58:54.566Z" }, - { url = "https://files.pythonhosted.org/packages/0a/33/a8362cb15cf16a3af7e86ed11962d5cd7d59b449202dc576cdc731310bde/aiohttp-3.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecc26751323224cf8186efcf7fbcbc30f4e1d8c7970659daf25ad995e4032a56", size = 1726701, upload-time = "2026-03-31T21:58:56.864Z" }, - { url = "https://files.pythonhosted.org/packages/45/0c/c091ac5c3a17114bd76cbf85d674650969ddf93387876cf67f754204bd77/aiohttp-3.13.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10a75acfcf794edf9d8db50e5a7ec5fc818b2a8d3f591ce93bc7b1210df016d2", size = 1683360, upload-time = "2026-03-31T21:58:59.072Z" }, - { url = "https://files.pythonhosted.org/packages/23/73/bcee1c2b79bc275e964d1446c55c54441a461938e70267c86afaae6fba27/aiohttp-3.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f7a18f258d124cd678c5fe072fe4432a4d5232b0657fca7c1847f599233c83a", size = 1773023, upload-time = "2026-03-31T21:59:01.776Z" }, - { url = "https://files.pythonhosted.org/packages/c7/ef/720e639df03004fee2d869f771799d8c23046dec47d5b81e396c7cda583a/aiohttp-3.13.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:df6104c009713d3a89621096f3e3e88cc323fd269dbd7c20afe18535094320be", size = 1853795, upload-time = "2026-03-31T21:59:04.568Z" }, - { url = "https://files.pythonhosted.org/packages/bd/c9/989f4034fb46841208de7aeeac2c6d8300745ab4f28c42f629ba77c2d916/aiohttp-3.13.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:241a94f7de7c0c3b616627aaad530fe2cb620084a8b144d3be7b6ecfe95bae3b", size = 1730405, upload-time = "2026-03-31T21:59:07.221Z" }, - { url = "https://files.pythonhosted.org/packages/ce/75/ee1fd286ca7dc599d824b5651dad7b3be7ff8d9a7e7b3fe9820d9180f7db/aiohttp-3.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c974fb66180e58709b6fc402846f13791240d180b74de81d23913abe48e96d94", size = 1558082, upload-time = "2026-03-31T21:59:09.484Z" }, - { url = "https://files.pythonhosted.org/packages/c3/20/1e9e6650dfc436340116b7aa89ff8cb2bbdf0abc11dfaceaad8f74273a10/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6e27ea05d184afac78aabbac667450c75e54e35f62238d44463131bd3f96753d", size = 1692346, upload-time = "2026-03-31T21:59:12.068Z" }, - { url = "https://files.pythonhosted.org/packages/d8/40/8ebc6658d48ea630ac7903912fe0dd4e262f0e16825aa4c833c56c9f1f56/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a79a6d399cef33a11b6f004c67bb07741d91f2be01b8d712d52c75711b1e07c7", size = 1698891, upload-time = "2026-03-31T21:59:14.552Z" }, - { url = "https://files.pythonhosted.org/packages/d8/78/ea0ae5ec8ba7a5c10bdd6e318f1ba5e76fcde17db8275188772afc7917a4/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c632ce9c0b534fbe25b52c974515ed674937c5b99f549a92127c85f771a78772", size = 1742113, upload-time = "2026-03-31T21:59:17.068Z" }, - { url = "https://files.pythonhosted.org/packages/8a/66/9d308ed71e3f2491be1acb8769d96c6f0c47d92099f3bc9119cada27b357/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:fceedde51fbd67ee2bcc8c0b33d0126cc8b51ef3bbde2f86662bd6d5a6f10ec5", size = 1553088, upload-time = "2026-03-31T21:59:19.541Z" }, - { url = "https://files.pythonhosted.org/packages/da/a6/6cc25ed8dfc6e00c90f5c6d126a98e2cf28957ad06fa1036bd34b6f24a2c/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f92995dfec9420bb69ae629abf422e516923ba79ba4403bc750d94fb4a6c68c1", size = 1757976, upload-time = "2026-03-31T21:59:22.311Z" }, - { url = "https://files.pythonhosted.org/packages/c1/2b/cce5b0ffe0de99c83e5e36d8f828e4161e415660a9f3e58339d07cce3006/aiohttp-3.13.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:20ae0ff08b1f2c8788d6fb85afcb798654ae6ba0b747575f8562de738078457b", size = 1712444, upload-time = "2026-03-31T21:59:24.635Z" }, - { url = "https://files.pythonhosted.org/packages/6c/cf/9e1795b4160c58d29421eafd1a69c6ce351e2f7c8d3c6b7e4ca44aea1a5b/aiohttp-3.13.5-cp314-cp314-win32.whl", hash = "sha256:b20df693de16f42b2472a9c485e1c948ee55524786a0a34345511afdd22246f3", size = 438128, upload-time = "2026-03-31T21:59:27.291Z" }, - { url = "https://files.pythonhosted.org/packages/22/4d/eaedff67fc805aeba4ba746aec891b4b24cebb1a7d078084b6300f79d063/aiohttp-3.13.5-cp314-cp314-win_amd64.whl", hash = "sha256:f85c6f327bf0b8c29da7d93b1cabb6363fb5e4e160a32fa241ed2dce21b73162", size = 464029, upload-time = "2026-03-31T21:59:29.429Z" }, - { url = "https://files.pythonhosted.org/packages/79/11/c27d9332ee20d68dd164dc12a6ecdef2e2e35ecc97ed6cf0d2442844624b/aiohttp-3.13.5-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:1efb06900858bb618ff5cee184ae2de5828896c448403d51fb633f09e109be0a", size = 778758, upload-time = "2026-03-31T21:59:31.547Z" }, - { url = "https://files.pythonhosted.org/packages/04/fb/377aead2e0a3ba5f09b7624f702a964bdf4f08b5b6728a9799830c80041e/aiohttp-3.13.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:fee86b7c4bd29bdaf0d53d14739b08a106fdda809ca5fe032a15f52fae5fe254", size = 512883, upload-time = "2026-03-31T21:59:34.098Z" }, - { url = "https://files.pythonhosted.org/packages/bb/a6/aa109a33671f7a5d3bd78b46da9d852797c5e665bfda7d6b373f56bff2ec/aiohttp-3.13.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:20058e23909b9e65f9da62b396b77dfa95965cbe840f8def6e572538b1d32e36", size = 516668, upload-time = "2026-03-31T21:59:36.497Z" }, - { url = "https://files.pythonhosted.org/packages/79/b3/ca078f9f2fa9563c36fb8ef89053ea2bb146d6f792c5104574d49d8acb63/aiohttp-3.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cf20a8d6868cb15a73cab329ffc07291ba8c22b1b88176026106ae39aa6df0f", size = 1883461, upload-time = "2026-03-31T21:59:38.723Z" }, - { url = "https://files.pythonhosted.org/packages/b7/e3/a7ad633ca1ca497b852233a3cce6906a56c3225fb6d9217b5e5e60b7419d/aiohttp-3.13.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:330f5da04c987f1d5bdb8ae189137c77139f36bd1cb23779ca1a354a4b027800", size = 1747661, upload-time = "2026-03-31T21:59:41.187Z" }, - { url = "https://files.pythonhosted.org/packages/33/b9/cd6fe579bed34a906d3d783fe60f2fa297ef55b27bb4538438ee49d4dc41/aiohttp-3.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f1cbf0c7926d315c3c26c2da41fd2b5d2fe01ac0e157b78caefc51a782196cf", size = 1863800, upload-time = "2026-03-31T21:59:43.84Z" }, - { url = "https://files.pythonhosted.org/packages/c0/3f/2c1e2f5144cefa889c8afd5cf431994c32f3b29da9961698ff4e3811b79a/aiohttp-3.13.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:53fc049ed6390d05423ba33103ded7281fe897cf97878f369a527070bd95795b", size = 1958382, upload-time = "2026-03-31T21:59:46.187Z" }, - { url = "https://files.pythonhosted.org/packages/66/1d/f31ec3f1013723b3babe3609e7f119c2c2fb6ef33da90061a705ef3e1bc8/aiohttp-3.13.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:898703aa2667e3c5ca4c54ca36cd73f58b7a38ef87a5606414799ebce4d3fd3a", size = 1803724, upload-time = "2026-03-31T21:59:48.656Z" }, - { url = "https://files.pythonhosted.org/packages/0e/b4/57712dfc6f1542f067daa81eb61da282fab3e6f1966fca25db06c4fc62d5/aiohttp-3.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0494a01ca9584eea1e5fbd6d748e61ecff218c51b576ee1999c23db7066417d8", size = 1640027, upload-time = "2026-03-31T21:59:51.284Z" }, - { url = "https://files.pythonhosted.org/packages/25/3c/734c878fb43ec083d8e31bf029daae1beafeae582d1b35da234739e82ee7/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6cf81fe010b8c17b09495cbd15c1d35afbc8fb405c0c9cf4738e5ae3af1d65be", size = 1806644, upload-time = "2026-03-31T21:59:53.753Z" }, - { url = "https://files.pythonhosted.org/packages/20/a5/f671e5cbec1c21d044ff3078223f949748f3a7f86b14e34a365d74a5d21f/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:c564dd5f09ddc9d8f2c2d0a301cd30a79a2cc1b46dd1a73bef8f0038863d016b", size = 1791630, upload-time = "2026-03-31T21:59:56.239Z" }, - { url = "https://files.pythonhosted.org/packages/0b/63/fb8d0ad63a0b8a99be97deac8c04dacf0785721c158bdf23d679a87aa99e/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2994be9f6e51046c4f864598fd9abeb4fba6e88f0b2152422c9666dcd4aea9c6", size = 1809403, upload-time = "2026-03-31T21:59:59.103Z" }, - { url = "https://files.pythonhosted.org/packages/59/0c/bfed7f30662fcf12206481c2aac57dedee43fe1c49275e85b3a1e1742294/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:157826e2fa245d2ef46c83ea8a5faf77ca19355d278d425c29fda0beb3318037", size = 1634924, upload-time = "2026-03-31T22:00:02.116Z" }, - { url = "https://files.pythonhosted.org/packages/17/d6/fd518d668a09fd5a3319ae5e984d4d80b9a4b3df4e21c52f02251ef5a32e/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:a8aca50daa9493e9e13c0f566201a9006f080e7c50e5e90d0b06f53146a54500", size = 1836119, upload-time = "2026-03-31T22:00:04.756Z" }, - { url = "https://files.pythonhosted.org/packages/78/b7/15fb7a9d52e112a25b621c67b69c167805cb1f2ab8f1708a5c490d1b52fe/aiohttp-3.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3b13560160d07e047a93f23aaa30718606493036253d5430887514715b67c9d9", size = 1772072, upload-time = "2026-03-31T22:00:07.494Z" }, - { url = "https://files.pythonhosted.org/packages/7e/df/57ba7f0c4a553fc2bd8b6321df236870ec6fd64a2a473a8a13d4f733214e/aiohttp-3.13.5-cp314-cp314t-win32.whl", hash = "sha256:9a0f4474b6ea6818b41f82172d799e4b3d29e22c2c520ce4357856fced9af2f8", size = 471819, upload-time = "2026-03-31T22:00:10.277Z" }, - { url = "https://files.pythonhosted.org/packages/62/29/2f8418269e46454a26171bfdd6a055d74febf32234e474930f2f60a17145/aiohttp-3.13.5-cp314-cp314t-win_amd64.whl", hash = "sha256:18a2f6c1182c51baa1d28d68fea51513cb2a76612f038853c0ad3c145423d3d9", size = 505441, upload-time = "2026-03-31T22:00:12.791Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/1d/cc/58f26f118d8099f84e009ce560b9148a3f803e63fa8473b57feb67241875/aiohttp-3.14.2.tar.gz", hash = "sha256:f96821eb2ae2f12b0dfa799eafbf221f5621a9220b457b4744a269a63a5f3a6c", size = 7969860, upload-time = "2026-07-20T19:53:26.881Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/37/6a24e23d559bc2d042287cee15b4a6e61b46f844d2b3c96832483f854a4a/aiohttp-3.14.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ceb77c159b2b4c1a179b96a26af36bcaa68eb79c393ec4f569386a69d013cbe9", size = 765793, upload-time = "2026-07-20T19:49:37.707Z" }, + { url = "https://files.pythonhosted.org/packages/dc/14/23aa28408805efe6adc0e97048f5cd6028a2a3036d237038f45d10dc05a6/aiohttp-3.14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3f3381f81bc1c6cbe160b2a3708d39d05014329118e6b648b95edc841eeeebd4", size = 517440, upload-time = "2026-07-20T19:49:40.182Z" }, + { url = "https://files.pythonhosted.org/packages/24/2d/7fc2d359d6702ce5299cd865ec2c70dad2fd8c1b3901bc79f83e3c61c395/aiohttp-3.14.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:483b6f964bbbdaa99a0cd7def631208c44e39d243b95cff23ebc812db8a80e03", size = 515306, upload-time = "2026-07-20T19:49:41.818Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f0/fd9c7019bdfba5529c9a697621a757f0cfd92787595a04a9252923b097fc/aiohttp-3.14.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc056948b7a8a40484b4bbc69923fa25cddd80cbc5f236a3a22ad2f836baeed2", size = 1708602, upload-time = "2026-07-20T19:49:43.351Z" }, + { url = "https://files.pythonhosted.org/packages/3d/6d/8de300d792a3b91a94533a626a835c32cda69189209ae539bebaadba88ad/aiohttp-3.14.2-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:135570f5b470c72c4988a58986f1f847ad336721f77fcc18fda8472bd3bbe3db", size = 1673881, upload-time = "2026-07-20T19:49:44.753Z" }, + { url = "https://files.pythonhosted.org/packages/65/27/37559302e4f03e343f549ff1628295c20fb0298d603e40193db2f25f5153/aiohttp-3.14.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ee5bdd7933c653e43ef8d720704a4e228e4927121f2f5f598b7efe6a4c18633a", size = 1766985, upload-time = "2026-07-20T19:49:46.464Z" }, + { url = "https://files.pythonhosted.org/packages/df/55/29cc3691fa0bb1334352bcb61ba5f256396fd6a0603cf321b8c29bb7e1fe/aiohttp-3.14.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0baed2a2367a28456b612f4c3fd28bb86b00fadfb6454e706d8f65c21636bfd7", size = 1858788, upload-time = "2026-07-20T19:49:48.015Z" }, + { url = "https://files.pythonhosted.org/packages/71/63/36a34c0139d0b1a830e8ee130a75312e9eddccb5b234a7f56e9de5e6edd2/aiohttp-3.14.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecdd6b8cab5b7c0ff2988378c11ba7192f076a1864e64dc3ff72f7ba05c71796", size = 1714003, upload-time = "2026-07-20T19:49:49.714Z" }, + { url = "https://files.pythonhosted.org/packages/ac/d8/c3a37079d503967a4072f8fc187c9d46c62b1eb72b25ae57dc0f2d0ddb11/aiohttp-3.14.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a3177e51e26e0158fb3376aebac97e0546c6f175c510f331f585e514a00a302b", size = 1588046, upload-time = "2026-07-20T19:49:51.209Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0c/c42b45bb275983cde529a4bc0e94f23ca6cdfe2a3c97285e73a4a6b81c23/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:86861a430657bc71e0f89b195de5f8fa495c0b9b5864cf2f89bd5ec1dbb6b77a", size = 1677219, upload-time = "2026-07-20T19:49:52.89Z" }, + { url = "https://files.pythonhosted.org/packages/75/a1/bdcd55b54d6335bc33e5f1b9f8613501c7f35cd99f44bf462d540d6b30d8/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:aac1b05fc5e2ef188b6d74cf151e977db75ab281238f30c3163bbd6f797788e3", size = 1691747, upload-time = "2026-07-20T19:49:54.495Z" }, + { url = "https://files.pythonhosted.org/packages/f1/98/a0d751d3787f2ca457beb16de5774a24e53fab840a8c7cb727cf900ed301/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:89120e926c68c4e60c78514d76e16fc15689d8df35843b2a6bf6c4cc0d64b11a", size = 1735039, upload-time = "2026-07-20T19:49:56.269Z" }, + { url = "https://files.pythonhosted.org/packages/ea/7a/33b8a5d348abc7335de33f4332ec0dcedfc7d45db28fd2162802d306345d/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:82d14d66d6147441b6571833405c828980efc17bda98075a248104ffdd330c30", size = 1577209, upload-time = "2026-07-20T19:49:57.926Z" }, + { url = "https://files.pythonhosted.org/packages/a9/03/09d41c3866e2102e6679e49fd78cd928926326fd304fa4e6f1d155f8ba04/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6cde463b9dd9ce4343785c5a39127b40fce059ae6fbd320f5a045a38c3d25cd0", size = 1751303, upload-time = "2026-07-20T19:49:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/eb/53/72115db0f3e4490b6c0cb063709d7553a1661ec03532b1b2f891e841af1b/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2280d165ab38355144d9984cdce77ce506cee019a07390bab7fd13682248ce91", size = 1699526, upload-time = "2026-07-20T19:50:01.328Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c6/9b8964be6d8d67dcf4bf32ff2380c203380322b1e23b5c1aa122c9b5a740/aiohttp-3.14.2-cp310-cp310-win32.whl", hash = "sha256:5e94a8c4445bfdaa30773c81f2be7f129673e0f528945e542b8bd024b2979134", size = 456626, upload-time = "2026-07-20T19:50:02.79Z" }, + { url = "https://files.pythonhosted.org/packages/bf/10/8dcdbbd9d83103db95ff74b255105113c1f6983865446f4facef81f0a1eb/aiohttp-3.14.2-cp310-cp310-win_amd64.whl", hash = "sha256:65cd3bb118f42fceceb9e8a615c735a01453d019c673f35c57b420601cc1a83a", size = 480367, upload-time = "2026-07-20T19:50:04.284Z" }, + { url = "https://files.pythonhosted.org/packages/14/08/b6eb0532f5ec2b202980c2d9658dd8ee3a1e21cdd0cb9d01debc0ba40045/aiohttp-3.14.2-cp310-cp310-win_arm64.whl", hash = "sha256:2a382aa6bb85347515ead043257445baeec0885d42bfedb962093b134c3b4816", size = 453374, upload-time = "2026-07-20T19:50:05.953Z" }, + { url = "https://files.pythonhosted.org/packages/f6/4a/a6c1426d2fb3cddd901575436803733caaaeb7ac0a49aa72d1930d2e3ab6/aiohttp-3.14.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:56432ee8f7abe47c97717cfbf5c32430463ea8a7138e12a87b7891fa6084c8ff", size = 764168, upload-time = "2026-07-20T19:50:07.389Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/88ae65afc3590719788cbff3b2e0f56e6850f53ca34114cbb371e677c543/aiohttp-3.14.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c244f7a65cbec04c830a301aae443c529d4dbca5fddfd4b19e5a179d896adfd", size = 516255, upload-time = "2026-07-20T19:50:08.84Z" }, + { url = "https://files.pythonhosted.org/packages/8f/bc/ad9b767785b014f2f57497a2ccf67e3d4316d153f7ed1c7715fbbd7573fe/aiohttp-3.14.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c05afdd28ecacce5a1f63275a2e3dce09efddd3a63d143ee9799fda83989c8d", size = 514670, upload-time = "2026-07-20T19:50:10.325Z" }, + { url = "https://files.pythonhosted.org/packages/48/94/697aef63f15ef354f64723eaac6ccfb289d59b99699b3b7cb1ff663b2045/aiohttp-3.14.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a57f39d6ec155932853b6b0f130cbbafab3208240fa807f29a2c96ea52b77ae1", size = 1780650, upload-time = "2026-07-20T19:50:11.676Z" }, + { url = "https://files.pythonhosted.org/packages/99/f9/6a1994c1bf138403cf10171cb618571a330ae5683a5803b1ef29b5723d7f/aiohttp-3.14.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fc31339824ec922cb7424d624b5b6c11d8942d077b2585e5bd602ca1a1e27ed", size = 1737710, upload-time = "2026-07-20T19:50:13.401Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ba/abe8d5015148b2cd7189473789461058dcf88ae202d4cf1cbecaf291a7ef/aiohttp-3.14.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d93854e215dcc7c88e4f530827193c1a594e2662931d8dbe7cca3abf52a7082d", size = 1845568, upload-time = "2026-07-20T19:50:15.168Z" }, + { url = "https://files.pythonhosted.org/packages/c2/89/98a2688810f469f19f2d02a298426a37b6e1cc420230a8cc7d6c85af7a01/aiohttp-3.14.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87c9b03be0c18c3b3587be979149830381e37ac4a6ca8557dbe72e44fcad66c3", size = 1928485, upload-time = "2026-07-20T19:50:16.922Z" }, + { url = "https://files.pythonhosted.org/packages/5a/fd/c980f64f5e5bff22f07968bcc6af1b64167dfd21dbbffda86f2d153fc802/aiohttp-3.14.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bc1a0793dce8fa9bb6906411e57fb18a2f1c31357b04172541b92b30337362a7", size = 1786216, upload-time = "2026-07-20T19:50:18.598Z" }, + { url = "https://files.pythonhosted.org/packages/da/80/c710ce9c7f22fcbb83366aa64a5ccf03dced35ab09a6e37545656a6df01e/aiohttp-3.14.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2f1b9540d2d0f2f95590528a1effd0ba5370f6ec189ac925e70b5eecae02dc77", size = 1636921, upload-time = "2026-07-20T19:50:20.201Z" }, + { url = "https://files.pythonhosted.org/packages/e1/b2/56ce1b0c535d188ef94c05bccbf3f5b1aaea1231fcb073318977bdd917e9/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c0a968b04fecf7c94e502015860ad1e2e112c6b761e97b6fdf65fbb374e22b73", size = 1753040, upload-time = "2026-07-20T19:50:21.857Z" }, + { url = "https://files.pythonhosted.org/packages/86/61/4318a947139a21d4e1a40e7f5a92799d0fe28feffaca6640a4a165e62b0e/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:2d2eedae227cd5cbd0bccc5e759f71e1af2cd77b7f74ce413bb9a2b87f94a272", size = 1760811, upload-time = "2026-07-20T19:50:23.623Z" }, + { url = "https://files.pythonhosted.org/packages/81/b0/2012165377d029ceb925c9e5f42b0b30a39d89cf7e494c4100f3ab8d27c6/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9d3f4c68b2c2cd282b65e558cebf4b27c8b440ab511f2b938a643d3598df2ddb", size = 1819760, upload-time = "2026-07-20T19:50:25.34Z" }, + { url = "https://files.pythonhosted.org/packages/16/e5/1de93ba3bc18edb87f71594326bedafdc38fe725da8118b7d36fd56610f8/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:d32a70b8bf8836fd80d4169d9e34eb032cd2a7cbccb0b9cf00eac1f40732467c", size = 1628145, upload-time = "2026-07-20T19:50:26.992Z" }, + { url = "https://files.pythonhosted.org/packages/66/8f/adc9e8592449ee08f72fcce94b7f3f1a9bbf0591a46026e4d322e5a70d7a/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:386ce4e709b4cc40f9ef9a132ad8e672d2d164a65451305672df656e7794c68e", size = 1832577, upload-time = "2026-07-20T19:50:28.546Z" }, + { url = "https://files.pythonhosted.org/packages/9b/7f/700500700513b1b63967a24c4e189aad377e18f9d67b7387b3418d6213cb/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc0ed30b942c3bd755583d74bb00b90248c067d20b1f8301e4489a53a33aa65f", size = 1774814, upload-time = "2026-07-20T19:50:30.144Z" }, + { url = "https://files.pythonhosted.org/packages/a5/d6/580f9b2ab4c78d9fbf9d56c85fb7f7d4d22d667b27df8032ab9bf7140e37/aiohttp-3.14.2-cp311-cp311-win32.whl", hash = "sha256:b5ed2c7dacebf4950d6b4a1b22548e4d709bb15e0287e064a7cdb32ada65893a", size = 455968, upload-time = "2026-07-20T19:50:31.722Z" }, + { url = "https://files.pythonhosted.org/packages/96/76/33665ae48e24e01c6dfa15ed14d9d9eec1349577cef497f3b26210621f0a/aiohttp-3.14.2-cp311-cp311-win_amd64.whl", hash = "sha256:bf7951959a8e89f2d4a1e719e60d3ea4e8fc26f011ee3aed09598ad786b112f7", size = 480978, upload-time = "2026-07-20T19:50:33.299Z" }, + { url = "https://files.pythonhosted.org/packages/5e/19/00963031da42bd23716032f57b2a8414c5355eb1abc41805b2b41173040c/aiohttp-3.14.2-cp311-cp311-win_arm64.whl", hash = "sha256:c167127a3b6089ef78ac2e33582c38040d51688ee28474b5053acf55f192187b", size = 452900, upload-time = "2026-07-20T19:50:35.049Z" }, + { url = "https://files.pythonhosted.org/packages/e0/99/8737b10b6fa447371541a3b2cdbf9703c31ecf3afff4998f2f0633646a57/aiohttp-3.14.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:30e41662123806e4590a0440585122ac33c89a2465a8be81cc1b50656ca0e432", size = 754562, upload-time = "2026-07-20T19:50:36.672Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e5/fd624b8b46d99dfd8f7f75111569b5ee21850539e914eed04ce39e4455ea/aiohttp-3.14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dbc45e2773c66d14fbd337754e9bf23932beef539bd539716a721f5b5f372034", size = 509386, upload-time = "2026-07-20T19:50:38.268Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a8/473db85d08b862724c506b51af2b9c6327e9e95cbd297c4c6f33968be1a8/aiohttp-3.14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:476cf7fac10619ad6d08e1df0225d07b5a8d57c04963a171ad845d5a349d47ef", size = 511905, upload-time = "2026-07-20T19:50:39.862Z" }, + { url = "https://files.pythonhosted.org/packages/c1/e8/aa5ebff13ac5e39ffae8add143757e936d1c2ceb726b82786e5f5cb9912c/aiohttp-3.14.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40bedff39ea83185f3f98a41155dd9da28b365c432e5bd90e7be140bcef0b7f3", size = 1764968, upload-time = "2026-07-20T19:50:41.559Z" }, + { url = "https://files.pythonhosted.org/packages/f4/22/23ec6d3d3f24f5961c7be73d5127481c992d6c92ca213f336ed8f0ff1453/aiohttp-3.14.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a26f14006883fc7662e21041b4311eac1acbc977a5c43aacb27ff17f8a4c28b2", size = 1740635, upload-time = "2026-07-20T19:50:43.363Z" }, + { url = "https://files.pythonhosted.org/packages/a0/7b/f8966d2d08f0582525ef02d5af007d2d2467cb733abf1d1f7849a02a6b98/aiohttp-3.14.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:673217cbc9370ebf8cd048b0889d7cbe922b7bb48f4e4c02d31cfefa140bd946", size = 1810447, upload-time = "2026-07-20T19:50:45.258Z" }, + { url = "https://files.pythonhosted.org/packages/39/f5/239f2a828b033ac244237074db7b560ad3279bb1e934bb462dbde19f3877/aiohttp-3.14.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b39dbdbe30a44958d63f3f8baa2af68f24ec8a631dcd18a33dd76dfa2a0eb917", size = 1905896, upload-time = "2026-07-20T19:50:47.022Z" }, + { url = "https://files.pythonhosted.org/packages/6c/6e/fb84b8dafc521026355aadbeed484fc1ec44a05aae927de309f204c1f0af/aiohttp-3.14.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d15f618255fcbe5f54689403aa4c2a90b6f2e6ebc96b295b1cb0e868c1c12384", size = 1792052, upload-time = "2026-07-20T19:50:48.683Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c4/25b199009f164ee02599b9b0962d22e6533d212418e49df9f4fdb37fe2eb/aiohttp-3.14.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ae767b7dffd316cc2d0abf3e1f90132b4c1a2819a32d8bcb1ba749800ea6273", size = 1590939, upload-time = "2026-07-20T19:50:50.702Z" }, + { url = "https://files.pythonhosted.org/packages/ad/f5/96d7540a52620433db3822267008a1697fc816979c109a4f535855ac893c/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3ec4b6501a076b2f73844256da17d6b7acb15bb74ee0e908a67feb9412371166", size = 1725039, upload-time = "2026-07-20T19:50:52.506Z" }, + { url = "https://files.pythonhosted.org/packages/f6/50/1a06abbeec14a2bcb46124ca6e281ed4ccb3e9006542ded6bc89a0ce5224/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7e328d02fb46b9a8dbfa070d98967e8b7eaa1d9ee10ae03fb664bdf30d58ccf0", size = 1764748, upload-time = "2026-07-20T19:50:54.336Z" }, + { url = "https://files.pythonhosted.org/packages/70/5d/b8821b362306627ea8ca11fe49ec47cba18e7c75d975fa5f6710ad93845c/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c0c7f2e5fe10910d5ab76438f269cc41bb7e499fd48ded978e926360ab1790c8", size = 1777119, upload-time = "2026-07-20T19:50:56.306Z" }, + { url = "https://files.pythonhosted.org/packages/81/e5/805d9d49e66c6358574ad70dd731031585d18fe95ae65b857bc378bccc9a/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:66de80888db2176655f8df0b705b817f5ae3834e6566cc2caa89360871d90195", size = 1580047, upload-time = "2026-07-20T19:50:58.316Z" }, + { url = "https://files.pythonhosted.org/packages/c6/fa/1536f272d5ad93bf8b75043b02b94c24bf4e6b55a849d3287553ad6da97e/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f2f9950b2dd0fc896ab520ea2366b7df6484d3d164a65d5e9f28f7b0e5742d8a", size = 1796861, upload-time = "2026-07-20T19:51:00.373Z" }, + { url = "https://files.pythonhosted.org/packages/e6/f3/86dfd6152bb706351cf5c6b45f0f6a1818a4e559d1e88d899c4c673c23a8/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cc4435b16dc246c5dfa7f2f8ee71b10a30765018a090ee36e99f356b1e9b75cc", size = 1768687, upload-time = "2026-07-20T19:51:02.214Z" }, + { url = "https://files.pythonhosted.org/packages/57/af/14b98e07fcd1a2b37ebb2f950309821eaa56e0eac3d32fc23dc55227e49b/aiohttp-3.14.2-cp312-cp312-win32.whl", hash = "sha256:4ca802547f1128008addfc21b24959f5cbf30a8952d365e7daa078a0d884b242", size = 451437, upload-time = "2026-07-20T19:51:03.954Z" }, + { url = "https://files.pythonhosted.org/packages/38/20/8478c05702a369b6d0800e40e0c5f9a289ff482d0921faec1eb17727339d/aiohttp-3.14.2-cp312-cp312-win_amd64.whl", hash = "sha256:e5efff8bfd27c44ce1bfdf92ce838362d9316ed8b2ed2f89f581dbe0bbe05acf", size = 476776, upload-time = "2026-07-20T19:51:05.705Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d0/e550bb1cb4fc82de3bdbe2add061cc0cedb34f2e7f01ada78fba94493ca1/aiohttp-3.14.2-cp312-cp312-win_arm64.whl", hash = "sha256:0eb1c9fd51f231ac8dc9d5824d5c2efc45337d429db0123fa9d4c20f570fdfc3", size = 447928, upload-time = "2026-07-20T19:51:07.523Z" }, + { url = "https://files.pythonhosted.org/packages/96/3a/8b8779f8e813d3a33cf16bc836a7ea7bf3c27b6588d42efa36b0c32fcb58/aiohttp-3.14.2-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:17eecd6ee9bfc8e31b6003137d74f349f0ac3797111a2df87e23acb4a7a912ea", size = 506205, upload-time = "2026-07-20T19:51:09.215Z" }, + { url = "https://files.pythonhosted.org/packages/d1/73/2f45204b37ecc4ce2c54b8b67254d70a8ea3b629c4083d58f3e2d27991cb/aiohttp-3.14.2-cp313-cp313-android_21_x86_64.whl", hash = "sha256:ce8dfb58f012f76258f29951d38935ac928b32ae24a480f30761f2ed5036fa78", size = 515116, upload-time = "2026-07-20T19:51:10.914Z" }, + { url = "https://files.pythonhosted.org/packages/f0/22/8f4424de1f50df4fbb74ea32006f9cff798ae0d346ffa6be7b6f0caca719/aiohttp-3.14.2-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:4181d72e0e6d1735c1fae56381193c6ae211d584d06413980c00775b9b2a176a", size = 486244, upload-time = "2026-07-20T19:51:12.878Z" }, + { url = "https://files.pythonhosted.org/packages/c2/53/60de022260f5d2d31976bc5f50db708e10671f0ac5da515402adcc6b4d4d/aiohttp-3.14.2-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:0e56babe35076f69ec9327833b71439eeccd10f51fe56c1a533da8f24923f014", size = 492260, upload-time = "2026-07-20T19:51:14.555Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6f/d3ccc31c15cd33888670b8f1bf1dc06f3239b4edd156fc818078e87ae628/aiohttp-3.14.2-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6b63709e259e3b3d7922b235606564e91ed4c224e777cc0ca4cae04f5f559206", size = 502174, upload-time = "2026-07-20T19:51:16.3Z" }, + { url = "https://files.pythonhosted.org/packages/40/20/52d21e485652f4708015ce27dd3029e63140e0bdb0dcc7bf72dc0bc3f4ad/aiohttp-3.14.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f7c10c4d0b33888a68c192d883d1390d4596c116a59bf689e6d352c6739b7940", size = 750878, upload-time = "2026-07-20T19:51:18.013Z" }, + { url = "https://files.pythonhosted.org/packages/2e/49/1220bdc73d568431cc3856667405d78c2e95eb57fed2b9ffa5e825932ab2/aiohttp-3.14.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f7b19e27b78a3a927b1932af93af7645806153e8f541cee8fe856426142503f", size = 508459, upload-time = "2026-07-20T19:51:19.876Z" }, + { url = "https://files.pythonhosted.org/packages/ed/f1/39177406ce0ae5cb2782b35e848c0edf6e09d6e082df636eeacdbdfa70bd/aiohttp-3.14.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:18fcc3a5cc7dde1d8f7903e309055294c28894c9434588645817e374f3b83d03", size = 509179, upload-time = "2026-07-20T19:51:21.719Z" }, + { url = "https://files.pythonhosted.org/packages/87/f7/6d081c2ee838458492c7ae1062399bdd68f149811d257d4502e79a25b306/aiohttp-3.14.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09d1b0deec698d1198eb0b8f910dd9432d856985abbfea3f06be8b296a6619b4", size = 1761346, upload-time = "2026-07-20T19:51:23.437Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ed/0befea4ae533f09c3a60f0d10b923cd4a90027a1bf49dfafaa24eeee08b8/aiohttp-3.14.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cabaaecb4c6888bd9abafac151051377534dad4c3859a386b6325f39d3732f99", size = 1735057, upload-time = "2026-07-20T19:51:25.512Z" }, + { url = "https://files.pythonhosted.org/packages/de/03/c1d89fcd94907f93a08d4aadbb4e1d9bd3d7d6c9f94bc9c17689de38107b/aiohttp-3.14.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:114299c08cce8ad4ebb21fafe766378864109e88ad8cf63cf6acb384ff844a57", size = 1800389, upload-time = "2026-07-20T19:51:27.585Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8b/edbac4d1a1cde3571588a1e5b40637df5acee43158efdf3ae9a161fde8ab/aiohttp-3.14.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6bea8451e26cd67645d9b2ee18232e438ddfc36cea35feecb4537f2359fc7030", size = 1895342, upload-time = "2026-07-20T19:51:29.794Z" }, + { url = "https://files.pythonhosted.org/packages/0c/31/2e9ca3b21c07ea8a001e2b142cb01401fd34fd07b248a0b95a04c3ebc4ec/aiohttp-3.14.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:46b8887aa303075c1e5b24123f314a1a7bbfa03d0213dff8bb70503b2148c853", size = 1789175, upload-time = "2026-07-20T19:51:31.744Z" }, + { url = "https://files.pythonhosted.org/packages/6f/91/b57d3d13a80fbf765b19ae0c38d783a3a23f35b1cb82ae3b22f91abe6c24/aiohttp-3.14.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:de3b04a3f7b40ad7f1bcd3540dd447cf9bd93d57a49969bca522cbcf01290f08", size = 1586845, upload-time = "2026-07-20T19:51:33.571Z" }, + { url = "https://files.pythonhosted.org/packages/69/e8/a2f5f9f6219cd21190e9b50e2cbc978d12a2aab748d0aa7c6ee930db15c3/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:42372e1f1a8dca0dcd5daf922849004ec1120042d0e24f14c926f97d2275ca79", size = 1724839, upload-time = "2026-07-20T19:51:35.518Z" }, + { url = "https://files.pythonhosted.org/packages/de/d4/a2b9442336051714dd8dbd419b9f4a1003c45bb850ee0f3af87f2743e867/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7871c94f3400358530ac4906dd7a526c5a24099cd5c48f53ffc4b1cb5037d7d7", size = 1756306, upload-time = "2026-07-20T19:51:37.459Z" }, + { url = "https://files.pythonhosted.org/packages/ab/93/22c94a599b2c4ea6ab88f1b912d90883f1fba5235b587ea9f13b148e9a0f/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f8f371794319a8185e61e15ba5e1be8407b986ebce1ade11856c02d24e090577", size = 1769133, upload-time = "2026-07-20T19:51:39.9Z" }, + { url = "https://files.pythonhosted.org/packages/fe/db/a4e4c207f7023e83c281a7cf3579f227bade48f1899cb6588c0ed6ae54de/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:af63ac06bad85191e6a0c4a733cb3c55adb99f8105bc7ce9913391561159a49a", size = 1578671, upload-time = "2026-07-20T19:51:42.418Z" }, + { url = "https://files.pythonhosted.org/packages/8d/6f/33746ba4947b8193652fc7ed0533e09f93b118e39777228f3029e5677c17/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:8c2cdb684c153f377157e856257ee8535c75d8478343e4bb1e83ca73bdfa3d31", size = 1791778, upload-time = "2026-07-20T19:51:44.298Z" }, + { url = "https://files.pythonhosted.org/packages/06/41/323856cb0ec9076b1f9a135eb0684f5f984dd97989a087873768aa34ca2f/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ceff4f84c1d928654faa6bcb0437ed095b279baae2a35fcfe5a3cbe0d8b9725d", size = 1768490, upload-time = "2026-07-20T19:51:46.279Z" }, + { url = "https://files.pythonhosted.org/packages/39/f0/09e29e457b6fb49253cbb61354ed2541fdf23ac192bddbb57bb34bc93d9c/aiohttp-3.14.2-cp313-cp313-win32.whl", hash = "sha256:15292b08ce7dd45e268fce542228894b4735102e8ee77163bd665b35fc2b5598", size = 451064, upload-time = "2026-07-20T19:51:48.194Z" }, + { url = "https://files.pythonhosted.org/packages/0b/76/b44703eafcfe1446f4f975be1ef2406042955425eaf56450e71b50506c49/aiohttp-3.14.2-cp313-cp313-win_amd64.whl", hash = "sha256:fc2d8e7373ceba7e1c7e9dc00adac854c2701a6d443fd21d4af2e49342d727bd", size = 476140, upload-time = "2026-07-20T19:51:50.285Z" }, + { url = "https://files.pythonhosted.org/packages/72/48/b095935c9e72a253439f80ec757b91d4733e0a9a98b63e108d84aaf39b08/aiohttp-3.14.2-cp313-cp313-win_arm64.whl", hash = "sha256:70570f50bda5037b416db8fcba595cf808ecf0fdce12d64e850b5ae1db7f64d4", size = 447585, upload-time = "2026-07-20T19:51:52.333Z" }, + { url = "https://files.pythonhosted.org/packages/4f/ca/716f720dccc3032e40dc80d0ab2d87a7365270a714976a85bdff73bc7254/aiohttp-3.14.2-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:7719cef2a9dc5e10cd5f476ec1744b25c5ac4da733a9a687d91c42de7d4afe30", size = 508899, upload-time = "2026-07-20T19:51:54.165Z" }, + { url = "https://files.pythonhosted.org/packages/f5/80/786166589e71b3f3cfce56b414170fe5008462d0bff100bd8837285632f6/aiohttp-3.14.2-cp314-cp314-android_24_x86_64.whl", hash = "sha256:3523ec0cc524a413699f25ec8340f3da368484bc9d5f2a1bf87f233ac20599bf", size = 514722, upload-time = "2026-07-20T19:51:56.208Z" }, + { url = "https://files.pythonhosted.org/packages/eb/b7/539961cf3e3d3f179ea4b20d456cbdb67d1163c68f2e95bf220438a5afd5/aiohttp-3.14.2-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:c8ab295ee58332ef8fbd62727df90540836dfcf7a61f545d0f2771223b80bf25", size = 488082, upload-time = "2026-07-20T19:51:58.293Z" }, + { url = "https://files.pythonhosted.org/packages/60/34/c7708eac8edacca9c049a0d6f5fa610005ac3c5634c9ea4751134263bf4e/aiohttp-3.14.2-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:71501bc03ede681401269c569e6f9306c761c1c7d4296675e8e78dd07147070f", size = 494140, upload-time = "2026-07-20T19:52:00.158Z" }, + { url = "https://files.pythonhosted.org/packages/d8/e1/076b88de36b4ebea62d1c0b225e32bc8a452ee71b2aded82878fa5fa7c9e/aiohttp-3.14.2-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:052478c7d01035d805302db50c2ef626b1c1ba0fe2f6d4a22ae6eaeb43bf2316", size = 502670, upload-time = "2026-07-20T19:52:02.097Z" }, + { url = "https://files.pythonhosted.org/packages/a9/71/7b7720ffe7e521aaa79a853ebff4c17937f4b5a3a586e9d13b0f38050b35/aiohttp-3.14.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:b0d49be9d9a210b2c993bf32b1eda03f949f7bcda68fc4f718ae8085ae3fb4b8", size = 756406, upload-time = "2026-07-20T19:52:04.082Z" }, + { url = "https://files.pythonhosted.org/packages/b9/9a/c67c7e22fff7d7b17387e718451b30eb89f55df6b8d13d2d7f91daba6505/aiohttp-3.14.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:5fe25c4c44ea5b56fd4512e2065e09384987fc8cc98e41bc8749efe12f653abb", size = 510106, upload-time = "2026-07-20T19:52:06.001Z" }, + { url = "https://files.pythonhosted.org/packages/27/2a/3caebd640229663263585d4d31898331a3937752f2e1f5ec0af509fa31be/aiohttp-3.14.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7e254b0d636957174a03ca210289e867a62bb9502081e1b44a8c2bb1f6266ecd", size = 512876, upload-time = "2026-07-20T19:52:08.036Z" }, + { url = "https://files.pythonhosted.org/packages/27/04/86945210e491493f5cd025efe5e6d8fc8a9e8aaf36f943c40f52c34eda7e/aiohttp-3.14.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a6b0ce033d49dd3c6a2566b387e322a9f9029110d67902f0d64571c0fd4b73d8", size = 1750050, upload-time = "2026-07-20T19:52:09.998Z" }, + { url = "https://files.pythonhosted.org/packages/11/d8/356c62552b4db60af5ad8cddeafa6f837788918201f1b5f2466565c986b5/aiohttp-3.14.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41b5b66b1ac2c48b61e420691eb9741d17d9068f2bc23b5ee3e750faa564bc8f", size = 1707177, upload-time = "2026-07-20T19:52:12.39Z" }, + { url = "https://files.pythonhosted.org/packages/77/2d/41bb20bed3df1d6dc7fc231ca4ffb72177fd151bf4205a4ade7a93e03501/aiohttp-3.14.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30a5ed81f752f182961237414a3cd0af209c0f74f06d66f66f9fcb8964f4978d", size = 1803795, upload-time = "2026-07-20T19:52:14.705Z" }, + { url = "https://files.pythonhosted.org/packages/63/21/ad9fe6786a1d2758bcfdae4dbc1d6869ffc7b1e0571530a508de3cdde09b/aiohttp-3.14.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1b9251f43d78ff675c0ddfcd53ba61abecc1f74eedc6287bb6657f6c6a033fe7", size = 1876539, upload-time = "2026-07-20T19:52:16.965Z" }, + { url = "https://files.pythonhosted.org/packages/0e/cb/d213f4fd7af279d82c4b46d30de22db93a01296d77a8d8e535289637da54/aiohttp-3.14.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf7930e83a12801b2e253d41cc8bf5553f61c0cfabef182a72ae13472cc81803", size = 1761130, upload-time = "2026-07-20T19:52:19.127Z" }, + { url = "https://files.pythonhosted.org/packages/46/4f/0792fe1a24c2b4b506d07350e980b0626c149fe73e68dd37dfb30ed89813/aiohttp-3.14.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:abb33120daba5e5643a757790ece44d638a5a11eb0598312e6e7ec2f1bd1a5a3", size = 1583576, upload-time = "2026-07-20T19:52:21.465Z" }, + { url = "https://files.pythonhosted.org/packages/46/ad/551c302f534f9cd6105bd16902e69dc64c726aa729127203f47ed4bddb2a/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:983a68048a48f35ed08aadfcc1ba55de9a121aa91be48a764965c9ec532b94b5", size = 1714139, upload-time = "2026-07-20T19:52:23.636Z" }, + { url = "https://files.pythonhosted.org/packages/e3/cf/a3be8601d2e80ccf7bd4f79807629cede5425d72c02636f06b1ad6a8290a/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:fef094bfc2f4e991a998af066fc6e3956a409ef799f5cbad2365175357181f2e", size = 1724352, upload-time = "2026-07-20T19:52:26.043Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b1/6b55f6448b43a3338749f37fc6a14e7ac7dad121d2d585f22c1dd3d324fe/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2f7ca81d936d820ae479971a6b6214b1b867420b5b58e54a1e7157716a943754", size = 1770749, upload-time = "2026-07-20T19:52:28.467Z" }, + { url = "https://files.pythonhosted.org/packages/39/58/b3f1cf6af47fa0b0d51c6e2b98b2bf0326b44a932d74915f3c0874413ea8/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:da4f142fa078fedbdb3f88d0542ad9315656224e167502ae274cbba818b90c90", size = 1577547, upload-time = "2026-07-20T19:52:30.658Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e2/1d79f1ab35593d70dabed98936ae842ac90d12847c9a62bba4a19d6005a4/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:3d4238e50a378f5ac69a1e0162715c676bd082dede2e5c4f67ca7fd0014cb09d", size = 1781840, upload-time = "2026-07-20T19:52:33.021Z" }, + { url = "https://files.pythonhosted.org/packages/01/73/770be856c6fc861563999081a5fe2d44e16b4255f5fd94b2217a2349ca65/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:03330676d8caa28bb33fa7104b0d542d9aac93350abcd91bf68e64abd531c320", size = 1745757, upload-time = "2026-07-20T19:52:35.541Z" }, + { url = "https://files.pythonhosted.org/packages/bc/0b/861fdbe3ff90b503a4d0a12276623f4afbe54c237ca876fc560125c270a3/aiohttp-3.14.2-cp314-cp314-win32.whl", hash = "sha256:43387429e4f2ec4047aaf9f935db003d4aa1268ea9021164877fd6b012b6396a", size = 455863, upload-time = "2026-07-20T19:52:37.634Z" }, + { url = "https://files.pythonhosted.org/packages/f7/03/cc8234d0f06fe4b0e1777c7ed313cc9014f078f72a9a0cbdc144965d1bd7/aiohttp-3.14.2-cp314-cp314-win_amd64.whl", hash = "sha256:e3a6302f47518dbf2ffd3cd518f02a1fbf53f85ffeed41a224fa4a6f6a62673b", size = 480986, upload-time = "2026-07-20T19:52:39.665Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b0/ae17dd629e22160f453b9041a4aee80a8a917ba2f44d5b3e252cc501ed2c/aiohttp-3.14.2-cp314-cp314-win_arm64.whl", hash = "sha256:8d1f3802887f0e0dc07387a081dca3ad0b5758e32bdf5fb619b12ac22b8e9b56", size = 453588, upload-time = "2026-07-20T19:52:41.634Z" }, + { url = "https://files.pythonhosted.org/packages/30/54/4bbcc00f04dbc380103ee669a56df30dea127c3686c8dc2ab86b05a1387b/aiohttp-3.14.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9094262ae4f2902c7291c14ba915960db5567276690ef9195cdefe8b7cbb3acb", size = 791337, upload-time = "2026-07-20T19:52:43.821Z" }, + { url = "https://files.pythonhosted.org/packages/e7/37/4f95edc1488580c63c0b5baaef429afbacadc7ccd9c47431cdcce90d9e5a/aiohttp-3.14.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:165b0dcc65960ffc9c99aa4ba1c3c76dbc7a34845c3c23a0bd3fbf33b3d12569", size = 526335, upload-time = "2026-07-20T19:52:45.903Z" }, + { url = "https://files.pythonhosted.org/packages/c3/ed/1d7ae73764d135638797a427cb637ae3d98f1fd61208c25891a9f26cdd67/aiohttp-3.14.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f518d75c03cd3f7f125eca1baadb56f8b94db94602278d2d0d19af6e177650a7", size = 532102, upload-time = "2026-07-20T19:52:47.994Z" }, + { url = "https://files.pythonhosted.org/packages/e3/12/da9816eee0d81506560259e7c0af93a4aa7df98acd0fe276958abd42d7c3/aiohttp-3.14.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b937d7864ca68f1e8a1c3a4eb2bac1de86a992f86d36492da10a135a482fab6", size = 1922727, upload-time = "2026-07-20T19:52:50.224Z" }, + { url = "https://files.pythonhosted.org/packages/2f/b9/d7ccbcde223a72c7b8f3458bdb08c2bacf5fc268a1fdd5cc29861eb0e4e2/aiohttp-3.14.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b155df7f572c73c6c4108b67be302c8639b96ae56fb02787eeae8cad0a1baf26", size = 1787202, upload-time = "2026-07-20T19:52:52.825Z" }, + { url = "https://files.pythonhosted.org/packages/c2/7c/39174069b7df18ea22b23a0fa9abffe4c091f0f86d53af83ddcbb5f44c8f/aiohttp-3.14.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0bfea68a48c8071d49aabdf5cd9a6939dcb246db65730e8dc76295fe02f7c73c", size = 1912574, upload-time = "2026-07-20T19:52:55.007Z" }, + { url = "https://files.pythonhosted.org/packages/21/ff/bd2b7473510caf352aef3f52a3d4fe10184ec22747df74ab658b4402020f/aiohttp-3.14.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8241ee6c7fff3ebb1e6b237bccc1d90b46d07c06cf978e9f2ecad43e29dac67a", size = 2005478, upload-time = "2026-07-20T19:52:57.401Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ee/db26af0acc994350b653b3a73dddf9ee9886bf2fdb68b23fc98705e76442/aiohttp-3.14.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ec64d1c4605d689ed537ba1e572138e2d4ff603a0cb2bbbfe61d4552c73d19e1", size = 1879709, upload-time = "2026-07-20T19:52:59.778Z" }, + { url = "https://files.pythonhosted.org/packages/6a/4d/592451fd40edca73fcb099d8718668cea36dc1dde873dd0f8e91a4081051/aiohttp-3.14.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0fb26fcc5ebf765095fe0c6ab7501574d3108c57fca9a0d462be15a65c9deb8d", size = 1675699, upload-time = "2026-07-20T19:53:02.11Z" }, + { url = "https://files.pythonhosted.org/packages/2a/3e/c1ce4aa13fd1f910e437684843ea6cf6e0041f91d89a1b0389dce247ee59/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ef710fbb770aefa4def5484eeddb606e70ab3492aa37390def61b35652f6820a", size = 1843542, upload-time = "2026-07-20T19:53:04.385Z" }, + { url = "https://files.pythonhosted.org/packages/aa/a4/3f9e22fda714cc38ef558166ff3326cd2f6f65c33da92ba00e3641cbea54/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d813f54560b9e5bce170fff7b0adde54d88253928e4add447c36792f27f92125", size = 1827505, upload-time = "2026-07-20T19:53:07.072Z" }, + { url = "https://files.pythonhosted.org/packages/37/9d/260c7b8a25c7cd74bee63ce957556a2d25839a321e9107a089d4da3a51af/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:1aa4f3b44563a88da4407cef8a13438e9e386967720a826a10a633493f69208f", size = 1853751, upload-time = "2026-07-20T19:53:10.012Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d6/7c3cfa191e666bf7b48b4346815900b35b85b43ffff783fd0be52e45fe09/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4610638d3135afaefadf179bffd1bbf3434d3dc7a5d0a4c4219b99fa976e944d", size = 1668850, upload-time = "2026-07-20T19:53:12.362Z" }, + { url = "https://files.pythonhosted.org/packages/c4/af/d9b8353aee9506dace04ca22c3c4e93b7375d9343c4780c8b512972fc6f9/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:6e30743bd3ab6ad98e9abbad6ccb39c52bcf6f11f9e3d4b6df97afffe8df53f3", size = 1883642, upload-time = "2026-07-20T19:53:14.664Z" }, + { url = "https://files.pythonhosted.org/packages/ed/29/ed64c0a013322570a02e5b0e359df2cfd30ae58ba045748dc78175f15826/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:68a6f7cd8d2c70869a2a5fe97a16e86a4e13a6ed6f0d9e6029aef7573e344cd6", size = 1844092, upload-time = "2026-07-20T19:53:16.995Z" }, + { url = "https://files.pythonhosted.org/packages/3c/74/ce6f229510fdd46ee7365fbb759ffaa3004e0bcc59fbd0ec51d8a8efc775/aiohttp-3.14.2-cp314-cp314t-win32.whl", hash = "sha256:205181d896f73436ac60cf6644e545544c759ab1c3ec8c34cc1e044689611361", size = 474098, upload-time = "2026-07-20T19:53:19.645Z" }, + { url = "https://files.pythonhosted.org/packages/72/4c/877c07a6d97a1a0e5e25a06bab76dd7449b533ff8bb6c281c5af8b09c8d9/aiohttp-3.14.2-cp314-cp314t-win_amd64.whl", hash = "sha256:312d414c294a1e26aa12888e8fd37cd2e1131e9c48ddcf2a4c6b590290d52a49", size = 500480, upload-time = "2026-07-20T19:53:22.227Z" }, + { url = "https://files.pythonhosted.org/packages/42/d8/d4c74bb7990da2ee6116fe262ace41cf376ebc6b0bda694c77eeaab5a509/aiohttp-3.14.2-cp314-cp314t-win_arm64.whl", hash = "sha256:63b840c03979732ec92e570f0bd6beb6311e2b5d19cacbfcd8cc7f6dd2693900", size = 469248, upload-time = "2026-07-20T19:53:24.622Z" }, ] [[package]] @@ -276,6 +293,99 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, ] +[[package]] +name = "backports-zstd" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/b5/5a873da082bd08acd6a497f7aae224e94a7c27fa8f24488089cc50a16c84/backports_zstd-1.6.0.tar.gz", hash = "sha256:80a7859ffe70bf239d7a2ce15293bdeb5b4280ff7dc326ffab312b0e254dbb24", size = 1000009, upload-time = "2026-06-14T10:50:58.555Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/8d/3f8e7a0fd319b3c0dbf0c4f751336309bb50a873b9185c2f5d228ff0d21b/backports_zstd-1.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:73000459db113a658c4fb0510100ef0e79137b5828bf957b7709aacae4eb1b87", size = 437068, upload-time = "2026-06-14T10:49:05.528Z" }, + { url = "https://files.pythonhosted.org/packages/db/14/4700047713a60131efcb3977a9892fab60bc9dd6634272550b8f1c5a427d/backports_zstd-1.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6e78d5e28f812b39f92397806ecddd4a6f3bf35531a8c039a1f187abc931af8", size = 363456, upload-time = "2026-06-14T10:49:07.154Z" }, + { url = "https://files.pythonhosted.org/packages/c4/34/92de2f1bd5ee29b24302c871b9f3c19155bf9478cd3af5a0dfd70fa2f483/backports_zstd-1.6.0-cp310-cp310-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:32f04d54ec1fdf3aa648b24a10b1c9234ed2046cc4af7a8850cbc236c05d42f3", size = 507392, upload-time = "2026-06-14T10:49:08.63Z" }, + { url = "https://files.pythonhosted.org/packages/5a/95/ed5b8b026c6df1a59681a73396f63cfd10e17ccfbc6315974745a8b7d834/backports_zstd-1.6.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83415af3c64550a56cc20b4cce59bbaa81f21d28466d7adf98feff011ecbc66d", size = 476957, upload-time = "2026-06-14T10:49:09.894Z" }, + { url = "https://files.pythonhosted.org/packages/5a/47/1a82ede48d9df99c8245cb38622cd1a9b388b34f89e1cb7b6650913b493d/backports_zstd-1.6.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a3c17e6a267d13de9cbf14bf2ebfa87e03d26692456fc67d2dbed9da4f479b18", size = 582618, upload-time = "2026-06-14T10:49:11.097Z" }, + { url = "https://files.pythonhosted.org/packages/6b/70/441ed36e230b0f66d7d49382c58249b540139c5b1aa096ace1ff00bd7873/backports_zstd-1.6.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:75578c71644b031118ce938855a53530708db7f4af6e83e2f8840d5a1de990f8", size = 642278, upload-time = "2026-06-14T10:49:12.545Z" }, + { url = "https://files.pythonhosted.org/packages/58/a3/8f5737bdb02576577a018c10a4c345a5b4b2e63cc3811baeecc054f71c00/backports_zstd-1.6.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4ae7ed5a6d813450cc2d818284ea3db9721edcef50a56aae42ea06feec38c6e", size = 492492, upload-time = "2026-06-14T10:49:14.037Z" }, + { url = "https://files.pythonhosted.org/packages/e1/a9/c086507f535c2466a25bf83a876666c9ccde07b17ce81680217ac17355fe/backports_zstd-1.6.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5e9a8370c8ed873083d5de956d6b2e60adbad31e52d7a11111c96ef01d1910ae", size = 566440, upload-time = "2026-06-14T10:49:15.483Z" }, + { url = "https://files.pythonhosted.org/packages/89/bb/778aaccb58c4d2fba3482438c0d33c6a3a413710ecdb2ee8559ff28632fc/backports_zstd-1.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c2d1ccfe088e8279d605011a3575619a74526c261be357695b3258c0f636115a", size = 482894, upload-time = "2026-06-14T10:49:16.982Z" }, + { url = "https://files.pythonhosted.org/packages/3a/88/87ad188ce971c15bce933e13c4dc2939e741a9cb06a8bd692ef8614c3ed4/backports_zstd-1.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e73a550dbeb84e8fa50f8385f7735e9a4735b465851ef617d02f80ab10e44e7e", size = 510822, upload-time = "2026-06-14T10:49:18.274Z" }, + { url = "https://files.pythonhosted.org/packages/6e/8c/01714884a14b836abfdb1d80339acbb39515b0e92e615c4b65caf0eec257/backports_zstd-1.6.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:84f92e5a60a78c72ccda79d0417d311a1f6da18f446423ed411726d545bf7b56", size = 586941, upload-time = "2026-06-14T10:49:19.563Z" }, + { url = "https://files.pythonhosted.org/packages/63/43/e2cb44bbe3f7485d6ad8493211f0c8fffdb7e02fb94203fd968751d9fad7/backports_zstd-1.6.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0eb4281f402b94d397b7482f6d9efd04c28274e4ed6eb57eb1f87bdd091a6a87", size = 564255, upload-time = "2026-06-14T10:49:20.968Z" }, + { url = "https://files.pythonhosted.org/packages/36/eb/eb0f00f6f7778db3710f757d77f5699c325548037dd975b52b186394125e/backports_zstd-1.6.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d6b9b06323e3ba947c0003b2d70e02f33c90c36bc6262a92eb8201afc4a1aa08", size = 632836, upload-time = "2026-06-14T10:49:22.177Z" }, + { url = "https://files.pythonhosted.org/packages/ac/b8/5434897431de92e79ebfb2c02e1ab3cd228e92853b7ff981b2cffcce7355/backports_zstd-1.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8872a0e9f1af975966b5be6af7eebd3dc4046f15e470b719316516dc3d137cd6", size = 496501, upload-time = "2026-06-14T10:49:23.444Z" }, + { url = "https://files.pythonhosted.org/packages/db/76/754939c3914e9724e20a50b75b17fdc27aeb24d697eb61c3e93438a42920/backports_zstd-1.6.0-cp310-cp310-win32.whl", hash = "sha256:c14fa5dc39a804f1b92d63506f450eca5c59647a18d197d1a564b89dac1be1ce", size = 291527, upload-time = "2026-06-14T10:49:24.568Z" }, + { url = "https://files.pythonhosted.org/packages/84/f1/adcebdc2caa2e3d3d496ac2501f0ada49ad2942ee36e5f88a944bca9ca92/backports_zstd-1.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:8219d6fceae6b39535c4ac323dba0923d10f781d59962ff3504e693fdcafa92c", size = 329024, upload-time = "2026-06-14T10:49:25.773Z" }, + { url = "https://files.pythonhosted.org/packages/74/10/12edc0b401a08aba157b9d331748ac0f0e9890af0a58a9c72425063d1450/backports_zstd-1.6.0-cp310-cp310-win_arm64.whl", hash = "sha256:b7bc9a0b66097f03820a54316d2fdd0beb38859cf98f10d63e94c55450ed8920", size = 291597, upload-time = "2026-06-14T10:49:27.156Z" }, + { url = "https://files.pythonhosted.org/packages/c5/90/428dd82228b1b6d62d5a1bf312c29e6c125af6a182fcfd82768ca179dcc7/backports_zstd-1.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c4fc41b2df5529cad5ceb230319e82728096d4b353ce8d4df68a2ec37e291bb8", size = 437067, upload-time = "2026-06-14T10:49:28.335Z" }, + { url = "https://files.pythonhosted.org/packages/ef/48/768edf21fe33bae8d874470b1be136681d4d32eb820a32e1c98262ebe39b/backports_zstd-1.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:83391ef5935cc0f329b1abca414ae20ffe40d335fc21a4b5e664f08a74317d5f", size = 363454, upload-time = "2026-06-14T10:49:29.784Z" }, + { url = "https://files.pythonhosted.org/packages/29/8a/d462c2e5071eb573378f0d26760f6590613086fdf59c2d3c66bdfffb9f41/backports_zstd-1.6.0-cp311-cp311-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:7d3f64c503af7b60115b97c16feaf75bd191ef2c978d5c0c7725a6682bef63c5", size = 507393, upload-time = "2026-06-14T10:49:31.077Z" }, + { url = "https://files.pythonhosted.org/packages/b9/cb/af58363b0dd0b497282ecef1fa99789b03cc1885a01a41394cad42ceeff6/backports_zstd-1.6.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0308990ffc998df3c7ed35276bde049728b5c3956203cae40d80893576a41459", size = 476957, upload-time = "2026-06-14T10:49:32.53Z" }, + { url = "https://files.pythonhosted.org/packages/e4/fd/5fbdf2275cefae95c4b3509f6db2dc372d0587ebafea342d28781d51d932/backports_zstd-1.6.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8c298785e2fadeab82342040f2d9ce764ce500e6da6a6d99a2de514e63580b5a", size = 582618, upload-time = "2026-06-14T10:49:33.723Z" }, + { url = "https://files.pythonhosted.org/packages/99/6f/7dd45c53c907ea67f635c3900b58bb3347c01dc2ded441402028aae0ef9c/backports_zstd-1.6.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ae106fe16e36efc60ab098d02478d30aa0e31e1420eb4ecf0116459253bc6361", size = 642279, upload-time = "2026-06-14T10:49:34.938Z" }, + { url = "https://files.pythonhosted.org/packages/4d/25/a9e37dd035027565fa0b7e367da50e88a6ab26e7fd413269aa118e25258b/backports_zstd-1.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7293fefe15f0e5852bdb4ad1e0e26f3cbd4d3e61c19f751ecc4ff34bc1eb237d", size = 492486, upload-time = "2026-06-14T10:49:36.06Z" }, + { url = "https://files.pythonhosted.org/packages/a1/52/659686bf8f7c53ea279e1c44038504b82a6901cee2f5ae83c30bbf581301/backports_zstd-1.6.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ece8e7288db5b827ef8c64b2f78519f1a173a8991a625978fce02eccd7654fe9", size = 566440, upload-time = "2026-06-14T10:49:37.536Z" }, + { url = "https://files.pythonhosted.org/packages/d9/1a/c7ea5a0ff607a1a6066bb7c7cb65ae20e2f85da6adc69ab77fd8943e180c/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:28eef3881164f3c23ce58ed59e4684103bdd279583eb2d299858c9e9b72fde9a", size = 482899, upload-time = "2026-06-14T10:49:38.805Z" }, + { url = "https://files.pythonhosted.org/packages/83/48/bd2b91100ee4fe6bb4d816e3659cbbb0cda5dd32760d2379c54d1752ec25/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:481a1e9bd8f419fdc625307aa20234687f99368c75df511ef589693c5fea4c6f", size = 510826, upload-time = "2026-06-14T10:49:40.062Z" }, + { url = "https://files.pythonhosted.org/packages/25/fe/fa28509d7ce2ad59404e7ce738a2fd858e12dfd9a896629f10330222a7fb/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3b6713371f8987a1178df93cb36f29eef191f224021e2d656b2f11ce60d26816", size = 586941, upload-time = "2026-06-14T10:49:41.305Z" }, + { url = "https://files.pythonhosted.org/packages/45/28/757daf2399aa71bb37f9f7f48b42ab03fc51c340eccfad2fec92a23f6aa3/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:b0ddbcd2866b8ff1a2836e4b0e4d44788f5b992d83fac75a38cda8f9a2bee079", size = 564261, upload-time = "2026-06-14T10:49:42.49Z" }, + { url = "https://files.pythonhosted.org/packages/4e/53/9b9db30cb2c148a69c40ad7647aa787338041f3dc81c5b22113286e590e9/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2914abea516704bdafb2090acd3f15b5f9debecfabd15b8dd8285b2ad3b92209", size = 632869, upload-time = "2026-06-14T10:49:43.981Z" }, + { url = "https://files.pythonhosted.org/packages/81/a4/1692fbb88af8aaf900a53619fcc95c9e45d9ff162223a47fd672a9893c8d/backports_zstd-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dd085eafa2aac6f883afd28210a3231f717f25409a1e44a39bb7b04c8c5b5646", size = 496496, upload-time = "2026-06-14T10:49:45.118Z" }, + { url = "https://files.pythonhosted.org/packages/93/42/c5a66c47320bd12ce84a7341330ea582d67069bdb70214bca0b6bf394cfd/backports_zstd-1.6.0-cp311-cp311-win32.whl", hash = "sha256:b81b4cf3d6e0ad7ac92bef248f49fafc954262c5fb0f7e19d6aac497e5a856b2", size = 291613, upload-time = "2026-06-14T10:49:46.473Z" }, + { url = "https://files.pythonhosted.org/packages/2a/f2/f22c19b4cdde429805ff5ac8dd77a95569a7c4cb8991741b2ff0d538f220/backports_zstd-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:10b61850c4112952e05aa6e6cce8c9a5936fbeadb321e154216705cc76a14afa", size = 329078, upload-time = "2026-06-14T10:49:47.71Z" }, + { url = "https://files.pythonhosted.org/packages/ef/dc/e902a3f1eb92c4907b5f47f90cb3c2734ee315c4ff67179fc111343b45ba/backports_zstd-1.6.0-cp311-cp311-win_arm64.whl", hash = "sha256:068ef3d8c18815a2e3a752f766313e19910e7c50939b956923748d9c04ebcb1b", size = 291727, upload-time = "2026-06-14T10:49:48.929Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/009af3a9532d4cc66d5385391c512210fae32ab2442605f26aca1d8d2957/backports_zstd-1.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0466b14723f3b7697669c00ee66fe16e30e25636b286b0a923fa86fa3d8a753c", size = 437407, upload-time = "2026-06-14T10:49:50.155Z" }, + { url = "https://files.pythonhosted.org/packages/0c/76/f7c02efde81ebb9993586f9e435d2fd1191a6f806f640e4eeb8d004493ed/backports_zstd-1.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d146926e997d2d3de8212bdcbf4985344a2622ca3bec458d8908000a84fd883", size = 363519, upload-time = "2026-06-14T10:49:51.383Z" }, + { url = "https://files.pythonhosted.org/packages/2e/5e/0cf66f12472fe3e082cc4134395a7e0b8746cfb30aabd74251ce8fafa9a7/backports_zstd-1.6.0-cp312-cp312-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:460fd6b3f338c659507ae36cfd6b58ac9942a2ff233c5cf574416dfec0451a84", size = 507756, upload-time = "2026-06-14T10:49:52.497Z" }, + { url = "https://files.pythonhosted.org/packages/03/95/7ed25c90369360f96f8bfa961540845e063377c32a43b775201af66a588c/backports_zstd-1.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c2b1f4a640c51130caa92cef5bf72bd3c3dbbcfbf814c37403aa0601b1811b0", size = 477578, upload-time = "2026-06-14T10:49:53.887Z" }, + { url = "https://files.pythonhosted.org/packages/e3/75/f16b1d3e33ca396525847c81d96e3de7bc74d2c6f9ca2ddee76b0c450697/backports_zstd-1.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:beb43e9885202c8d4f3762319ed4d5e98e197622afbff8439fbbdd81d08938b9", size = 583029, upload-time = "2026-06-14T10:49:55.132Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2b/a17b111b631e1c79a0e570881c1a266c661b936585afa395435a458b1991/backports_zstd-1.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fbb746522ebfc11155f1cd688e2c48ef3d74125e38b63eabdaab068a055c3e88", size = 641741, upload-time = "2026-06-14T10:49:56.42Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b2/d17b2722c636d64b4e77ddc68d8d0625719d39f94021be8719a218af4c0a/backports_zstd-1.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a99710fbb225d459d66def4dc2bb2cd4a9a0bdc8b799fc0621cfdd863be9c93", size = 495554, upload-time = "2026-06-14T10:49:57.652Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/2853e8b6c03f03795b6548ea61f82cc104d4f7ff2523a04bc69f46984663/backports_zstd-1.6.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f69365ee2b836939137de024a302395a1cb8654fb6dc5ffef6381105259c8f87", size = 570027, upload-time = "2026-06-14T10:49:59.003Z" }, + { url = "https://files.pythonhosted.org/packages/18/aa/83f37b81f3b8c6ea035bf260ec374648bd59372894c02323dc9de3cbdf77/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:66cf8038893c7708ec345ffb3ac63c775d10f430f323ac2f0334fdb6a397c57c", size = 483594, upload-time = "2026-06-14T10:50:00.49Z" }, + { url = "https://files.pythonhosted.org/packages/f5/6a/d77f8cd2ff642d3b3652c1ccab5b6583114dbf10f8cb0143531357c83998/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e514c71ca72f3b56bd8fbda1a6a5b7d1100a2764b42a3c74a38841f25f9b00ab", size = 511206, upload-time = "2026-06-14T10:50:01.86Z" }, + { url = "https://files.pythonhosted.org/packages/56/b2/99a60fe4d1aac8053769d2463271d5df37a7c11c387072fdbb0b16aed7f7/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7741e44f7938ec94f9a52678c8d19b7bc548522ffdc39c9e4481af8db545fa9a", size = 587416, upload-time = "2026-06-14T10:50:03.236Z" }, + { url = "https://files.pythonhosted.org/packages/ec/1e/a9c003fe4d14bd4bf671598d4c7dcc1cef51e3513d9d7111ba1d07b6f07b/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:97e8a9674652496c7612b528085dd5a296c052a2edc466ca1bfb7b0b27820413", size = 567615, upload-time = "2026-06-14T10:50:04.524Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b9/955bd604f692c550c7cb66d00bd7691ead5c86df8ebd23d7254eeaa90789/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:23a793f2fed4dbf0517319759a2cded0b0dd8e8d3797fe30badd5693e320c175", size = 632269, upload-time = "2026-06-14T10:50:05.86Z" }, + { url = "https://files.pythonhosted.org/packages/18/d7/9f61f612f8a4193484c78a1f26db82a50141234189885113ef0085a8a961/backports_zstd-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b951113113ed4b8d173418a4f155c14b739dace626b3fa3f82be1831958d39e4", size = 500066, upload-time = "2026-06-14T10:50:07.446Z" }, + { url = "https://files.pythonhosted.org/packages/81/a3/19fb8c48d94139481c5ccaf2fb54c31b543fa635fd7bd7399aadd15752ac/backports_zstd-1.6.0-cp312-cp312-win32.whl", hash = "sha256:6430b34a2ae6fcc604672f4f913102563473d9a015bdca1ce8c95041cc1f2677", size = 291825, upload-time = "2026-06-14T10:50:08.762Z" }, + { url = "https://files.pythonhosted.org/packages/58/38/40ba081c6c71f0f22c64d3d54b912ad75a4e6812caa1397cbb15b5693b12/backports_zstd-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:08793876172551a930ce4d65c712cd516184d1a97070d4a1193e05bf0cf7040d", size = 329201, upload-time = "2026-06-14T10:50:09.979Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6c/f7116dd2edc6f960545f0d8616939eae3a20031b3b6669697d4f9fd83b2e/backports_zstd-1.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:03b7c59c71f7a597e2bcb3f8368371e9a660a1bdf1c37afc1f1ad1496a013c19", size = 291901, upload-time = "2026-06-14T10:50:11.198Z" }, + { url = "https://files.pythonhosted.org/packages/38/06/c430537d59c55d49bcd15ecf4b1aa965453219caad810a4f2b484816f4be/backports_zstd-1.6.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:2ace939e4d620e119423606f2d3d7115f8707733bf57f279ad9a9383f875986f", size = 400327, upload-time = "2026-06-14T10:50:12.446Z" }, + { url = "https://files.pythonhosted.org/packages/36/48/2f8323bb0e3ebba88b54877a2979afeb83983fb2ca572f09ad61aae2d3a0/backports_zstd-1.6.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:4c68a9ed2df0cca51d774c521e68a34d2e3d9ebfc687ef8096adfd4f345b551d", size = 454276, upload-time = "2026-06-14T10:50:13.667Z" }, + { url = "https://files.pythonhosted.org/packages/7c/39/87a665244a65f5b87a06b848c29a8cce07e91d59c5988ee2a32c0293a21c/backports_zstd-1.6.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:30576f49b82328ec8af16c11100efe52ca88526f71bbe100ef6b4e707dc13bf2", size = 357457, upload-time = "2026-06-14T10:50:14.906Z" }, + { url = "https://files.pythonhosted.org/packages/7f/8b/854d4a47bb8b7a48bfb2ed381c7b03a70efb4fc49f0e4a1509b38a2e1727/backports_zstd-1.6.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b4bddfcfb6679215d6f4dc5f79a1f9301af339480d70527a14b57a1f2e6b6cbf", size = 366139, upload-time = "2026-06-14T10:50:16.399Z" }, + { url = "https://files.pythonhosted.org/packages/8f/de/c3af43eb8df6f2581e157e18a3e0121eadb826055b2fde3f91ec188689cb/backports_zstd-1.6.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:65048ed08c5124f05ff9f355ab9703014bb2dbe7f8d9948ce193685b1775f442", size = 446683, upload-time = "2026-06-14T10:50:17.633Z" }, + { url = "https://files.pythonhosted.org/packages/5c/39/87cf3d883d386c10ac52f5322604fb9afdd204229f4c47d4a820a839b8ff/backports_zstd-1.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5918fc6b31437208721276964323933cd86077b8d5b469c59c1b3fd2c8220a05", size = 436869, upload-time = "2026-06-14T10:50:19.113Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b6/9479e6f0f18824ad38e8d7dd85161ab0842a198be669421232925bb30960/backports_zstd-1.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4b6c8b02ab0ccb2431bb7bc238be91d158b308915e7b07937388e540466fe7e7", size = 363090, upload-time = "2026-06-14T10:50:20.302Z" }, + { url = "https://files.pythonhosted.org/packages/d9/74/a5e98fe108e17c91d9bc590a19e77f5d47d579e34d3f5bc098a949d6c27c/backports_zstd-1.6.0-cp313-cp313-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:711e6b98f8924e8b4a61ff97ab6321f33de024e1ed6a32f5123763aeda8459be", size = 507070, upload-time = "2026-06-14T10:50:21.536Z" }, + { url = "https://files.pythonhosted.org/packages/69/f5/392bb7dce7363b77bc5403060f418fad438b9cfdd3edd10d65cee7d8fd11/backports_zstd-1.6.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2ba9ac10fc393e5123a08802e0e895a107cb4a66b9973d2844dbd8a343111e59", size = 477200, upload-time = "2026-06-14T10:50:22.91Z" }, + { url = "https://files.pythonhosted.org/packages/e4/4d/dfb665806ba4f74bc48071d32006843b53568c4a17ff627a3061de5eaa09/backports_zstd-1.6.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2f723219335387d7546412d8141e0303590600949b4184a1391a0c6a3c756058", size = 582724, upload-time = "2026-06-14T10:50:24.28Z" }, + { url = "https://files.pythonhosted.org/packages/57/b2/beeca7393a8310debd82ee2f0ce5c1801e8d7cb673f7f226f4a0866ca238/backports_zstd-1.6.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:64b94d7a836568926a3309ff510c7f8261b881b341fd4992cabf4f0998878f8a", size = 643493, upload-time = "2026-06-14T10:50:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/38/26/ce90e9eed6f25aaa4a4fa305a2aaf2d2ad81fd69de8eb248ddd91c80d1e0/backports_zstd-1.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e39258a09b1c7ca70b5e94a5c5ccfe4700b4250b8077cfeab31d0f79565d4c9b", size = 492190, upload-time = "2026-06-14T10:50:27.205Z" }, + { url = "https://files.pythonhosted.org/packages/17/9b/37b9b146df1f5452419a96071a7017cbac212ec9b137d7a88ca46dc2aa9e/backports_zstd-1.6.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:15b1aae0f64cd742df4bba1d989d0a09a6ec619202543fdba684640454541fd3", size = 567432, upload-time = "2026-06-14T10:50:28.386Z" }, + { url = "https://files.pythonhosted.org/packages/06/66/81b30991be83237529f36335ac3682bce26409064b906ac6122874575196/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:25b5ddc789480072551af571a746e9500356b2aff0499861cf2ca07ea7431e68", size = 483021, upload-time = "2026-06-14T10:50:29.654Z" }, + { url = "https://files.pythonhosted.org/packages/49/2a/792c65dcc1e45eb0c1bdc012ee94b84867186bfe27a860d0813bd216f03b/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a13cfa3410a75e4cb87abdb669aaf79da861cb79299159054ff8f77b9671bc40", size = 510596, upload-time = "2026-06-14T10:50:31.657Z" }, + { url = "https://files.pythonhosted.org/packages/1d/22/01b92a600505620e4cb5f20429e181f30458b7207ca8b52ca5ca6068c35f/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2ddab55a5f54dec8acfad68ef70f1c704fd21919990ddc238afbd6f496e61c6a", size = 587143, upload-time = "2026-06-14T10:50:32.868Z" }, + { url = "https://files.pythonhosted.org/packages/d8/60/4672f5110b9eb01388cc6225a739e3a5fcd749a63a9c4c1450a04fa27113/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fa305a84087e10d7a85e8a8a3dcba8cdbda4868f2180173b264b7b488fd37c55", size = 565238, upload-time = "2026-06-14T10:50:34.173Z" }, + { url = "https://files.pythonhosted.org/packages/5c/3b/19928d60ea7d25820bf12ef88de74534ca85b56ff7cf13c1b0e74e3a3d7c/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:df27b57d214a3124fbe4e933ef5a903d4567f154260d9aece8c797a987f2a205", size = 633970, upload-time = "2026-06-14T10:50:35.506Z" }, + { url = "https://files.pythonhosted.org/packages/df/97/c4cecb3e0ff53563ef9819f0395d919ceaae9c5147392ac23bac7afdb20f/backports_zstd-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:28fecd73459d74910ae1987ab84b7bef690d3dd860948430dd5555108b006daf", size = 496539, upload-time = "2026-06-14T10:50:37.015Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f4/46b2f29d2938a80e56e61a19f11ab093f531a9f8cd0ec8eeaac1246bcd99/backports_zstd-1.6.0-cp313-cp313-win32.whl", hash = "sha256:3e689af303df287142770abe3a48bbefd24dab4a09da5807d0e1fa8c75bab026", size = 291451, upload-time = "2026-06-14T10:50:38.518Z" }, + { url = "https://files.pythonhosted.org/packages/d1/ad/b529f92166da61f496621345f95d2dc583c8ca5ac553c084a4ef6c12cd71/backports_zstd-1.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:b067b1ef9c8e41fb0882c828aa37829938b5c0dab067eca72b23fc24c563b9da", size = 329023, upload-time = "2026-06-14T10:50:39.742Z" }, + { url = "https://files.pythonhosted.org/packages/30/d8/6be904d20345fbebec583ca83676e01f30c76118b283eb666d8ec8291ca1/backports_zstd-1.6.0-cp313-cp313-win_arm64.whl", hash = "sha256:a838296f5b84c920172fb579cac894d255c1fc25457c7234613ddcfa385e49b7", size = 291636, upload-time = "2026-06-14T10:50:41.004Z" }, + { url = "https://files.pythonhosted.org/packages/f7/52/9ed88f528b9484f3847f07b9d1d014b496e048d391b4bc04cb0117bd71a5/backports_zstd-1.6.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6c73ae37dbf9207727ac095dedef864c05d836eaec962a47b3b64eaadaf1c6b6", size = 411126, upload-time = "2026-06-14T10:50:42.253Z" }, + { url = "https://files.pythonhosted.org/packages/fe/26/bf8093d117cb6c36202ee7a2127f672c7b0c81f0c104ce28124534b75efa/backports_zstd-1.6.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:839faf90a7eb525a401978dc925df8c44bd12526e8ba1529b9f8a7106e729637", size = 340643, upload-time = "2026-06-14T10:50:43.571Z" }, + { url = "https://files.pythonhosted.org/packages/17/10/55f0860ed359d290e0eadd410da47ae720a1acf0d8362149e22acbe63223/backports_zstd-1.6.0-pp310-pypy310_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:f8f5c1c7c69a4b00889e52d9304a918a5b49010f9645768eb5fd0ad404f790ba", size = 421696, upload-time = "2026-06-14T10:50:44.915Z" }, + { url = "https://files.pythonhosted.org/packages/7c/3e/8dd9cc6f3e697e4721e53d6b9ca8c95c9d51ad2e759e7fcee6885e5b71db/backports_zstd-1.6.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e80bceebc9b58e959bede9b26cafe15b5b9526f3533a6dd06330c5da73cb9329", size = 395239, upload-time = "2026-06-14T10:50:46.186Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bb/ab92f8599749cb6063416dd9f46e084004c4e8db68e2eb768283012a6d27/backports_zstd-1.6.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:79284c1dd702f4f24ed1a36e51555c907dd237b6c0d829595978f4089a2aeea9", size = 415202, upload-time = "2026-06-14T10:50:47.726Z" }, + { url = "https://files.pythonhosted.org/packages/2c/f4/dd3ef995f6b22e23da145ac3ecc91e1f1fc4cb572b7f95e6b2b11de16782/backports_zstd-1.6.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1e20b3ecd0a711be82e964aca28554eabbc31ee69a20e5e7b8fd42268af46212", size = 315722, upload-time = "2026-06-14T10:50:49Z" }, + { url = "https://files.pythonhosted.org/packages/e8/09/898fe2f8196fa7ab825f5fed786c68581fdac7d23a8e20baa0cc01cb2f0b/backports_zstd-1.6.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:aeef8563b82ed4af328f98e5041c1b4800d86f68f857ffd1577d4d47dc9aa6cd", size = 411023, upload-time = "2026-06-14T10:50:50.286Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ad/6ad9af1596ab5f284bb53954be41396e13d23c81cdfe3d945402e8ee0215/backports_zstd-1.6.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9cb75e33131946fabd6319061df3b8b1d588fe0963183280e9b5f49f7772fc09", size = 340554, upload-time = "2026-06-14T10:50:51.523Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/f083d7c8a4ee5d0bb21b4d3144e76de9f655ca4dd0bffcb95baa5bc47a62/backports_zstd-1.6.0-pp311-pypy311_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:ef132cfb638e9a86bd5dc07fb4e1cb895bc55bce6bb5e759366e8b160d0747e2", size = 421694, upload-time = "2026-06-14T10:50:52.917Z" }, + { url = "https://files.pythonhosted.org/packages/41/d7/693b20f3ccae2e05d166f98fe55b1657451170b72c804ed9f6b98df520be/backports_zstd-1.6.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab70eace272d6f122b121c057e436709b50a28abf30d97aab28433c08f4a4095", size = 395237, upload-time = "2026-06-14T10:50:54.448Z" }, + { url = "https://files.pythonhosted.org/packages/53/a1/484e0f9ec994bd2285d6747e7c8028350f1a177e9210bc57637898042d3b/backports_zstd-1.6.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:17efb3d11137de5166dd51eedab9c36ad633402acba386eee8d715213ea47e49", size = 415201, upload-time = "2026-06-14T10:50:55.854Z" }, + { url = "https://files.pythonhosted.org/packages/3c/56/70860ece85cd49b564305cbc22bf6c4183975427ff6dfe2097e855f5dd5e/backports_zstd-1.6.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:994167ff6551b9c1ce226e0aab16295b98c94507b5701aa60d2c32b7d50796b1", size = 315721, upload-time = "2026-06-14T10:50:57.074Z" }, +] + [[package]] name = "cattrs" version = "26.1.0" @@ -292,210 +402,220 @@ wheels = [ [[package]] name = "certifi" -version = "2026.4.22" +version = "2026.6.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" }, + { url = "https://files.pythonhosted.org/packages/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" }, ] [[package]] name = "cffi" -version = "2.0.0" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser", marker = "implementation_name != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", size = 184283, upload-time = "2025-09-08T23:22:08.01Z" }, - { url = "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", size = 180504, upload-time = "2025-09-08T23:22:10.637Z" }, - { url = "https://files.pythonhosted.org/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", size = 208811, upload-time = "2025-09-08T23:22:12.267Z" }, - { url = "https://files.pythonhosted.org/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", size = 216402, upload-time = "2025-09-08T23:22:13.455Z" }, - { url = "https://files.pythonhosted.org/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", size = 203217, upload-time = "2025-09-08T23:22:14.596Z" }, - { url = "https://files.pythonhosted.org/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", size = 203079, upload-time = "2025-09-08T23:22:15.769Z" }, - { url = "https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", size = 216475, upload-time = "2025-09-08T23:22:17.427Z" }, - { url = "https://files.pythonhosted.org/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", size = 218829, upload-time = "2025-09-08T23:22:19.069Z" }, - { url = "https://files.pythonhosted.org/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", size = 211211, upload-time = "2025-09-08T23:22:20.588Z" }, - { url = "https://files.pythonhosted.org/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", size = 218036, upload-time = "2025-09-08T23:22:22.143Z" }, - { url = "https://files.pythonhosted.org/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", size = 172184, upload-time = "2025-09-08T23:22:23.328Z" }, - { url = "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", size = 182790, upload-time = "2025-09-08T23:22:24.752Z" }, - { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, - { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, - { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, - { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, - { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, - { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, - { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, - { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, - { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, - { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, - { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, - { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, - { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, - { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, - { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, - { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, - { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, - { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, - { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, - { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, - { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, - { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, - { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, - { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, - { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, - { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, - { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, - { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, - { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, - { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, - { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, - { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, - { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, - { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, - { url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" }, - { url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" }, - { url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" }, - { url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" }, - { url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" }, - { url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" }, - { url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" }, - { url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" }, - { url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" }, - { url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" }, - { url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" }, - { url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" }, - { url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" }, - { url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" }, - { url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" }, - { url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" }, - { url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" }, - { url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" }, - { url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" }, - { url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" }, - { url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" }, - { url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/57/5f/ff100cae70ebe9d8df1c01a00e510e45d9adb5c1fdda84791b199141de97/cffi-2.1.0.tar.gz", hash = "sha256:efc1cdd798b1aaf39b4610bba7aad28c9bea9b910f25c784ccf9ec1fa719d1f9", size = 531036, upload-time = "2026-07-06T21:34:30.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/e9/6d7724983b3d5a0908dbf74f64038ade77c18646ff6636ec7894fd392ce1/cffi-2.1.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:b65f590ef2a44640f9a05dbb548a429b4ade77913ce683ac8b1480777658a6c0", size = 183837, upload-time = "2026-07-06T21:32:09.655Z" }, + { url = "https://files.pythonhosted.org/packages/69/aa/24580a278de21fd7322635556334d9b535f1cbc00b0a3919447cdf464c65/cffi-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164bff1657b2a74f0b6d54e11c9b375bc97b931f2ca9c43fcf875838da1570dd", size = 184226, upload-time = "2026-07-06T21:32:11.196Z" }, + { url = "https://files.pythonhosted.org/packages/88/a9/02cae418ec4beb282ace11958d9d4737793439d561fadc7e6d56f2e2b354/cffi-2.1.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:c941bb58d5a6e1c3892d86e42927ed6c180302f07e6d395d08c416e594b98b46", size = 211107, upload-time = "2026-07-06T21:32:12.328Z" }, + { url = "https://files.pythonhosted.org/packages/3b/30/c806937ed5e4c2c7ac30d9d6b76b5dc57ff8b75d83800d9bb11a8253cf2a/cffi-2.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a016194dbe13d14ee9556e734b772d8d67b947092b268d757fd4290e3ba2dfc2", size = 218733, upload-time = "2026-07-06T21:32:13.67Z" }, + { url = "https://files.pythonhosted.org/packages/f9/cf/398272b8bbfd58aa314fda5a7f1cdbb26d1d78ae324a11211521315dd1f0/cffi-2.1.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:03e9810d18c646077e501f661b682fbf5dee4676048527ca3cffe66faa9960dd", size = 205543, upload-time = "2026-07-06T21:32:15.148Z" }, + { url = "https://files.pythonhosted.org/packages/45/ca/f91641185cdd90c36d317a9dc7f85e88ef8682d8b300977baff5e23c35d8/cffi-2.1.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:19c54ac121cad98450b4896fa9a43ee0180d57bc4bc911a33db6cab1efab6cd3", size = 205460, upload-time = "2026-07-06T21:32:16.479Z" }, + { url = "https://files.pythonhosted.org/packages/38/66/04781a77b411f0bb5b234d62c1814754ab75ebe455ccff1b08e8d7aae98f/cffi-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d433a51f1870e43a13b6732f92aaf540ff77c2015097c78556f75a2d6c030e0", size = 218760, upload-time = "2026-07-06T21:32:17.98Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9a/bb1d5ed9c3fcae158e9f6391bf309c95d98c2ac37ed56573228471d0af5e/cffi-2.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3d7f118b5adbfdfead90c25822690b02bc8074fba949bb7858bec4ebd55adb43", size = 221230, upload-time = "2026-07-06T21:32:19.407Z" }, + { url = "https://files.pythonhosted.org/packages/41/aa/3c1409cdd26094efacd1c36c66e0a6eb9d4296e4fd4f9901b8b2042f4323/cffi-2.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c5f5df567f6eb216de69be06ce55c8b714090fae02b18a3b40da8163b8c5fa9c", size = 213524, upload-time = "2026-07-06T21:32:20.828Z" }, + { url = "https://files.pythonhosted.org/packages/fa/75/74dfb7c3fc6ebbd408038476bd4c1d7e925c62614e7b9c534ecc34218288/cffi-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:11b3fb55f4f8ad92274ed26705f65d8f91457de71f5380061eb6d125a768fecd", size = 220341, upload-time = "2026-07-06T21:32:21.9Z" }, + { url = "https://files.pythonhosted.org/packages/70/b6/9003c33a3e7d2c1306f5962e646457dcfe5a8cd8fce6bbe02d7af25db783/cffi-2.1.0-cp310-cp310-win32.whl", hash = "sha256:9d72af0cf10a76a600a9690078fe31c63b9588c8e86bf9fd353f713c84b5db0f", size = 174578, upload-time = "2026-07-06T21:32:23.073Z" }, + { url = "https://files.pythonhosted.org/packages/8a/26/710688310447531c7a22f857c7f79d9855ec18b03e04494ced723fb37e2f/cffi-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb62edb5bb52cca65fab91a63afa7561607120d26090a7e8fda6fb9f064726da", size = 185071, upload-time = "2026-07-06T21:32:24.671Z" }, + { url = "https://files.pythonhosted.org/packages/d3/67/85c89a59ba36a671e79638f44d466749f08179266a57e4f2ffdf92174072/cffi-2.1.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:02cb7ff33ded4f1532476731f89ede53e2e488a8e6205515a82144246ffa7dcc", size = 183845, upload-time = "2026-07-06T21:32:26.32Z" }, + { url = "https://files.pythonhosted.org/packages/ea/dd/e3b0baa2d3d6a857ac72b7efbf18e32e487c9cdafcc13049ad765495b15e/cffi-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f5bce581e6b8c235e566a14768a943b172ada3ed73537bb0c0be1edee312d4e7", size = 184186, upload-time = "2026-07-06T21:32:28.025Z" }, + { url = "https://files.pythonhosted.org/packages/65/68/9f3ef890cf3c6ab97bd531c5677f67613d302165d16f8142b2811782a614/cffi-2.1.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:30b65779d598c370374fefabf138d456fd6f3216bfa7bedfab1ba82025b0cd93", size = 211892, upload-time = "2026-07-06T21:32:29.565Z" }, + { url = "https://files.pythonhosted.org/packages/22/d7/1a74539db16d8bfd839ff1515948948efbb162e574650fd3d846896eea95/cffi-2.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88023dfe18799507b73f1dbb0d14326a17465de1bc9c9c7655c22845e9ddc3a2", size = 218793, upload-time = "2026-07-06T21:32:30.951Z" }, + { url = "https://files.pythonhosted.org/packages/ec/d1/9a5b7169499e8e8d8e636de70b97ac7c9447104d2ff1a2cd94790cea5162/cffi-2.1.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:0a96b74cda968eebbad56d973efe5098974f0a9fb323865bf99ea1fd24e3e64c", size = 205737, upload-time = "2026-07-06T21:32:32.216Z" }, + { url = "https://files.pythonhosted.org/packages/ba/b0/e131a9c41f10607926278453d9596163594fe1c4ebc46efe3b5e5b34eb84/cffi-2.1.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a5781494d4d400a3f47f8f1da94b324f6e6b440a53387774002890a2a2f4b50f", size = 204909, upload-time = "2026-07-06T21:32:33.655Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d2/4398416cd699b35167947c6e22aca52c47e69ad5695073c9f1f2c52e04aa/cffi-2.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aa7a1b53a2a4452ada2d1b5dade9960b2522f1e61293a811a077439e39029565", size = 217883, upload-time = "2026-07-06T21:32:35.173Z" }, + { url = "https://files.pythonhosted.org/packages/a2/a5/d4fe77b589e5e82d43ebc809bf2e6474afe8e48e32ea050b9357645b6471/cffi-2.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d8272c0e483b024e1b9ad029821470ed8ec65631dbd90217469da0e7cd89f1c", size = 221251, upload-time = "2026-07-06T21:32:36.527Z" }, + { url = "https://files.pythonhosted.org/packages/22/f0/a2fc43084c0433caf7f461bccc013e28f848d04ee1c5ed7fce71423cf4d9/cffi-2.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7762faa47e8ff7eb80bd261d9a7d8eea2d8baa69de5e95b70c1f338bbe712f02", size = 214250, upload-time = "2026-07-06T21:32:37.852Z" }, + { url = "https://files.pythonhosted.org/packages/04/8c/b925975448cf20634a9fbd5efceb807219db452653648d2897c0989cab2d/cffi-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:89095c1968b4ba8285840e131bf2891b09ae137fe2146905acae0354fbce1b5e", size = 219441, upload-time = "2026-07-06T21:32:39.146Z" }, + { url = "https://files.pythonhosted.org/packages/eb/da/5c4918a2d61d86fa927d716cb3d8e4626ef8dc8f605a599d32f33897f59a/cffi-2.1.0-cp311-cp311-win32.whl", hash = "sha256:64c753a0f87a256020004f37a1c8c02c480e725f910f0b2a0f3f07debd1b2479", size = 174496, upload-time = "2026-07-06T21:32:40.467Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c8/6c2de1d55cf35ef8b92885d5ef280790f0fb9634d87ea1cc315176aecd61/cffi-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:4f26194e3d95e06501b942642855aed4f953d55e95d7d01b7c4483db3ecff458", size = 185113, upload-time = "2026-07-06T21:32:41.761Z" }, + { url = "https://files.pythonhosted.org/packages/9e/4e/e8d7cb5783f1841a3c8fb3a7735838d7484d08ec08c9f984b14cac1ac0e9/cffi-2.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:35aaea0c7ee0e58a5cd8c2fd1a48fdf7ece0d2699b7ecdda08194e9ce5dd9b3d", size = 179927, upload-time = "2026-07-06T21:32:42.961Z" }, + { url = "https://files.pythonhosted.org/packages/1e/85/990925db5df586ec90beb97529c853497e7f85ba0234830447faf41c3057/cffi-2.1.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:df2b82571a1b30f58a87bf4e5a9e78d2b1eff6c6ce8fd3aa3757221f93f0863f", size = 184829, upload-time = "2026-07-06T21:32:44.324Z" }, + { url = "https://files.pythonhosted.org/packages/4b/92/e7bb136ad6b5352603732cf907ef862ca103f20f2031c1735a46300c20c9/cffi-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78474632761faa0fb96f30b1c928c84ebcf68713cbb80d15bab09dfe61640fde", size = 184728, upload-time = "2026-07-06T21:32:45.683Z" }, + { url = "https://files.pythonhosted.org/packages/c3/c0/d1ec30ffb370f748f2fb54425972bfef9871e0132e82fb589c46b6676049/cffi-2.1.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:5972433ad71a9e46516584ef60a0fda12d9dc459938d1539c3ddecf9bdc1368d", size = 214815, upload-time = "2026-07-06T21:32:48.557Z" }, + { url = "https://files.pythonhosted.org/packages/1b/dc/5620cf930688be01f2d673804291de757a934c90b946dbdc3d84130c2ea4/cffi-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b6422532152adf4e59b110cb2808cee7a033800952f5c036b4af047ee43199e7", size = 222429, upload-time = "2026-07-06T21:32:49.848Z" }, + { url = "https://files.pythonhosted.org/packages/4b/a4/77b53abbf7a1e0beb9637edbef2a94d15f9c822f591e85d439ffd91519a6/cffi-2.1.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:46b1c8db8f6122420f32d02fffb924c2fe9bc772d228c7c711748fff56aabb2b", size = 210315, upload-time = "2026-07-06T21:32:51.221Z" }, + { url = "https://files.pythonhosted.org/packages/58/0c/f528df19cc94b675087324d4760d9e6d5bfae97d6217aa4fac43de4f5fcc/cffi-2.1.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9fafc5aa2e2a39aaf7f8cc0c1f044a9b07fca12e558dca53a3cc5c654ad67a7", size = 208859, upload-time = "2026-07-06T21:32:52.512Z" }, + { url = "https://files.pythonhosted.org/packages/62/f2/c9522a81c32132799a1972c39f5c5f8b4c8b9f00488a23feaa6c06f07741/cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1e9f50d192a3e525b15a75ab5114e442d83d657b7ec29182a991bc9a88fd3a66", size = 221844, upload-time = "2026-07-06T21:32:53.704Z" }, + { url = "https://files.pythonhosted.org/packages/6e/28/bd53988b9833e8f8ad539d26f4c07a6b3f6bcb1e9e02e7ca038250b3428d/cffi-2.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98fff996e983a36d3aa2eca83af40c5821202e7e6f32d13ae94e3d2286f10cfe", size = 225287, upload-time = "2026-07-06T21:32:54.907Z" }, + { url = "https://files.pythonhosted.org/packages/79/99/0d0fd37f055224085f42bbb2c022d002e17dde4a97972822327b07d84101/cffi-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:379de10ce1ba048b1448599d1b37b24caee16309d1ac98d3982fc997f768700b", size = 223681, upload-time = "2026-07-06T21:32:56.329Z" }, + { url = "https://files.pythonhosted.org/packages/b0/80/c138990aa2a70b1a269f6e06348729836d733d6f970867943f61d367f8cc/cffi-2.1.0-cp312-cp312-win32.whl", hash = "sha256:9b8f0f26ca4e7513c534d351eca551947d053fac438f2a04ac96d882909b0d3a", size = 175269, upload-time = "2026-07-06T21:32:57.777Z" }, + { url = "https://files.pythonhosted.org/packages/a8/eb/f636456ff21a83fc13c032b58cc5dde061691546ac79efa284b2989b7982/cffi-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:c97f080ea627e2863524c5af3836e2270b5f5dfff1f104392b959f8df0c5d384", size = 185881, upload-time = "2026-07-06T21:32:59.253Z" }, + { url = "https://files.pythonhosted.org/packages/dd/2c/400ea43e721727dca8a65c4521390e9196757caba4a45643acb2b63271b8/cffi-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:6d194185eabd279f1c05ebe3504265ddfc5ad2b58d0714f7db9f01da592e9eb6", size = 180088, upload-time = "2026-07-06T21:33:02.278Z" }, + { url = "https://files.pythonhosted.org/packages/96/88/a996879e2eeccb815f6e3a5967b12a308257412acec882039d386bd2aa7b/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:10537b1df4967ca26d21e5072d7d54188354483b91dc75058968d3f0cf13fbda", size = 194331, upload-time = "2026-07-06T21:33:03.697Z" }, + { url = "https://files.pythonhosted.org/packages/58/85/7ae00d5c8dd6266f4e944c3db630f3c5c9a98b61d469c714d848b1d8138a/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a95b05f9baf29b91171b3a8bd2020b028835243e7b0ff6bb23e2a3c228518b1b", size = 196966, upload-time = "2026-07-06T21:33:05.353Z" }, + { url = "https://files.pythonhosted.org/packages/8c/e9/45c3a76ad8d43ad9261f4c95436da61128d3ca545d72b9612c0ab5be0b1c/cffi-2.1.0-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:15faec4adfff450819f3aee0e2e02c812de6edb88203aa58807955db2003472a", size = 184795, upload-time = "2026-07-06T21:33:06.699Z" }, + { url = "https://files.pythonhosted.org/packages/84/4c/82f132cb4418ee6d953d982b19191e87e2a6372c8a4ce36e50b69d6ade4a/cffi-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:716ff8ec22f20b4d988b12884086bcef0fc99737043e503f7a3935a6be99b1ea", size = 184746, upload-time = "2026-07-06T21:33:08.071Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1c/4ed5a0e5bdca6cbc275556de3328dd1b76fd0c11cc13c88fe66d1d8715f2/cffi-2.1.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:63960549e4f8dc41e31accb97b975abaecfc44c03e396c093a6436763c2ea7db", size = 214747, upload-time = "2026-07-06T21:33:09.671Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a6/e879bb68cc23a2bc9ba8f4b7d8019f0c2694bad2ab6c4a3701d429439f58/cffi-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff067a8d8d880e7809e4ac88eb009bb848870115317b306666502ccad30b147f", size = 222392, upload-time = "2026-07-06T21:33:10.896Z" }, + { url = "https://files.pythonhosted.org/packages/88/f6/01890cfd63c08f8eb96a8319b0443690197d240a8bd6346048cf7bde9190/cffi-2.1.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3b926723c13eba9f81d2ef3820d63aeceec3b2d4639906047bf675cb8a7a500d", size = 210285, upload-time = "2026-07-06T21:33:12.251Z" }, + { url = "https://files.pythonhosted.org/packages/a6/cf/2b684132056f438567b61e19d690dd31cd0921ace051e0a458be6074369e/cffi-2.1.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:47ff3a8bfd8cb9da1af7524b965127095055654c177fcfc7578debcb015eecd0", size = 208801, upload-time = "2026-07-06T21:33:13.617Z" }, + { url = "https://files.pythonhosted.org/packages/6f/08/f2e7d62c460faae0926f2d6e423694aa409ced3bc1fe2927a0a6e5f05416/cffi-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:799416bae98336e400981ff6e532d67d5c709cfb30afb79865a1315f94b0e224", size = 221808, upload-time = "2026-07-06T21:33:15.466Z" }, + { url = "https://files.pythonhosted.org/packages/38/37/04f54b8e63a02f3d908332c9effbf8c366167c6f733ed8a3d4f79b7e2a1e/cffi-2.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:961be50688f7fba2fa65f63712d3b9b341a22311f5253460ce933f52f0de1c8c", size = 225241, upload-time = "2026-07-06T21:33:16.869Z" }, + { url = "https://files.pythonhosted.org/packages/a9/d6/c72eecca433cd3e681c65ed313ab4835d9d4a379704d0f628a6a05f51c2e/cffi-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf5c6cf48238b0eb4c086978c492ad1cbc22373fc5b2d7353b3a598ce6db887a", size = 223588, upload-time = "2026-07-06T21:33:18.239Z" }, + { url = "https://files.pythonhosted.org/packages/c6/4b/e706f67279140f92939da3475ad610df18bfd52d50f14953a8e5fede71d5/cffi-2.1.0-cp313-cp313-win32.whl", hash = "sha256:db3eb7d46527159a878ec3460e9d40615bc25ba337d477db681aea6e4f05c5d2", size = 175248, upload-time = "2026-07-06T21:33:19.799Z" }, + { url = "https://files.pythonhosted.org/packages/5a/47/59eb7975cb0e4ef0afa764ea945b29a5bb4537a9f771cb7d6c8a5dd74c95/cffi-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:8e74a6135550c4748af665b1b1118b6aab33b1fc6a16f9aff630af107c3b4512", size = 185717, upload-time = "2026-07-06T21:33:21.47Z" }, + { url = "https://files.pythonhosted.org/packages/5a/af/34fee85c48f8d94efc8597bc09470c9dd274c145f1c12e0fbc6ab6d38d74/cffi-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:2282cd5e38aa8accd03e99d1256af8411c84cdbee6a89d841b563fdbd1f3e50f", size = 180114, upload-time = "2026-07-06T21:33:22.515Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f0/81478e482afa03f6d18dc8f2afb5edc45b3080853b634b5ed91961be0998/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d2117334c3af3bdcb9a88522b844a2bdb5efdc4f71c6c822df55486ae1c3347a", size = 194142, upload-time = "2026-07-06T21:33:23.657Z" }, + { url = "https://files.pythonhosted.org/packages/7d/95/8de304305cd9204974b0ca051b86d307cafca13aa575a0ef1b44d92c0d8c/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:702c436735fbe99d59ada02a1f65cfc0d31c0ee8b7290912f8fbc5cd1e4b16c3", size = 196819, upload-time = "2026-07-06T21:33:25.007Z" }, + { url = "https://files.pythonhosted.org/packages/20/71/7c8372d30e42415602ed9f268f7cfd66f1b855fed881ecd168bcb45dbc0b/cffi-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1ff3456eab0d889592d1936d6125bbfbc7ae4d3354a700f8bd80450a66445d4d", size = 184965, upload-time = "2026-07-06T21:33:26.605Z" }, + { url = "https://files.pythonhosted.org/packages/d6/5c/584e626835f0375c928176c04137c96927165cb8733cdb3150ec04e5ee5e/cffi-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c4165821e131d6d4ca444347c2b694e2311bcfa3fe5a861cc72968f28867beac", size = 184952, upload-time = "2026-07-06T21:33:27.823Z" }, + { url = "https://files.pythonhosted.org/packages/2e/d2/065fcae1c73979fac8e054462478d0ff8a29c40cdc2ed7ea5676a061df53/cffi-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:276f20fffd7b396e12516ba8edf9509210ac248cbbc5acbc39cd512f9f59ebe6", size = 222353, upload-time = "2026-07-06T21:33:29.178Z" }, + { url = "https://files.pythonhosted.org/packages/ed/a5/e8bbb1ce5b3ac2f53ad6a10bde44318a5a8d99d4f4a000d44a6e39aeb3e4/cffi-2.1.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7d5980a3433d4b71a5e120f9dd551403d7824e31e2e67124fe2769c404c06913", size = 210051, upload-time = "2026-07-06T21:33:30.534Z" }, + { url = "https://files.pythonhosted.org/packages/28/ed/c127d3ac36e899c965e3361357c3befacd6578c03f40125183e41c3b219e/cffi-2.1.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6ca4919c6e4f89aa99c42510b42cf54596892c00b3f9077f6bdd1505e24b9c8d", size = 208630, upload-time = "2026-07-06T21:33:31.753Z" }, + { url = "https://files.pythonhosted.org/packages/cc/d7/97d3136f81db489ec8d1d67748c110d6c994268fd7528014aa9f2b085e4e/cffi-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d53d10f7da99ae46f7373b9150393e9c5eab9b224909982b43832668de4779f5", size = 221593, upload-time = "2026-07-06T21:33:33.044Z" }, + { url = "https://files.pythonhosted.org/packages/d3/27/93195977168ee63aed233a1a0993a2178798654d1f4bddcdd321d6fd3b21/cffi-2.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c351efb95e832a853a29361675f33a7ce53de1a109cd73fd47af0712213aa4ce", size = 225146, upload-time = "2026-07-06T21:33:34.224Z" }, + { url = "https://files.pythonhosted.org/packages/b3/c1/6dbd291ee2ae5a50a034aa057207081f545923bbf15dad4511e985aafff5/cffi-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:dbf7c7a88e2bac086f06d14577332760bdeecc42bdec8ac4077f6260557d9326", size = 223240, upload-time = "2026-07-06T21:33:35.57Z" }, + { url = "https://files.pythonhosted.org/packages/0f/6f/ade5ce9863a57992a6ea3d0d10d7e29b8749fc127204b3d493d667b2815f/cffi-2.1.0-cp314-cp314-win32.whl", hash = "sha256:1854b724d00f6654c742097d5387569021be12d3a0f770eae1df8f8acfcc6acd", size = 177723, upload-time = "2026-07-06T21:33:51.626Z" }, + { url = "https://files.pythonhosted.org/packages/41/de/92b9eeed4ae4a21d6fd9b2a2c8505cbed573299902ea73981cc13f7ff62c/cffi-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:1b96bfe2c4bd825681b7d311ad6d9b7280a091f43e8f63da5729638083cd3bfb", size = 187937, upload-time = "2026-07-06T21:33:53.403Z" }, + { url = "https://files.pythonhosted.org/packages/2e/1a/cc6ae6c2913a03aab8898eee57963cf1035b8df5872ed8b9115fcc7e2be8/cffi-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:7d28dff1db6764108bc30788d85d61c876beff416d9a49cb9dd7c5a9f34f5804", size = 183001, upload-time = "2026-07-06T21:33:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/14/f0/134c00ce0779ec86dea2aa1aac69339c2741a8045072676763512363a2ea/cffi-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7ea6b3e2c4250ff1de21c630fe72d0f63eb95c2c32ffbf64a358cf4a8836d714", size = 188538, upload-time = "2026-07-06T21:33:36.792Z" }, + { url = "https://files.pythonhosted.org/packages/50/d8/3b86aba791cb610d24e8a3e1b2cd529e71fa15096b04e4d4e360049d4a4c/cffi-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6af371f3767faeffc6ac1ef57cdfd25844403e9d3f476c5537caee499de96376", size = 188230, upload-time = "2026-07-06T21:33:38.011Z" }, + { url = "https://files.pythonhosted.org/packages/14/d0/117dcd9209255ad8571fbc8c92ef32593a1d294dcec91ddc4e4db50606f2/cffi-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb4e8997a49aa2c08a3e43c9045d224448b8941d88e7ac163c7d383e560cbf98", size = 223899, upload-time = "2026-07-06T21:33:39.514Z" }, + { url = "https://files.pythonhosted.org/packages/b6/3d/f20f8b886b254e3ad10e15cd4186d3aed49f3e6a35ab37aab9f8f25f7c03/cffi-2.1.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:bf01d8c84cbea96b944c73b22182e6c7c432b3475632b8111dbfdc95ddad6e13", size = 211652, upload-time = "2026-07-06T21:33:40.851Z" }, + { url = "https://files.pythonhosted.org/packages/28/3b/fad54de07260b93ddeef4b96d0131d57ea900675df1d410ae1deee52d7a6/cffi-2.1.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:33eb1ad83ebe8f313e0df035c406227d55a79456704a863fad9842136af5ad7d", size = 210755, upload-time = "2026-07-06T21:33:42.183Z" }, + { url = "https://files.pythonhosted.org/packages/cc/82/3d5c705acb7abbba9bbd7d79b8e62e0f25b6120eb7ae6ac49f1b721722fe/cffi-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ac0f1a2d0cfa7eea3f2aaf006ab6e70e8feeb16b75d65b7e5939982ca2f11056", size = 223933, upload-time = "2026-07-06T21:33:43.603Z" }, + { url = "https://files.pythonhosted.org/packages/6c/d0/47e338384ab6b1004241002fa616301020cea4fc95f283506565d252f276/cffi-2.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c16914df9fb7f500e440e6875fa23ff5e0b31db01fa9c06af98d59a91f0dc2e4", size = 226749, upload-time = "2026-07-06T21:33:45.046Z" }, + { url = "https://files.pythonhosted.org/packages/70/25/65bd5b58ea4bfdfc15cde02cb5365f89ef8ab8b2adfb8fe5c4bd4233382f/cffi-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5ecbd0499275d57506d397eebe1981cee87b47fcd9ef5c22cab7ed7644a39a94", size = 225703, upload-time = "2026-07-06T21:33:46.374Z" }, + { url = "https://files.pythonhosted.org/packages/dc/78/aa01ac599a8a4322533d45a1f9bc93b338276d2d59dabbe7c6d92a775c81/cffi-2.1.0-cp314-cp314t-win32.whl", hash = "sha256:7d034dcffa09e9a46c93fa3a3be402096cb5354ac6e41ab8e5cc9cd8b642ad76", size = 182857, upload-time = "2026-07-06T21:33:47.696Z" }, + { url = "https://files.pythonhosted.org/packages/b9/26/d00496b22de4d4228f32dde94ad996f350c8aad676d63bcca0743c8dea4d/cffi-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0582a58f3051372229ca8e7f5f589f9e5632678208d8636fea3676711fdf7fe5", size = 194065, upload-time = "2026-07-06T21:33:48.953Z" }, + { url = "https://files.pythonhosted.org/packages/d5/dd/0c7dbf815a579ff005008a2d815a55d6bb047c349eef536d9dc53d3f0a8d/cffi-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:510aeeeac94811b138077451da1fb18b308a5feab47dd2b603af55804155e1c8", size = 186404, upload-time = "2026-07-06T21:33:50.309Z" }, + { url = "https://files.pythonhosted.org/packages/55/c7/8c8c50cb11c6750051daf12164098a9a6f027ac4356967fd4d800a07f242/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:2e9dabb9abcb7ad15938c7196ad5c1718a4e6d33cc79b4c0209bdb64c4a54a5c", size = 194121, upload-time = "2026-07-06T21:33:56.109Z" }, + { url = "https://files.pythonhosted.org/packages/99/e2/67680bf19a6b60d2bb7ff83baefa2a4c3d2d7dc0f3277034b802e1fc504c/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:37f525a7e7e50c017fdebe58b787be310ad59357ae43a053943a6e1a6c526001", size = 196820, upload-time = "2026-07-06T21:33:57.288Z" }, + { url = "https://files.pythonhosted.org/packages/ed/da/4bbe583a3b3a5c8c60892124fe17f3fa3656523faf0d3484eae90f091853/cffi-2.1.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:95f2954c2c9473d892eca6e0409f3568b37ab62a8eedb122461f73cc273476e3", size = 184936, upload-time = "2026-07-06T21:33:58.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/4b/1f4c36ab273980d7aa75bb126ea4f8971f24a96108acad3a0a084028c57b/cffi-2.1.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:cdf2448aab5f661c9315308ec8b93f4e8a1a67a3c733f8631067a2b67d5913dc", size = 185045, upload-time = "2026-07-06T21:34:00.085Z" }, + { url = "https://files.pythonhosted.org/packages/ef/c3/ad299dc38f3583f8d916b299f028af418a9ec98bc695fcbebeae7420691c/cffi-2.1.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:90bec57cf82089383bd06a605b3eb8daebf7e5a668520beaf6e327a83a947699", size = 222342, upload-time = "2026-07-06T21:34:01.814Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d8/df4543cc087245044ed02ef3ad8e0a26619d0075ac7a77a12dc81177851b/cffi-2.1.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6274dcb2d15cef48daa73ed1be5a40d501d74dccd0cd6db364776d12cb6ba022", size = 210073, upload-time = "2026-07-06T21:34:03.255Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0e/fac738d73728c6cea2a88a2883dca54892496cbba88a1dc1f2909cb8a6f5/cffi-2.1.0-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:2b71d409cccee78310ab5dec549aed052aaea483346e282c7b02362596e01bb0", size = 208551, upload-time = "2026-07-06T21:34:04.433Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3f/0b04a700dd64f465c93020253a793a82c9b4dff9961f48facd0df945d9b8/cffi-2.1.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7d3538f9c0e50670f4deb93dbb696576e60590369cae2faf7de681e597a8a1f1", size = 221649, upload-time = "2026-07-06T21:34:06.157Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/b7379a5704c79eda57ce075869ba70a0368d1c850f803b3c0d078d39dcaf/cffi-2.1.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:8f9ec95b8a043d3dfbc74d9abc6f7baf524dd27a8dc160b0a32ff9cdab650c28", size = 225203, upload-time = "2026-07-06T21:34:07.489Z" }, + { url = "https://files.pythonhosted.org/packages/5a/02/d5e6c43ea85c41bda2a184a3418f195fe7cf602967a8d2b94e085b83deef/cffi-2.1.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:af5e2915d41fe6c961694d7bfdc8562942638200f3ce2765dfb8b745cf997629", size = 223263, upload-time = "2026-07-06T21:34:08.712Z" }, + { url = "https://files.pythonhosted.org/packages/2c/d8/772b8259bf75749adffb1c546828978381fb516f60cf701f6c83daf60c85/cffi-2.1.0-cp315-cp315-win32.whl", hash = "sha256:0a42c688d19fca6e095a53c6a6e2295a5b050a8b289f109adab02a9e61a25de6", size = 177696, upload-time = "2026-07-06T21:34:26.355Z" }, + { url = "https://files.pythonhosted.org/packages/2f/dd/afa2191fc6d57fedd26e5844a2fe2fcc0bbfa00961bbaa5a41e4921e7cca/cffi-2.1.0-cp315-cp315-win_amd64.whl", hash = "sha256:bccbbb5ee76a61f9d99b5bf3846a51d7fca4b6a732fe46f89295610edaf41853", size = 187914, upload-time = "2026-07-06T21:34:27.58Z" }, + { url = "https://files.pythonhosted.org/packages/05/ef/6cd4f8c671517162379dc79cfae5aea9106bc38abb89628d5c16adf6a838/cffi-2.1.0-cp315-cp315-win_arm64.whl", hash = "sha256:8d35c139744adb3e727cd51b1a18324bbe44b8bd41bf8322bca4d41289f48eda", size = 183004, upload-time = "2026-07-06T21:34:28.905Z" }, + { url = "https://files.pythonhosted.org/packages/11/b6/12fc55092817a5faa26fb8c40c7f9d662e11a46ee248c137aafc42517d92/cffi-2.1.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:f9912624a0c0b834b7520d7769b3644453aabc0a7e1c839da7359f050750e9bc", size = 188378, upload-time = "2026-07-06T21:34:09.926Z" }, + { url = "https://files.pythonhosted.org/packages/8d/2e/cdac88979f295fde5daa69622c7d2111e56e7ceb94f211357fbe452339e4/cffi-2.1.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:df92f2aba50eb4d96718b68ef76f2e57a57b54f2fa62333496d16c6d585a85ca", size = 188319, upload-time = "2026-07-06T21:34:11.101Z" }, + { url = "https://files.pythonhosted.org/packages/e0/27/1d0b408497e41a74795af122d7b603c418c5fed0171450f899afd04e594f/cffi-2.1.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0520e1f4c35f44e209cbbb421b67eec42e6a157f59444dfb6058874ff3610e5d", size = 223904, upload-time = "2026-07-06T21:34:12.606Z" }, + { url = "https://files.pythonhosted.org/packages/8b/31/e115c985105dd7ffb32444505f18ceb874bb42d992af05d5dced7ecf1980/cffi-2.1.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3681e031db29958a7502f5c0c9d6bbc4c36cb20f7b104086fa642d1799631ff8", size = 211554, upload-time = "2026-07-06T21:34:13.987Z" }, + { url = "https://files.pythonhosted.org/packages/5a/67/9e6e09409336d9e515c58367e7cfcf4f89df06ad25252675595a58eb59d5/cffi-2.1.0-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:762f99479dcb369f60ab9017ad4ab97a36a1dd7c1ee5a3b15db0f4b8659120cd", size = 210795, upload-time = "2026-07-06T21:34:15.972Z" }, + { url = "https://files.pythonhosted.org/packages/19/e5/d3cc82a4a0be7902af279c04181ad038449c096734464a5ae1de3e1401bd/cffi-2.1.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0611e7ebf90573a535ebdc33ae9da222d037853983e13359f580fab781ca017f", size = 223843, upload-time = "2026-07-06T21:34:17.509Z" }, + { url = "https://files.pythonhosted.org/packages/b9/65/b434abc97ce7cecc2c640fde160507c0ecc7e21544b483ba3325d2e2ea17/cffi-2.1.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:86cf8755a791f72c85dc287128cc62d4f24d392e3f1e15837245623f4a33cccc", size = 226773, upload-time = "2026-07-06T21:34:19.05Z" }, + { url = "https://files.pythonhosted.org/packages/b5/9f/d4dc66ca651eb1145a133314cda721abf13cfac3d28c4a0402263ae6ad75/cffi-2.1.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:ba00f661f8ba35d075c937174e27c2c421cec3942fd2e0ea3e66996757c0fdd9", size = 225719, upload-time = "2026-07-06T21:34:20.576Z" }, + { url = "https://files.pythonhosted.org/packages/68/5a/e536c528bc8057496c360c0978559a2dc45653f89dd6151078aa7d8fca1a/cffi-2.1.0-cp315-cp315t-win32.whl", hash = "sha256:cb96698e3c7413d906ce83f8ffd245ec1bd94707541f299d0ce4d6b0193e982b", size = 182760, upload-time = "2026-07-06T21:34:22.059Z" }, + { url = "https://files.pythonhosted.org/packages/d3/0b/0ffe8b82d3875bced5fa1e7986a7a46b748262a40ab7f60b475eb9fb1bb3/cffi-2.1.0-cp315-cp315t-win_amd64.whl", hash = "sha256:f146d154428a2523f9cc7936c02353c2459b8f6cf07d3cd1ee1c0a611109c5d5", size = 193769, upload-time = "2026-07-06T21:34:23.589Z" }, + { url = "https://files.pythonhosted.org/packages/a0/17/1073b53b68c9b5ca6914adf5f8bf55aacc2d3be102418c90700160ea8605/cffi-2.1.0-cp315-cp315t-win_arm64.whl", hash = "sha256:cbb7640ce37159548d2147b5b8c241f962143d4c71231431820783f4dc78f210", size = 186405, upload-time = "2026-07-06T21:34:24.857Z" }, ] [[package]] name = "charset-normalizer" -version = "3.4.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/08/0f303cb0b529e456bb116f2d50565a482694fbb94340bf56d44677e7ed03/charset_normalizer-3.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cdd68a1fb318e290a2077696b7eb7a21a49163c455979c639bf5a5dcdc46617d", size = 315182, upload-time = "2026-04-02T09:25:40.673Z" }, - { url = "https://files.pythonhosted.org/packages/24/47/b192933e94b546f1b1fe4df9cc1f84fcdbf2359f8d1081d46dd029b50207/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e17b8d5d6a8c47c85e68ca8379def1303fd360c3e22093a807cd34a71cd082b8", size = 209329, upload-time = "2026-04-02T09:25:42.354Z" }, - { url = "https://files.pythonhosted.org/packages/c2/b4/01fa81c5ca6141024d89a8fc15968002b71da7f825dd14113207113fabbd/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:511ef87c8aec0783e08ac18565a16d435372bc1ac25a91e6ac7f5ef2b0bff790", size = 231230, upload-time = "2026-04-02T09:25:44.281Z" }, - { url = "https://files.pythonhosted.org/packages/20/f7/7b991776844dfa058017e600e6e55ff01984a063290ca5622c0b63162f68/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc", size = 225890, upload-time = "2026-04-02T09:25:45.475Z" }, - { url = "https://files.pythonhosted.org/packages/20/e7/bed0024a0f4ab0c8a9c64d4445f39b30c99bd1acd228291959e3de664247/charset_normalizer-3.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf29836da5119f3c8a8a70667b0ef5fdca3bb12f80fd06487cfa575b3909b393", size = 216930, upload-time = "2026-04-02T09:25:46.58Z" }, - { url = "https://files.pythonhosted.org/packages/e2/ab/b18f0ab31cdd7b3ddb8bb76c4a414aeb8160c9810fdf1bc62f269a539d87/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:12d8baf840cc7889b37c7c770f478adea7adce3dcb3944d02ec87508e2dcf153", size = 202109, upload-time = "2026-04-02T09:25:48.031Z" }, - { url = "https://files.pythonhosted.org/packages/82/e5/7e9440768a06dfb3075936490cb82dbf0ee20a133bf0dd8551fa096914ec/charset_normalizer-3.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d560742f3c0d62afaccf9f41fe485ed69bd7661a241f86a3ef0f0fb8b1a397af", size = 214684, upload-time = "2026-04-02T09:25:49.245Z" }, - { url = "https://files.pythonhosted.org/packages/71/94/8c61d8da9f062fdf457c80acfa25060ec22bf1d34bbeaca4350f13bcfd07/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b14b2d9dac08e28bb8046a1a0434b1750eb221c8f5b87a68f4fa11a6f97b5e34", size = 212785, upload-time = "2026-04-02T09:25:50.671Z" }, - { url = "https://files.pythonhosted.org/packages/66/cd/6e9889c648e72c0ab2e5967528bb83508f354d706637bc7097190c874e13/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:bc17a677b21b3502a21f66a8cc64f5bfad4df8a0b8434d661666f8ce90ac3af1", size = 203055, upload-time = "2026-04-02T09:25:51.802Z" }, - { url = "https://files.pythonhosted.org/packages/92/2e/7a951d6a08aefb7eb8e1b54cdfb580b1365afdd9dd484dc4bee9e5d8f258/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:750e02e074872a3fad7f233b47734166440af3cdea0add3e95163110816d6752", size = 232502, upload-time = "2026-04-02T09:25:53.388Z" }, - { url = "https://files.pythonhosted.org/packages/58/d5/abcf2d83bf8e0a1286df55cd0dc1d49af0da4282aa77e986df343e7de124/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:4e5163c14bffd570ef2affbfdd77bba66383890797df43dc8b4cc7d6f500bf53", size = 214295, upload-time = "2026-04-02T09:25:54.765Z" }, - { url = "https://files.pythonhosted.org/packages/47/3a/7d4cd7ed54be99973a0dc176032cba5cb1f258082c31fa6df35cff46acfc/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6ed74185b2db44f41ef35fd1617c5888e59792da9bbc9190d6c7300617182616", size = 227145, upload-time = "2026-04-02T09:25:55.904Z" }, - { url = "https://files.pythonhosted.org/packages/1d/98/3a45bf8247889cf28262ebd3d0872edff11565b2a1e3064ccb132db3fbb0/charset_normalizer-3.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:94e1885b270625a9a828c9793b4d52a64445299baa1fea5a173bf1d3dd9a1a5a", size = 218884, upload-time = "2026-04-02T09:25:57.074Z" }, - { url = "https://files.pythonhosted.org/packages/ad/80/2e8b7f8915ed5c9ef13aa828d82738e33888c485b65ebf744d615040c7ea/charset_normalizer-3.4.7-cp310-cp310-win32.whl", hash = "sha256:6785f414ae0f3c733c437e0f3929197934f526d19dfaa75e18fdb4f94c6fb374", size = 148343, upload-time = "2026-04-02T09:25:58.199Z" }, - { url = "https://files.pythonhosted.org/packages/35/1b/3b8c8c77184af465ee9ad88b5aea46ea6b2e1f7b9dc9502891e37af21e30/charset_normalizer-3.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:6696b7688f54f5af4462118f0bfa7c1621eeb87154f77fa04b9295ce7a8f2943", size = 159174, upload-time = "2026-04-02T09:25:59.322Z" }, - { url = "https://files.pythonhosted.org/packages/be/c1/feb40dca40dbb21e0a908801782d9288c64fc8d8e562c2098e9994c8c21b/charset_normalizer-3.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:66671f93accb62ed07da56613636f3641f1a12c13046ce91ffc923721f23c008", size = 147805, upload-time = "2026-04-02T09:26:00.756Z" }, - { url = "https://files.pythonhosted.org/packages/c2/d7/b5b7020a0565c2e9fa8c09f4b5fa6232feb326b8c20081ccded47ea368fd/charset_normalizer-3.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7641bb8895e77f921102f72833904dcd9901df5d6d72a2ab8f31d04b7e51e4e7", size = 309705, upload-time = "2026-04-02T09:26:02.191Z" }, - { url = "https://files.pythonhosted.org/packages/5a/53/58c29116c340e5456724ecd2fff4196d236b98f3da97b404bc5e51ac3493/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:202389074300232baeb53ae2569a60901f7efadd4245cf3a3bf0617d60b439d7", size = 206419, upload-time = "2026-04-02T09:26:03.583Z" }, - { url = "https://files.pythonhosted.org/packages/b2/02/e8146dc6591a37a00e5144c63f29fb7c97a734ea8a111190783c0e60ab63/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30b8d1d8c52a48c2c5690e152c169b673487a2a58de1ec7393196753063fcd5e", size = 227901, upload-time = "2026-04-02T09:26:04.738Z" }, - { url = "https://files.pythonhosted.org/packages/fb/73/77486c4cd58f1267bf17db420e930c9afa1b3be3fe8c8b8ebbebc9624359/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:532bc9bf33a68613fd7d65e4b1c71a6a38d7d42604ecf239c77392e9b4e8998c", size = 222742, upload-time = "2026-04-02T09:26:06.36Z" }, - { url = "https://files.pythonhosted.org/packages/a1/fa/f74eb381a7d94ded44739e9d94de18dc5edc9c17fb8c11f0a6890696c0a9/charset_normalizer-3.4.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fe249cb4651fd12605b7288b24751d8bfd46d35f12a20b1ba33dea122e690df", size = 214061, upload-time = "2026-04-02T09:26:08.347Z" }, - { url = "https://files.pythonhosted.org/packages/dc/92/42bd3cefcf7687253fb86694b45f37b733c97f59af3724f356fa92b8c344/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:65bcd23054beab4d166035cabbc868a09c1a49d1efe458fe8e4361215df40265", size = 199239, upload-time = "2026-04-02T09:26:09.823Z" }, - { url = "https://files.pythonhosted.org/packages/4c/3d/069e7184e2aa3b3cddc700e3dd267413dc259854adc3380421c805c6a17d/charset_normalizer-3.4.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:08e721811161356f97b4059a9ba7bafb23ea5ee2255402c42881c214e173c6b4", size = 210173, upload-time = "2026-04-02T09:26:10.953Z" }, - { url = "https://files.pythonhosted.org/packages/62/51/9d56feb5f2e7074c46f93e0ebdbe61f0848ee246e2f0d89f8e20b89ebb8f/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e060d01aec0a910bdccb8be71faf34e7799ce36950f8294c8bf612cba65a2c9e", size = 209841, upload-time = "2026-04-02T09:26:12.142Z" }, - { url = "https://files.pythonhosted.org/packages/d2/59/893d8f99cc4c837dda1fe2f1139079703deb9f321aabcb032355de13b6c7/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:38c0109396c4cfc574d502df99742a45c72c08eff0a36158b6f04000043dbf38", size = 200304, upload-time = "2026-04-02T09:26:13.711Z" }, - { url = "https://files.pythonhosted.org/packages/7d/1d/ee6f3be3464247578d1ed5c46de545ccc3d3ff933695395c402c21fa6b77/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1c2a768fdd44ee4a9339a9b0b130049139b8ce3c01d2ce09f67f5a68048d477c", size = 229455, upload-time = "2026-04-02T09:26:14.941Z" }, - { url = "https://files.pythonhosted.org/packages/54/bb/8fb0a946296ea96a488928bdce8ef99023998c48e4713af533e9bb98ef07/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:1a87ca9d5df6fe460483d9a5bbf2b18f620cbed41b432e2bddb686228282d10b", size = 210036, upload-time = "2026-04-02T09:26:16.478Z" }, - { url = "https://files.pythonhosted.org/packages/9a/bc/015b2387f913749f82afd4fcba07846d05b6d784dd16123cb66860e0237d/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d635aab80466bc95771bb78d5370e74d36d1fe31467b6b29b8b57b2a3cd7d22c", size = 224739, upload-time = "2026-04-02T09:26:17.751Z" }, - { url = "https://files.pythonhosted.org/packages/17/ab/63133691f56baae417493cba6b7c641571a2130eb7bceba6773367ab9ec5/charset_normalizer-3.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ae196f021b5e7c78e918242d217db021ed2a6ace2bc6ae94c0fc596221c7f58d", size = 216277, upload-time = "2026-04-02T09:26:18.981Z" }, - { url = "https://files.pythonhosted.org/packages/06/6d/3be70e827977f20db77c12a97e6a9f973631a45b8d186c084527e53e77a4/charset_normalizer-3.4.7-cp311-cp311-win32.whl", hash = "sha256:adb2597b428735679446b46c8badf467b4ca5f5056aae4d51a19f9570301b1ad", size = 147819, upload-time = "2026-04-02T09:26:20.295Z" }, - { url = "https://files.pythonhosted.org/packages/20/d9/5f67790f06b735d7c7637171bbfd89882ad67201891b7275e51116ed8207/charset_normalizer-3.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:8e385e4267ab76874ae30db04c627faaaf0b509e1ccc11a95b3fc3e83f855c00", size = 159281, upload-time = "2026-04-02T09:26:21.74Z" }, - { url = "https://files.pythonhosted.org/packages/ca/83/6413f36c5a34afead88ce6f66684d943d91f233d76dd083798f9602b75ae/charset_normalizer-3.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:d4a48e5b3c2a489fae013b7589308a40146ee081f6f509e047e0e096084ceca1", size = 147843, upload-time = "2026-04-02T09:26:22.901Z" }, - { url = "https://files.pythonhosted.org/packages/0c/eb/4fc8d0a7110eb5fc9cc161723a34a8a6c200ce3b4fbf681bc86feee22308/charset_normalizer-3.4.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:eca9705049ad3c7345d574e3510665cb2cf844c2f2dcfe675332677f081cbd46", size = 311328, upload-time = "2026-04-02T09:26:24.331Z" }, - { url = "https://files.pythonhosted.org/packages/f8/e3/0fadc706008ac9d7b9b5be6dc767c05f9d3e5df51744ce4cc9605de7b9f4/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6178f72c5508bfc5fd446a5905e698c6212932f25bcdd4b47a757a50605a90e2", size = 208061, upload-time = "2026-04-02T09:26:25.568Z" }, - { url = "https://files.pythonhosted.org/packages/42/f0/3dd1045c47f4a4604df85ec18ad093912ae1344ac706993aff91d38773a2/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1421b502d83040e6d7fb2fb18dff63957f720da3d77b2fbd3187ceb63755d7b", size = 229031, upload-time = "2026-04-02T09:26:26.865Z" }, - { url = "https://files.pythonhosted.org/packages/dc/67/675a46eb016118a2fbde5a277a5d15f4f69d5f3f5f338e5ee2f8948fcf43/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:edac0f1ab77644605be2cbba52e6b7f630731fc42b34cb0f634be1a6eface56a", size = 225239, upload-time = "2026-04-02T09:26:28.044Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f8/d0118a2f5f23b02cd166fa385c60f9b0d4f9194f574e2b31cef350ad7223/charset_normalizer-3.4.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5649fd1c7bade02f320a462fdefd0b4bd3ce036065836d4f42e0de958038e116", size = 216589, upload-time = "2026-04-02T09:26:29.239Z" }, - { url = "https://files.pythonhosted.org/packages/b1/f1/6d2b0b261b6c4ceef0fcb0d17a01cc5bc53586c2d4796fa04b5c540bc13d/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:203104ed3e428044fd943bc4bf45fa73c0730391f9621e37fe39ecf477b128cb", size = 202733, upload-time = "2026-04-02T09:26:30.5Z" }, - { url = "https://files.pythonhosted.org/packages/6f/c0/7b1f943f7e87cc3db9626ba17807d042c38645f0a1d4415c7a14afb5591f/charset_normalizer-3.4.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:298930cec56029e05497a76988377cbd7457ba864beeea92ad7e844fe74cd1f1", size = 212652, upload-time = "2026-04-02T09:26:31.709Z" }, - { url = "https://files.pythonhosted.org/packages/38/dd/5a9ab159fe45c6e72079398f277b7d2b523e7f716acc489726115a910097/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:708838739abf24b2ceb208d0e22403dd018faeef86ddac04319a62ae884c4f15", size = 211229, upload-time = "2026-04-02T09:26:33.282Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ff/531a1cad5ca855d1c1a8b69cb71abfd6d85c0291580146fda7c82857caa1/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0f7eb884681e3938906ed0434f20c63046eacd0111c4ba96f27b76084cd679f5", size = 203552, upload-time = "2026-04-02T09:26:34.845Z" }, - { url = "https://files.pythonhosted.org/packages/c1/4c/a5fb52d528a8ca41f7598cb619409ece30a169fbdf9cdce592e53b46c3a6/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4dc1e73c36828f982bfe79fadf5919923f8a6f4df2860804db9a98c48824ce8d", size = 230806, upload-time = "2026-04-02T09:26:36.152Z" }, - { url = "https://files.pythonhosted.org/packages/59/7a/071feed8124111a32b316b33ae4de83d36923039ef8cf48120266844285b/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:aed52fea0513bac0ccde438c188c8a471c4e0f457c2dd20cdbf6ea7a450046c7", size = 212316, upload-time = "2026-04-02T09:26:37.672Z" }, - { url = "https://files.pythonhosted.org/packages/fd/35/f7dba3994312d7ba508e041eaac39a36b120f32d4c8662b8814dab876431/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464", size = 227274, upload-time = "2026-04-02T09:26:38.93Z" }, - { url = "https://files.pythonhosted.org/packages/8a/2d/a572df5c9204ab7688ec1edc895a73ebded3b023bb07364710b05dd1c9be/charset_normalizer-3.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb6d88045545b26da47aa879dd4a89a71d1dce0f0e549b1abcb31dfe4a8eac49", size = 218468, upload-time = "2026-04-02T09:26:40.17Z" }, - { url = "https://files.pythonhosted.org/packages/86/eb/890922a8b03a568ca2f336c36585a4713c55d4d67bf0f0c78924be6315ca/charset_normalizer-3.4.7-cp312-cp312-win32.whl", hash = "sha256:2257141f39fe65a3fdf38aeccae4b953e5f3b3324f4ff0daf9f15b8518666a2c", size = 148460, upload-time = "2026-04-02T09:26:41.416Z" }, - { url = "https://files.pythonhosted.org/packages/35/d9/0e7dffa06c5ab081f75b1b786f0aefc88365825dfcd0ac544bdb7b2b6853/charset_normalizer-3.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:5ed6ab538499c8644b8a3e18debabcd7ce684f3fa91cf867521a7a0279cab2d6", size = 159330, upload-time = "2026-04-02T09:26:42.554Z" }, - { url = "https://files.pythonhosted.org/packages/9e/5d/481bcc2a7c88ea6b0878c299547843b2521ccbc40980cb406267088bc701/charset_normalizer-3.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:56be790f86bfb2c98fb742ce566dfb4816e5a83384616ab59c49e0604d49c51d", size = 147828, upload-time = "2026-04-02T09:26:44.075Z" }, - { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" }, - { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" }, - { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" }, - { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" }, - { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" }, - { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" }, - { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" }, - { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" }, - { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" }, - { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" }, - { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" }, - { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" }, - { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" }, - { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" }, - { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" }, - { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" }, - { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" }, - { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" }, - { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" }, - { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" }, - { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" }, - { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" }, - { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" }, - { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" }, - { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" }, - { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" }, - { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" }, - { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" }, - { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" }, - { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" }, - { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" }, - { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" }, - { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" }, - { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" }, - { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" }, - { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" }, - { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" }, - { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" }, - { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" }, - { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" }, - { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" }, - { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" }, - { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" }, - { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" }, - { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" }, +version = "3.4.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/2a/23f34ec9d04624958e137efdc394888716353190e75f25dd22c7a2c7a8aa/charset_normalizer-3.4.9.tar.gz", hash = "sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b", size = 152439, upload-time = "2026-07-07T14:34:58.454Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ad/81/8e983840c6e5b93b33c2ba81aa3d52c2e42f0e9a690ce7607a2e61da4a5c/charset_normalizer-3.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a", size = 322240, upload-time = "2026-07-07T14:32:36.236Z" }, + { url = "https://files.pythonhosted.org/packages/de/d1/b4319dc3229d8272fba305e206fc0a148e2de8d4087917ce62ae6382f359/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616", size = 216475, upload-time = "2026-07-07T14:32:38.142Z" }, + { url = "https://files.pythonhosted.org/packages/80/33/6c99c1b3e6b8bf730e1bc809b9a2608f224145069114c479a2e9e1494346/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c1225416b463483160e4af85d5fc3a9690ccb53fd4b1865a6437825f5ede3209", size = 238670, upload-time = "2026-07-07T14:32:39.658Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f4/ffbb83546e1f198ecc70ecd372b65cf2b50f9068b380abd67640f17a8e18/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:16d10d789dd9bcca1173c95af82c58433122564b7bc39385124be735a35cbe99", size = 233476, upload-time = "2026-07-07T14:32:41.155Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5f/b98b8da398637b551e427e7be922bdec19177dc54d6811dcdaa503f23aac/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bb41182d93ea91f60b4bc8fbf4c820c69ef8a12ab2d917f3f1834f1acad07e8", size = 223817, upload-time = "2026-07-07T14:32:42.592Z" }, + { url = "https://files.pythonhosted.org/packages/36/31/a276bb2e66243072a3fd06fdcab9cbb61a305b02143d70d2bda21d888fa8/charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_armv7l.whl", hash = "sha256:bcf74c1df76758a395bf0af608c04c82257523f55c9868b334f06270d0f2112b", size = 207974, upload-time = "2026-07-07T14:32:44.258Z" }, + { url = "https://files.pythonhosted.org/packages/5e/be/7ee4453d7e88dfbc4104ccd34900b9f2c7c17dac22881865fe0e82424a25/charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b5314963fce9b0b12743891de876e724997864ee22aa496f903f426c7e2fa5b2", size = 221655, upload-time = "2026-07-07T14:32:45.64Z" }, + { url = "https://files.pythonhosted.org/packages/1d/85/181c652953eb5276d198f375b1dd641047392050098100a3a02d6534f657/charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e9701d0049d92c16703a42771b98d560b95248949f23f8cf7b4eddd201814fb9", size = 219229, upload-time = "2026-07-07T14:32:47.376Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e7/aaf6da33fc9f4691cda8f7efbc9f69179d3d39ec8a4799baf273ee1d8db0/charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:65a7ff3f705e57d392f7261b6d0550fe137c3019477431f1c355e0db0a7d3e15", size = 209704, upload-time = "2026-07-07T14:32:48.855Z" }, + { url = "https://files.pythonhosted.org/packages/63/01/f2fb3bd3a73be48b173ee0c6aa8d2497af97d5663a8c4c4b491de4c62f7a/charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79580094b00d1789d1f93ea55bc43cb2f611910c72235b7657f3482ddcc1b22d", size = 226243, upload-time = "2026-07-07T14:32:50.239Z" }, + { url = "https://files.pythonhosted.org/packages/c4/02/c57a22739fe05246b0b5783b3bfb6afaac4eebb46f3ececdfb2f048f780e/charset_normalizer-3.4.9-cp310-cp310-win32.whl", hash = "sha256:432786d3561e69aeeae6c7e8648964ce0ad05736120135601f87ac26b9c83381", size = 150935, upload-time = "2026-07-07T14:32:51.676Z" }, + { url = "https://files.pythonhosted.org/packages/37/8d/ca39a7559a4797505530d084fd3a49a2c959efbbbff146302fb7be4e3b35/charset_normalizer-3.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:8c041122946b7ba21bb32c45b1aa57b1be35527690aeb3c5c234521085632eee", size = 162314, upload-time = "2026-07-07T14:32:53.193Z" }, + { url = "https://files.pythonhosted.org/packages/01/da/a44bd7a13d426e69e4894557106cd58669097bfad4a8681123b618fbfc5d/charset_normalizer-3.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:375b83ed0aecfce76c16d198fbc21f3b11b337d68662bea0a995046682a11419", size = 153075, upload-time = "2026-07-07T14:32:54.554Z" }, + { url = "https://files.pythonhosted.org/packages/0b/e3/85ec501f206fb049259288c1f3506e53876937fb00edb47009348e66756b/charset_normalizer-3.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0e94703ec9684807f20cfb5eed95c70f67f2a8f21ad620146d7b5a13677b93e5", size = 317075, upload-time = "2026-07-07T14:32:56.021Z" }, + { url = "https://files.pythonhosted.org/packages/c3/69/2a5385192e67175f7d8bd5ce4f57c24bc956439adeae5c13a99aa28a53d1/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a441ea71902098ffe78c5abe6c494f44160b4af614ed16c3d9a3b1d17fd8ee2", size = 213837, upload-time = "2026-07-07T14:32:57.78Z" }, + { url = "https://files.pythonhosted.org/packages/b3/46/03ddc7da576d814fe0a36dd1f0fd3258e95404b4b2e3c026b7923d7e133f/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:304b13570067b2547562e308af560b3963857b1fa90bd6afd978130130fe2d6a", size = 235503, upload-time = "2026-07-07T14:32:59.205Z" }, + { url = "https://files.pythonhosted.org/packages/4e/6e/de0229a7ef40f6f9d28a837eebf4ec47bdca5dab4e900c84f22919af636a/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4773092f8019072343a7447203308b176e10199920eb02d6195e81bbb3274c29", size = 229944, upload-time = "2026-07-07T14:33:00.803Z" }, + { url = "https://files.pythonhosted.org/packages/a5/34/49b9060e8418b14fb5cba9cf6bfb383111e2538a03a1fb18e66a95aeb3d5/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:04ce310cb89c15df659582aee80a0603788732a5e017d5bd5c81158106ce249c", size = 221276, upload-time = "2026-07-07T14:33:02.199Z" }, + { url = "https://files.pythonhosted.org/packages/44/95/80282cce0fae9c3061203d723ee87da996aed79679e65d8935050ee7ca1f/charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_armv7l.whl", hash = "sha256:c0323c9daef75ef2e5083624b4585018a0c9d5e3b40f607eed81a311270b934b", size = 205260, upload-time = "2026-07-07T14:33:03.698Z" }, + { url = "https://files.pythonhosted.org/packages/0c/74/2f62c8821b969ea3bd67cc2e6976834f48ca5d12664d2559ebcd9bcfbed7/charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:871ff67ea1aad4dfd91736464934d56b32dac49f9fbe16cddba36198a7b3a0db", size = 217786, upload-time = "2026-07-07T14:33:05.12Z" }, + { url = "https://files.pythonhosted.org/packages/d9/8d/feabb82cb49fcad14515b1d7d1ca4787b0da7fc723a212bf89bc9e0fac52/charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:67830fc78e67501f47bb950471b2dcb9b35b140084429318e862895a8e89c993", size = 216798, upload-time = "2026-07-07T14:33:06.629Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ff/c946d63bc3786d5b84d960b0f7ab7e25b828486a946b5aa997625bcaf6a6/charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:3d92613ec25e43b05f042302531ec0f00b8445190e43325880cbd6ab7c2581da", size = 206429, upload-time = "2026-07-07T14:33:08.006Z" }, + { url = "https://files.pythonhosted.org/packages/af/ba/5e5007c370702f85d2ef75791fac7943ed41e080364a673b20142e430e3e/charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:280081916dc341820640489a66e4696049401ef1cf6dd672f672e70ad915aca3", size = 223066, upload-time = "2026-07-07T14:33:09.783Z" }, + { url = "https://files.pythonhosted.org/packages/83/d5/9096aa3cf532dfad237861544eb47a0f20d5adbf1039760fed8eaae935d9/charset_normalizer-3.4.9-cp311-cp311-win32.whl", hash = "sha256:ac351b3b8014eead140e77e9717e2992c6bbe30b63bc3422422eb84865412e3d", size = 150456, upload-time = "2026-07-07T14:33:11.217Z" }, + { url = "https://files.pythonhosted.org/packages/ed/a1/e29995109e455dc8eff8d0fac6ae509be39561318a7cfeac5d33ad029213/charset_normalizer-3.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:6366a16e1a25018694d6a5d784d09b046edc9eac40ea2b54065c3052672516a1", size = 161410, upload-time = "2026-07-07T14:33:12.743Z" }, + { url = "https://files.pythonhosted.org/packages/4f/8d/1569f4d0032d6ba2a4fe4591c35bf87868c600c41a71eb5c2e1ffa8464c2/charset_normalizer-3.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:1d22856ffbe153a602df38e4a5464f0b748a54002e0d69ac6d2ad0a197cc99ec", size = 152649, upload-time = "2026-07-07T14:33:14.173Z" }, + { url = "https://files.pythonhosted.org/packages/70/4a/ecbd131485c07fcdfad54e28946d513e3da22ef3b4bd854dcafae54ec739/charset_normalizer-3.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0", size = 319300, upload-time = "2026-07-07T14:33:15.666Z" }, + { url = "https://files.pythonhosted.org/packages/ec/96/5d9364e3342d69f3a045e1777bc47c85c383e6e9466d561b33fdb419d1f9/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9", size = 215802, upload-time = "2026-07-07T14:33:17.031Z" }, + { url = "https://files.pythonhosted.org/packages/4b/4c/5361f9aa7f2cb58d94f2ab831b3d493f69efb1d239654b4744e3c09527cb/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44", size = 237171, upload-time = "2026-07-07T14:33:18.576Z" }, + { url = "https://files.pythonhosted.org/packages/50/78/ce342ca4ff30b2eb49fe6d9578df85974f90c67d294113e94efdd9664cbd/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9", size = 233075, upload-time = "2026-07-07T14:33:20.084Z" }, + { url = "https://files.pythonhosted.org/packages/01/c4/4fa4c8b3097a11f3c5f09a35b72ed6855fb1d332469504962ab7bafcc702/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd", size = 224256, upload-time = "2026-07-07T14:33:21.747Z" }, + { url = "https://files.pythonhosted.org/packages/87/3a/ad914516df7e358a81aae018caa5e0470ba827fa6d763b1d2e87d920a5f6/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84", size = 208784, upload-time = "2026-07-07T14:33:23.313Z" }, + { url = "https://files.pythonhosted.org/packages/d7/74/3c12f9755717dfe5c5c87da63f35d765fa0c00382ec26bf23f7fae34f2ba/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b", size = 219928, upload-time = "2026-07-07T14:33:24.814Z" }, + { url = "https://files.pythonhosted.org/packages/33/9a/895095b83e7907abd6d3d99aad3a38ad0d9686cc186cb0c94c24320fe63e/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde", size = 218489, upload-time = "2026-07-07T14:33:26.42Z" }, + { url = "https://files.pythonhosted.org/packages/a1/34/ef5c05f412f42520d7709b7d3784d19640839eb7366ded1755511585429f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39", size = 210267, upload-time = "2026-07-07T14:33:27.952Z" }, + { url = "https://files.pythonhosted.org/packages/83/dc/9b29fa4412b318bf3bfea985c35d67eb55e04b59a7c3f2237168b0e0be6f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62", size = 226030, upload-time = "2026-07-07T14:33:29.397Z" }, + { url = "https://files.pythonhosted.org/packages/0e/42/6dbc00b8cd16011691203e33570fa42ed5746599a2e878112d16eab403a3/charset_normalizer-3.4.9-cp312-cp312-win32.whl", hash = "sha256:78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642", size = 151185, upload-time = "2026-07-07T14:33:30.781Z" }, + { url = "https://files.pythonhosted.org/packages/80/cc/f920afd1a23c58ccd53c1d36085a71893a4737ff5e66e0371efab6809850/charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0", size = 162557, upload-time = "2026-07-07T14:33:32.176Z" }, + { url = "https://files.pythonhosted.org/packages/f0/e6/0386d43a261ff4e4b30c5857af7df877254b46bec7b9d1b74b6bf969a90b/charset_normalizer-3.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2", size = 152665, upload-time = "2026-07-07T14:33:33.711Z" }, + { url = "https://files.pythonhosted.org/packages/b2/06/97ec2aeae780b31d742b6352218b43841a6871e2564578ca522dce4a45c3/charset_normalizer-3.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614", size = 317688, upload-time = "2026-07-07T14:33:35.408Z" }, + { url = "https://files.pythonhosted.org/packages/d0/39/8ff066c672434225f8d25f8b739f992af250944392173dcc88362681c9bf/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698", size = 214982, upload-time = "2026-07-07T14:33:36.996Z" }, + { url = "https://files.pythonhosted.org/packages/92/8f/3a47a3667c83c2df9483d91644c6c107de3bf8874aa1793da9d3012eb986/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b", size = 236460, upload-time = "2026-07-07T14:33:38.536Z" }, + { url = "https://files.pythonhosted.org/packages/f1/60/b22cdbee7e4013dab8b0d7647fc6181120fbbbc8f7025c226d15bd5a47fc/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9", size = 232003, upload-time = "2026-07-07T14:33:40.059Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f8/72eb13dcabe7257035cea8aefd922caad2f110d252bf9f67c4c2ca763aee/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33", size = 223149, upload-time = "2026-07-07T14:33:41.631Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3e/faee8f9de92b14ee1198e9163252bb15efee7301b31256a3b6d9ebfdd0dd/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63", size = 207901, upload-time = "2026-07-07T14:33:43.209Z" }, + { url = "https://files.pythonhosted.org/packages/3a/25/45f30093ae27dd7b92a793b61882a38685f993700113ca36e0c9c14965e1/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0", size = 219176, upload-time = "2026-07-07T14:33:44.725Z" }, + { url = "https://files.pythonhosted.org/packages/48/18/c8f397329c35e32f6a837e488986f4ae03bd2abebc453b48714991630c2f/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe", size = 217356, upload-time = "2026-07-07T14:33:46.192Z" }, + { url = "https://files.pythonhosted.org/packages/86/7e/5ce0bba863470fd1902d5e5843968951bddf38abe4742fc97116ef4598b3/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35", size = 209614, upload-time = "2026-07-07T14:33:47.705Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ef/2473d3c4d869155be4af1191111d59c4d5c4e0173026f7e85b176e23bf65/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8", size = 224991, upload-time = "2026-07-07T14:33:49.238Z" }, + { url = "https://files.pythonhosted.org/packages/d0/a3/53ddae3db108a088156aa8ddfafd411ebbc1340f48c5573f697b27f69a39/charset_normalizer-3.4.9-cp313-cp313-win32.whl", hash = "sha256:51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9", size = 150622, upload-time = "2026-07-07T14:33:50.711Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ef/6953a77c7cf2c2ff9998e6f575ab3e380119f100223381565a4f94c1f836/charset_normalizer-3.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115", size = 161947, upload-time = "2026-07-07T14:33:52.197Z" }, + { url = "https://files.pythonhosted.org/packages/6e/fb/d560d1d1555debbfe7849d9cac6145c1b537709d79576bf22557ed803b82/charset_normalizer-3.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012", size = 152594, upload-time = "2026-07-07T14:33:53.486Z" }, + { url = "https://files.pythonhosted.org/packages/7e/8d/496817fa0944239ecae662dd57ea765cfeaec6a735f9f025d4b7b72e7143/charset_normalizer-3.4.9-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380", size = 317253, upload-time = "2026-07-07T14:33:54.994Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f9/ef4a69ea338ad3c0deceea0f5f7d2380ae8b52132b06d652cb0d2cd86706/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9", size = 215898, upload-time = "2026-07-07T14:33:56.334Z" }, + { url = "https://files.pythonhosted.org/packages/8c/e7/5ddfd76fc061eb52de219658a4aa431cbacadf0a0219c8854f00da50d289/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4", size = 236718, upload-time = "2026-07-07T14:33:57.9Z" }, + { url = "https://files.pythonhosted.org/packages/49/ba/768fa3f36048d81c477a0ce61f813bc1454d80917ccfe550abd9f44f5e24/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a", size = 232519, upload-time = "2026-07-07T14:33:59.811Z" }, + { url = "https://files.pythonhosted.org/packages/f4/c4/b3e049d2aa3766180c78507110543d9d50894cc97f57de543f1be521dcdc/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046", size = 223143, upload-time = "2026-07-07T14:34:01.517Z" }, + { url = "https://files.pythonhosted.org/packages/19/79/55c32d06d76ae4feafe053f061f3e3ab70bcf19f4007797ce8c3efda7830/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81", size = 206742, upload-time = "2026-07-07T14:34:03.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/e0/47c079dd82d217c807479cd59ffd30af56307ea31c108b75758970459ad3/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917", size = 219191, upload-time = "2026-07-07T14:34:04.657Z" }, + { url = "https://files.pythonhosted.org/packages/42/ab/b9bc2e77d6b44a7e46ef62ec5cac1c9a6ba7b9135a5d560f002696ec9995/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41", size = 218328, upload-time = "2026-07-07T14:34:06.115Z" }, + { url = "https://files.pythonhosted.org/packages/f1/78/c9c71d599f5aa2d42bcdd35cbbd46d7f535351a57e40ff7d8e5a7e219401/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1", size = 207406, upload-time = "2026-07-07T14:34:07.554Z" }, + { url = "https://files.pythonhosted.org/packages/f6/39/c914445c321a845097ce4f6ac7de9a18228a77b766272125a1ce00d851eb/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf", size = 225157, upload-time = "2026-07-07T14:34:09.061Z" }, + { url = "https://files.pythonhosted.org/packages/9b/f2/c0d4b8508565a36bc5c624e88ed297f5b0b1095011034d7f5b83a69908b5/charset_normalizer-3.4.9-cp314-cp314-win32.whl", hash = "sha256:c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48", size = 151095, upload-time = "2026-07-07T14:34:10.901Z" }, + { url = "https://files.pythonhosted.org/packages/49/fd/a1d26144398c67486422a72bf5812cda22cb4ccfcd95a290fb41ceb4b8e2/charset_normalizer-3.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b", size = 162796, upload-time = "2026-07-07T14:34:12.47Z" }, + { url = "https://files.pythonhosted.org/packages/20/95/d75e82f8ce9fd323ebf059c16c9aadefb22a1ecde13b7840b35835e4886c/charset_normalizer-3.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519", size = 153334, upload-time = "2026-07-07T14:34:14.044Z" }, + { url = "https://files.pythonhosted.org/packages/00/5e/17398df3a139985ba9d11ed072531986f408c8fca952835ef1ab1820c02b/charset_normalizer-3.4.9-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198", size = 338848, upload-time = "2026-07-07T14:34:15.688Z" }, + { url = "https://files.pythonhosted.org/packages/cd/91/7253a32e86b7e1d1239b1b36ba6dd0f021a21107ab33054b53119cc083b9/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32", size = 223022, upload-time = "2026-07-07T14:34:17.248Z" }, + { url = "https://files.pythonhosted.org/packages/cb/32/2e64bd2be10e89c61e57ebe6a93fd98ae88eb7ebe414b5121f22c96c69eb/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632", size = 241590, upload-time = "2026-07-07T14:34:18.813Z" }, + { url = "https://files.pythonhosted.org/packages/3d/ef/d96ec496cfea0c21db43b0ad03891308b02388d054cc902cf0e5a1ad6a88/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf", size = 239584, upload-time = "2026-07-07T14:34:20.52Z" }, + { url = "https://files.pythonhosted.org/packages/d4/ce/9af95f7876194bd7a14e3dfe4a4de2e0bff02666a3910d72beafd06cc297/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990", size = 230224, upload-time = "2026-07-07T14:34:22.189Z" }, + { url = "https://files.pythonhosted.org/packages/52/94/af74dde74a3996bd959c350709bfe50e297823d70a8c1cbd54b838880863/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d", size = 212667, upload-time = "2026-07-07T14:34:23.857Z" }, + { url = "https://files.pythonhosted.org/packages/ee/f0/f1c4fe746c395922961b5916ed1d7d6e7d4c84851d19ed43cc89980ec953/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e", size = 227179, upload-time = "2026-07-07T14:34:25.586Z" }, + { url = "https://files.pythonhosted.org/packages/e4/56/6c745619ac397e8871e2bcd3cea1eec86b877488f33888b3aef5c3ed506e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c", size = 225372, upload-time = "2026-07-07T14:34:27.212Z" }, + { url = "https://files.pythonhosted.org/packages/78/ad/98aae8630ac71f16711968e38a5acfecce41b778bf2f0312851020f565a8/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2", size = 215222, upload-time = "2026-07-07T14:34:28.774Z" }, + { url = "https://files.pythonhosted.org/packages/f7/40/9593d54209765207a7f11073c06494c1721e4ca4a0a426c597679bf7f91e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534", size = 231958, upload-time = "2026-07-07T14:34:30.345Z" }, + { url = "https://files.pythonhosted.org/packages/b1/27/693ee5e8a18191eb38647360c51cd505013e2bd3b366aa43fd5344c21e3c/charset_normalizer-3.4.9-cp314-cp314t-win32.whl", hash = "sha256:0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226", size = 155580, upload-time = "2026-07-07T14:34:31.884Z" }, + { url = "https://files.pythonhosted.org/packages/80/3f/bd97d3d9c613013d07cb7733d299385b41df37f0471310f5a73dc359f0b8/charset_normalizer-3.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177", size = 167620, upload-time = "2026-07-07T14:34:33.438Z" }, + { url = "https://files.pythonhosted.org/packages/3d/c6/eee9dca4439b1061f76373f06ea855678cc4a64c1c3c90b50e479edbb8eb/charset_normalizer-3.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501", size = 158037, upload-time = "2026-07-07T14:34:35.018Z" }, + { url = "https://files.pythonhosted.org/packages/98/2b/f97f1c193fb855c345d678f5077d6926034db0722df74c8f057020e05a25/charset_normalizer-3.4.9-py3-none-any.whl", hash = "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5", size = 64538, upload-time = "2026-07-07T14:34:56.993Z" }, ] [[package]] name = "click" -version = "8.3.3" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/63/f9e1ea081ce35720d8b92acde70daaedace594dc93b693c869e0d5910718/click-8.3.3.tar.gz", hash = "sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2", size = 328061, upload-time = "2026-04-22T15:11:27.506Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl", hash = "sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613", size = 110502, upload-time = "2026-04-22T15:11:25.044Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" }, ] [[package]] @@ -521,115 +641,100 @@ wheels = [ [[package]] name = "coverage" -version = "7.13.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/e0/70553e3000e345daff267cec284ce4cbf3fc141b6da229ac52775b5428f1/coverage-7.13.5.tar.gz", hash = "sha256:c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179", size = 915967, upload-time = "2026-03-17T10:33:18.341Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/69/33/e8c48488c29a73fd089f9d71f9653c1be7478f2ad6b5bc870db11a55d23d/coverage-7.13.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0723d2c96324561b9aa76fb982406e11d93cdb388a7a7da2b16e04719cf7ca5", size = 219255, upload-time = "2026-03-17T10:29:51.081Z" }, - { url = "https://files.pythonhosted.org/packages/da/bd/b0ebe9f677d7f4b74a3e115eec7ddd4bcf892074963a00d91e8b164a6386/coverage-7.13.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:52f444e86475992506b32d4e5ca55c24fc88d73bcbda0e9745095b28ef4dc0cf", size = 219772, upload-time = "2026-03-17T10:29:52.867Z" }, - { url = "https://files.pythonhosted.org/packages/48/cc/5cb9502f4e01972f54eedd48218bb203fe81e294be606a2bc93970208013/coverage-7.13.5-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:704de6328e3d612a8f6c07000a878ff38181ec3263d5a11da1db294fa6a9bdf8", size = 246532, upload-time = "2026-03-17T10:29:54.688Z" }, - { url = "https://files.pythonhosted.org/packages/7d/d8/3217636d86c7e7b12e126e4f30ef1581047da73140614523af7495ed5f2d/coverage-7.13.5-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a1a6d79a14e1ec1832cabc833898636ad5f3754a678ef8bb4908515208bf84f4", size = 248333, upload-time = "2026-03-17T10:29:56.221Z" }, - { url = "https://files.pythonhosted.org/packages/2b/30/2002ac6729ba2d4357438e2ed3c447ad8562866c8c63fc16f6dfc33afe56/coverage-7.13.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79060214983769c7ba3f0cee10b54c97609dca4d478fa1aa32b914480fd5738d", size = 250211, upload-time = "2026-03-17T10:29:57.938Z" }, - { url = "https://files.pythonhosted.org/packages/6c/85/552496626d6b9359eb0e2f86f920037c9cbfba09b24d914c6e1528155f7d/coverage-7.13.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:356e76b46783a98c2a2fe81ec79df4883a1e62895ea952968fb253c114e7f930", size = 252125, upload-time = "2026-03-17T10:29:59.388Z" }, - { url = "https://files.pythonhosted.org/packages/44/21/40256eabdcbccdb6acf6b381b3016a154399a75fe39d406f790ae84d1f3c/coverage-7.13.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0cef0cdec915d11254a7f549c1170afecce708d30610c6abdded1f74e581666d", size = 247219, upload-time = "2026-03-17T10:30:01.199Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e8/96e2a6c3f21a0ea77d7830b254a1542d0328acc8d7bdf6a284ba7e529f77/coverage-7.13.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dc022073d063b25a402454e5712ef9e007113e3a676b96c5f29b2bda29352f40", size = 248248, upload-time = "2026-03-17T10:30:03.317Z" }, - { url = "https://files.pythonhosted.org/packages/da/ba/8477f549e554827da390ec659f3c38e4b6d95470f4daafc2d8ff94eaa9c2/coverage-7.13.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9b74db26dfea4f4e50d48a4602207cd1e78be33182bc9cbf22da94f332f99878", size = 246254, upload-time = "2026-03-17T10:30:04.832Z" }, - { url = "https://files.pythonhosted.org/packages/55/59/bc22aef0e6aa179d5b1b001e8b3654785e9adf27ef24c93dc4228ebd5d68/coverage-7.13.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ad146744ca4fd09b50c482650e3c1b1f4dfa1d4792e0a04a369c7f23336f0400", size = 250067, upload-time = "2026-03-17T10:30:06.535Z" }, - { url = "https://files.pythonhosted.org/packages/de/1b/c6a023a160806a5137dca53468fd97530d6acad24a22003b1578a9c2e429/coverage-7.13.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:c555b48be1853fe3997c11c4bd521cdd9a9612352de01fa4508f16ec341e6fe0", size = 246521, upload-time = "2026-03-17T10:30:08.486Z" }, - { url = "https://files.pythonhosted.org/packages/2d/3f/3532c85a55aa2f899fa17c186f831cfa1aa434d88ff792a709636f64130e/coverage-7.13.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7034b5c56a58ae5e85f23949d52c14aca2cfc6848a31764995b7de88f13a1ea0", size = 247126, upload-time = "2026-03-17T10:30:09.966Z" }, - { url = "https://files.pythonhosted.org/packages/aa/2e/b9d56af4a24ef45dfbcda88e06870cb7d57b2b0bfa3a888d79b4c8debd76/coverage-7.13.5-cp310-cp310-win32.whl", hash = "sha256:eb7fdf1ef130660e7415e0253a01a7d5a88c9c4d158bcf75cbbd922fd65a5b58", size = 221860, upload-time = "2026-03-17T10:30:11.393Z" }, - { url = "https://files.pythonhosted.org/packages/9f/cc/d938417e7a4d7f0433ad4edee8bb2acdc60dc7ac5af19e2a07a048ecbee3/coverage-7.13.5-cp310-cp310-win_amd64.whl", hash = "sha256:3e1bb5f6c78feeb1be3475789b14a0f0a5b47d505bfc7267126ccbd50289999e", size = 222788, upload-time = "2026-03-17T10:30:12.886Z" }, - { url = "https://files.pythonhosted.org/packages/4b/37/d24c8f8220ff07b839b2c043ea4903a33b0f455abe673ae3c03bbdb7f212/coverage-7.13.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66a80c616f80181f4d643b0f9e709d97bcea413ecd9631e1dedc7401c8e6695d", size = 219381, upload-time = "2026-03-17T10:30:14.68Z" }, - { url = "https://files.pythonhosted.org/packages/35/8b/cd129b0ca4afe886a6ce9d183c44d8301acbd4ef248622e7c49a23145605/coverage-7.13.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:145ede53ccbafb297c1c9287f788d1bc3efd6c900da23bf6931b09eafc931587", size = 219880, upload-time = "2026-03-17T10:30:16.231Z" }, - { url = "https://files.pythonhosted.org/packages/55/2f/e0e5b237bffdb5d6c530ce87cc1d413a5b7d7dfd60fb067ad6d254c35c76/coverage-7.13.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0672854dc733c342fa3e957e0605256d2bf5934feeac328da9e0b5449634a642", size = 250303, upload-time = "2026-03-17T10:30:17.748Z" }, - { url = "https://files.pythonhosted.org/packages/92/be/b1afb692be85b947f3401375851484496134c5554e67e822c35f28bf2fbc/coverage-7.13.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ec10e2a42b41c923c2209b846126c6582db5e43a33157e9870ba9fb70dc7854b", size = 252218, upload-time = "2026-03-17T10:30:19.804Z" }, - { url = "https://files.pythonhosted.org/packages/da/69/2f47bb6fa1b8d1e3e5d0c4be8ccb4313c63d742476a619418f85740d597b/coverage-7.13.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be3d4bbad9d4b037791794ddeedd7d64a56f5933a2c1373e18e9e568b9141686", size = 254326, upload-time = "2026-03-17T10:30:21.321Z" }, - { url = "https://files.pythonhosted.org/packages/d5/d0/79db81da58965bd29dabc8f4ad2a2af70611a57cba9d1ec006f072f30a54/coverage-7.13.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d2afbc5cc54d286bfb54541aa50b64cdb07a718227168c87b9e2fb8f25e1743", size = 256267, upload-time = "2026-03-17T10:30:23.094Z" }, - { url = "https://files.pythonhosted.org/packages/e5/32/d0d7cc8168f91ddab44c0ce4806b969df5f5fdfdbb568eaca2dbc2a04936/coverage-7.13.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3ad050321264c49c2fa67bb599100456fc51d004b82534f379d16445da40fb75", size = 250430, upload-time = "2026-03-17T10:30:25.311Z" }, - { url = "https://files.pythonhosted.org/packages/4d/06/a055311d891ddbe231cd69fdd20ea4be6e3603ffebddf8704b8ca8e10a3c/coverage-7.13.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7300c8a6d13335b29bb76d7651c66af6bd8658517c43499f110ddc6717bfc209", size = 252017, upload-time = "2026-03-17T10:30:27.284Z" }, - { url = "https://files.pythonhosted.org/packages/d6/f6/d0fd2d21e29a657b5f77a2fe7082e1568158340dceb941954f776dce1b7b/coverage-7.13.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:eb07647a5738b89baab047f14edd18ded523de60f3b30e75c2acc826f79c839a", size = 250080, upload-time = "2026-03-17T10:30:29.481Z" }, - { url = "https://files.pythonhosted.org/packages/4e/ab/0d7fb2efc2e9a5eb7ddcc6e722f834a69b454b7e6e5888c3a8567ecffb31/coverage-7.13.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9adb6688e3b53adffefd4a52d72cbd8b02602bfb8f74dcd862337182fd4d1a4e", size = 253843, upload-time = "2026-03-17T10:30:31.301Z" }, - { url = "https://files.pythonhosted.org/packages/ba/6f/7467b917bbf5408610178f62a49c0ed4377bb16c1657f689cc61470da8ce/coverage-7.13.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7c8d4bc913dd70b93488d6c496c77f3aff5ea99a07e36a18f865bca55adef8bd", size = 249802, upload-time = "2026-03-17T10:30:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/75/2c/1172fb689df92135f5bfbbd69fc83017a76d24ea2e2f3a1154007e2fb9f8/coverage-7.13.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0e3c426ffc4cd952f54ee9ffbdd10345709ecc78a3ecfd796a57236bfad0b9b8", size = 250707, upload-time = "2026-03-17T10:30:35.2Z" }, - { url = "https://files.pythonhosted.org/packages/67/21/9ac389377380a07884e3b48ba7a620fcd9dbfaf1d40565facdc6b36ec9ef/coverage-7.13.5-cp311-cp311-win32.whl", hash = "sha256:259b69bb83ad9894c4b25be2528139eecba9a82646ebdda2d9db1ba28424a6bf", size = 221880, upload-time = "2026-03-17T10:30:36.775Z" }, - { url = "https://files.pythonhosted.org/packages/af/7f/4cd8a92531253f9d7c1bbecd9fa1b472907fb54446ca768c59b531248dc5/coverage-7.13.5-cp311-cp311-win_amd64.whl", hash = "sha256:258354455f4e86e3e9d0d17571d522e13b4e1e19bf0f8596bcf9476d61e7d8a9", size = 222816, upload-time = "2026-03-17T10:30:38.891Z" }, - { url = "https://files.pythonhosted.org/packages/12/a6/1d3f6155fb0010ca68eba7fe48ca6c9da7385058b77a95848710ecf189b1/coverage-7.13.5-cp311-cp311-win_arm64.whl", hash = "sha256:bff95879c33ec8da99fc9b6fe345ddb5be6414b41d6d1ad1c8f188d26f36e028", size = 221483, upload-time = "2026-03-17T10:30:40.463Z" }, - { url = "https://files.pythonhosted.org/packages/a0/c3/a396306ba7db865bf96fc1fb3b7fd29bcbf3d829df642e77b13555163cd6/coverage-7.13.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:460cf0114c5016fa841214ff5564aa4864f11948da9440bc97e21ad1f4ba1e01", size = 219554, upload-time = "2026-03-17T10:30:42.208Z" }, - { url = "https://files.pythonhosted.org/packages/a6/16/a68a19e5384e93f811dccc51034b1fd0b865841c390e3c931dcc4699e035/coverage-7.13.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e223ce4b4ed47f065bfb123687686512e37629be25cc63728557ae7db261422", size = 219908, upload-time = "2026-03-17T10:30:43.906Z" }, - { url = "https://files.pythonhosted.org/packages/29/72/20b917c6793af3a5ceb7fb9c50033f3ec7865f2911a1416b34a7cfa0813b/coverage-7.13.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6e3370441f4513c6252bf042b9c36d22491142385049243253c7e48398a15a9f", size = 251419, upload-time = "2026-03-17T10:30:45.545Z" }, - { url = "https://files.pythonhosted.org/packages/8c/49/cd14b789536ac6a4778c453c6a2338bc0a2fb60c5a5a41b4008328b9acc1/coverage-7.13.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:03ccc709a17a1de074fb1d11f217342fb0d2b1582ed544f554fc9fc3f07e95f5", size = 254159, upload-time = "2026-03-17T10:30:47.204Z" }, - { url = "https://files.pythonhosted.org/packages/9d/00/7b0edcfe64e2ed4c0340dac14a52ad0f4c9bd0b8b5e531af7d55b703db7c/coverage-7.13.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3f4818d065964db3c1c66dc0fbdac5ac692ecbc875555e13374fdbe7eedb4376", size = 255270, upload-time = "2026-03-17T10:30:48.812Z" }, - { url = "https://files.pythonhosted.org/packages/93/89/7ffc4ba0f5d0a55c1e84ea7cee39c9fc06af7b170513d83fbf3bbefce280/coverage-7.13.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:012d5319e66e9d5a218834642d6c35d265515a62f01157a45bcc036ecf947256", size = 257538, upload-time = "2026-03-17T10:30:50.77Z" }, - { url = "https://files.pythonhosted.org/packages/81/bd/73ddf85f93f7e6fa83e77ccecb6162d9415c79007b4bc124008a4995e4a7/coverage-7.13.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8dd02af98971bdb956363e4827d34425cb3df19ee550ef92855b0acb9c7ce51c", size = 251821, upload-time = "2026-03-17T10:30:52.5Z" }, - { url = "https://files.pythonhosted.org/packages/a0/81/278aff4e8dec4926a0bcb9486320752811f543a3ce5b602cc7a29978d073/coverage-7.13.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f08fd75c50a760c7eb068ae823777268daaf16a80b918fa58eea888f8e3919f5", size = 253191, upload-time = "2026-03-17T10:30:54.543Z" }, - { url = "https://files.pythonhosted.org/packages/70/ee/fe1621488e2e0a58d7e94c4800f0d96f79671553488d401a612bebae324b/coverage-7.13.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:843ea8643cf967d1ac7e8ecd4bb00c99135adf4816c0c0593fdcc47b597fcf09", size = 251337, upload-time = "2026-03-17T10:30:56.663Z" }, - { url = "https://files.pythonhosted.org/packages/37/a6/f79fb37aa104b562207cc23cb5711ab6793608e246cae1e93f26b2236ed9/coverage-7.13.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:9d44d7aa963820b1b971dbecd90bfe5fe8f81cff79787eb6cca15750bd2f79b9", size = 255404, upload-time = "2026-03-17T10:30:58.427Z" }, - { url = "https://files.pythonhosted.org/packages/75/f0/ed15262a58ec81ce457ceb717b7f78752a1713556b19081b76e90896e8d4/coverage-7.13.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:7132bed4bd7b836200c591410ae7d97bf7ae8be6fc87d160b2bd881df929e7bf", size = 250903, upload-time = "2026-03-17T10:31:00.093Z" }, - { url = "https://files.pythonhosted.org/packages/0f/e9/9129958f20e7e9d4d56d51d42ccf708d15cac355ff4ac6e736e97a9393d2/coverage-7.13.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a698e363641b98843c517817db75373c83254781426e94ada3197cabbc2c919c", size = 252780, upload-time = "2026-03-17T10:31:01.916Z" }, - { url = "https://files.pythonhosted.org/packages/a4/d7/0ad9b15812d81272db94379fe4c6df8fd17781cc7671fdfa30c76ba5ff7b/coverage-7.13.5-cp312-cp312-win32.whl", hash = "sha256:bdba0a6b8812e8c7df002d908a9a2ea3c36e92611b5708633c50869e6d922fdf", size = 222093, upload-time = "2026-03-17T10:31:03.642Z" }, - { url = "https://files.pythonhosted.org/packages/29/3d/821a9a5799fac2556bcf0bd37a70d1d11fa9e49784b6d22e92e8b2f85f18/coverage-7.13.5-cp312-cp312-win_amd64.whl", hash = "sha256:d2c87e0c473a10bffe991502eac389220533024c8082ec1ce849f4218dded810", size = 222900, upload-time = "2026-03-17T10:31:05.651Z" }, - { url = "https://files.pythonhosted.org/packages/d4/fa/2238c2ad08e35cf4f020ea721f717e09ec3152aea75d191a7faf3ef009a8/coverage-7.13.5-cp312-cp312-win_arm64.whl", hash = "sha256:bf69236a9a81bdca3bff53796237aab096cdbf8d78a66ad61e992d9dac7eb2de", size = 221515, upload-time = "2026-03-17T10:31:07.293Z" }, - { url = "https://files.pythonhosted.org/packages/74/8c/74fedc9663dcf168b0a059d4ea756ecae4da77a489048f94b5f512a8d0b3/coverage-7.13.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ec4af212df513e399cf11610cc27063f1586419e814755ab362e50a85ea69c1", size = 219576, upload-time = "2026-03-17T10:31:09.045Z" }, - { url = "https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3", size = 219942, upload-time = "2026-03-17T10:31:10.708Z" }, - { url = "https://files.pythonhosted.org/packages/5f/13/93419671cee82b780bab7ea96b67c8ef448f5f295f36bf5031154ec9a790/coverage-7.13.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:da305e9937617ee95c2e39d8ff9f040e0487cbf1ac174f777ed5eddd7a7c1f26", size = 250935, upload-time = "2026-03-17T10:31:12.392Z" }, - { url = "https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3", size = 253541, upload-time = "2026-03-17T10:31:14.247Z" }, - { url = "https://files.pythonhosted.org/packages/4e/5e/3ee3b835647be646dcf3c65a7c6c18f87c27326a858f72ab22c12730773d/coverage-7.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02ca0eed225b2ff301c474aeeeae27d26e2537942aa0f87491d3e147e784a82b", size = 254780, upload-time = "2026-03-17T10:31:16.193Z" }, - { url = "https://files.pythonhosted.org/packages/44/b3/cb5bd1a04cfcc49ede6cd8409d80bee17661167686741e041abc7ee1b9a9/coverage-7.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:04690832cbea4e4663d9149e05dba142546ca05cb1848816760e7f58285c970a", size = 256912, upload-time = "2026-03-17T10:31:17.89Z" }, - { url = "https://files.pythonhosted.org/packages/1b/66/c1dceb7b9714473800b075f5c8a84f4588f887a90eb8645282031676e242/coverage-7.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0590e44dd2745c696a778f7bab6aa95256de2cbc8b8cff4f7db8ff09813d6969", size = 251165, upload-time = "2026-03-17T10:31:19.605Z" }, - { url = "https://files.pythonhosted.org/packages/b7/62/5502b73b97aa2e53ea22a39cf8649ff44827bef76d90bf638777daa27a9d/coverage-7.13.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d7cfad2d6d81dd298ab6b89fe72c3b7b05ec7544bdda3b707ddaecff8d25c161", size = 252908, upload-time = "2026-03-17T10:31:21.312Z" }, - { url = "https://files.pythonhosted.org/packages/7d/37/7792c2d69854397ca77a55c4646e5897c467928b0e27f2d235d83b5d08c6/coverage-7.13.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e092b9499de38ae0fbfbc603a74660eb6ff3e869e507b50d85a13b6db9863e15", size = 250873, upload-time = "2026-03-17T10:31:23.565Z" }, - { url = "https://files.pythonhosted.org/packages/a3/23/bc866fb6163be52a8a9e5d708ba0d3b1283c12158cefca0a8bbb6e247a43/coverage-7.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:48c39bc4a04d983a54a705a6389512883d4a3b9862991b3617d547940e9f52b1", size = 255030, upload-time = "2026-03-17T10:31:25.58Z" }, - { url = "https://files.pythonhosted.org/packages/7d/8b/ef67e1c222ef49860701d346b8bbb70881bef283bd5f6cbba68a39a086c7/coverage-7.13.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2d3807015f138ffea1ed9afeeb8624fd781703f2858b62a8dd8da5a0994c57b6", size = 250694, upload-time = "2026-03-17T10:31:27.316Z" }, - { url = "https://files.pythonhosted.org/packages/46/0d/866d1f74f0acddbb906db212e096dee77a8e2158ca5e6bb44729f9d93298/coverage-7.13.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee2aa19e03161671ec964004fb74b2257805d9710bf14a5c704558b9d8dbaf17", size = 252469, upload-time = "2026-03-17T10:31:29.472Z" }, - { url = "https://files.pythonhosted.org/packages/7a/f5/be742fec31118f02ce42b21c6af187ad6a344fed546b56ca60caacc6a9a0/coverage-7.13.5-cp313-cp313-win32.whl", hash = "sha256:ce1998c0483007608c8382f4ff50164bfc5bd07a2246dd272aa4043b75e61e85", size = 222112, upload-time = "2026-03-17T10:31:31.526Z" }, - { url = "https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl", hash = "sha256:631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b", size = 222923, upload-time = "2026-03-17T10:31:33.633Z" }, - { url = "https://files.pythonhosted.org/packages/48/af/fea819c12a095781f6ccd504890aaddaf88b8fab263c4940e82c7b770124/coverage-7.13.5-cp313-cp313-win_arm64.whl", hash = "sha256:f4cd16206ad171cbc2470dbea9103cf9a7607d5fe8c242fdf1edf36174020664", size = 221540, upload-time = "2026-03-17T10:31:35.445Z" }, - { url = "https://files.pythonhosted.org/packages/23/d2/17879af479df7fbbd44bd528a31692a48f6b25055d16482fdf5cdb633805/coverage-7.13.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0428cbef5783ad91fe240f673cc1f76b25e74bbfe1a13115e4aa30d3f538162d", size = 220262, upload-time = "2026-03-17T10:31:37.184Z" }, - { url = "https://files.pythonhosted.org/packages/5b/4c/d20e554f988c8f91d6a02c5118f9abbbf73a8768a3048cb4962230d5743f/coverage-7.13.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e0b216a19534b2427cc201a26c25da4a48633f29a487c61258643e89d28200c0", size = 220617, upload-time = "2026-03-17T10:31:39.245Z" }, - { url = "https://files.pythonhosted.org/packages/29/9c/f9f5277b95184f764b24e7231e166dfdb5780a46d408a2ac665969416d61/coverage-7.13.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:972a9cd27894afe4bc2b1480107054e062df08e671df7c2f18c205e805ccd806", size = 261912, upload-time = "2026-03-17T10:31:41.324Z" }, - { url = "https://files.pythonhosted.org/packages/d5/f6/7f1ab39393eeb50cfe4747ae8ef0e4fc564b989225aa1152e13a180d74f8/coverage-7.13.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4b59148601efcd2bac8c4dbf1f0ad6391693ccf7a74b8205781751637076aee3", size = 263987, upload-time = "2026-03-17T10:31:43.724Z" }, - { url = "https://files.pythonhosted.org/packages/a0/d7/62c084fb489ed9c6fbdf57e006752e7c516ea46fd690e5ed8b8617c7d52e/coverage-7.13.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:505d7083c8b0c87a8fa8c07370c285847c1f77739b22e299ad75a6af6c32c5c9", size = 266416, upload-time = "2026-03-17T10:31:45.769Z" }, - { url = "https://files.pythonhosted.org/packages/a9/f6/df63d8660e1a0bff6125947afda112a0502736f470d62ca68b288ea762d8/coverage-7.13.5-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:60365289c3741e4db327e7baff2a4aaacf22f788e80fa4683393891b70a89fbd", size = 267558, upload-time = "2026-03-17T10:31:48.293Z" }, - { url = "https://files.pythonhosted.org/packages/5b/02/353ca81d36779bd108f6d384425f7139ac3c58c750dcfaafe5d0bee6436b/coverage-7.13.5-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1b88c69c8ef5d4b6fe7dea66d6636056a0f6a7527c440e890cf9259011f5e606", size = 261163, upload-time = "2026-03-17T10:31:50.125Z" }, - { url = "https://files.pythonhosted.org/packages/2c/16/2e79106d5749bcaf3aee6d309123548e3276517cd7851faa8da213bc61bf/coverage-7.13.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5b13955d31d1633cf9376908089b7cebe7d15ddad7aeaabcbe969a595a97e95e", size = 263981, upload-time = "2026-03-17T10:31:51.961Z" }, - { url = "https://files.pythonhosted.org/packages/29/c7/c29e0c59ffa6942030ae6f50b88ae49988e7e8da06de7ecdbf49c6d4feae/coverage-7.13.5-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0", size = 261604, upload-time = "2026-03-17T10:31:53.872Z" }, - { url = "https://files.pythonhosted.org/packages/40/48/097cdc3db342f34006a308ab41c3a7c11c3f0d84750d340f45d88a782e00/coverage-7.13.5-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:084b84a8c63e8d6fc7e3931b316a9bcafca1458d753c539db82d31ed20091a87", size = 265321, upload-time = "2026-03-17T10:31:55.997Z" }, - { url = "https://files.pythonhosted.org/packages/bb/1f/4994af354689e14fd03a75f8ec85a9a68d94e0188bbdab3fc1516b55e512/coverage-7.13.5-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ad14385487393e386e2ea988b09d62dd42c397662ac2dabc3832d71253eee479", size = 260502, upload-time = "2026-03-17T10:31:58.308Z" }, - { url = "https://files.pythonhosted.org/packages/22/c6/9bb9ef55903e628033560885f5c31aa227e46878118b63ab15dc7ba87797/coverage-7.13.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7f2c47b36fe7709a6e83bfadf4eefb90bd25fbe4014d715224c4316f808e59a2", size = 262688, upload-time = "2026-03-17T10:32:00.141Z" }, - { url = "https://files.pythonhosted.org/packages/14/4f/f5df9007e50b15e53e01edea486814783a7f019893733d9e4d6caad75557/coverage-7.13.5-cp313-cp313t-win32.whl", hash = "sha256:67e9bc5449801fad0e5dff329499fb090ba4c5800b86805c80617b4e29809b2a", size = 222788, upload-time = "2026-03-17T10:32:02.246Z" }, - { url = "https://files.pythonhosted.org/packages/e1/98/aa7fccaa97d0f3192bec013c4e6fd6d294a6ed44b640e6bb61f479e00ed5/coverage-7.13.5-cp313-cp313t-win_amd64.whl", hash = "sha256:da86cdcf10d2519e10cabb8ac2de03da1bcb6e4853790b7fbd48523332e3a819", size = 223851, upload-time = "2026-03-17T10:32:04.416Z" }, - { url = "https://files.pythonhosted.org/packages/3d/8b/e5c469f7352651e5f013198e9e21f97510b23de957dd06a84071683b4b60/coverage-7.13.5-cp313-cp313t-win_arm64.whl", hash = "sha256:0ecf12ecb326fe2c339d93fc131816f3a7367d223db37817208905c89bded911", size = 222104, upload-time = "2026-03-17T10:32:06.65Z" }, - { url = "https://files.pythonhosted.org/packages/8e/77/39703f0d1d4b478bfd30191d3c14f53caf596fac00efb3f8f6ee23646439/coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f", size = 219621, upload-time = "2026-03-17T10:32:08.589Z" }, - { url = "https://files.pythonhosted.org/packages/e2/3e/51dff36d99ae14639a133d9b164d63e628532e2974d8b1edb99dd1ebc733/coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e", size = 219953, upload-time = "2026-03-17T10:32:10.507Z" }, - { url = "https://files.pythonhosted.org/packages/6a/6c/1f1917b01eb647c2f2adc9962bd66c79eb978951cab61bdc1acab3290c07/coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a", size = 250992, upload-time = "2026-03-17T10:32:12.41Z" }, - { url = "https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510", size = 253503, upload-time = "2026-03-17T10:32:14.449Z" }, - { url = "https://files.pythonhosted.org/packages/80/28/2a148a51e5907e504fa7b85490277734e6771d8844ebcc48764a15e28155/coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247", size = 254852, upload-time = "2026-03-17T10:32:16.56Z" }, - { url = "https://files.pythonhosted.org/packages/61/77/50e8d3d85cc0b7ebe09f30f151d670e302c7ff4a1bf6243f71dd8b0981fa/coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6", size = 257161, upload-time = "2026-03-17T10:32:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/3b/c4/b5fd1d4b7bf8d0e75d997afd3925c59ba629fc8616f1b3aae7605132e256/coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0", size = 251021, upload-time = "2026-03-17T10:32:21.344Z" }, - { url = "https://files.pythonhosted.org/packages/f8/66/6ea21f910e92d69ef0b1c3346ea5922a51bad4446c9126db2ae96ee24c4c/coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882", size = 252858, upload-time = "2026-03-17T10:32:23.506Z" }, - { url = "https://files.pythonhosted.org/packages/9e/ea/879c83cb5d61aa2a35fb80e72715e92672daef8191b84911a643f533840c/coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740", size = 250823, upload-time = "2026-03-17T10:32:25.516Z" }, - { url = "https://files.pythonhosted.org/packages/8a/fb/616d95d3adb88b9803b275580bdeee8bd1b69a886d057652521f83d7322f/coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16", size = 255099, upload-time = "2026-03-17T10:32:27.944Z" }, - { url = "https://files.pythonhosted.org/packages/1c/93/25e6917c90ec1c9a56b0b26f6cad6408e5f13bb6b35d484a0d75c9cf000d/coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0", size = 250638, upload-time = "2026-03-17T10:32:29.914Z" }, - { url = "https://files.pythonhosted.org/packages/fc/7b/dc1776b0464145a929deed214aef9fb1493f159b59ff3c7eeeedf91eddd0/coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0", size = 252295, upload-time = "2026-03-17T10:32:31.981Z" }, - { url = "https://files.pythonhosted.org/packages/ea/fb/99cbbc56a26e07762a2740713f3c8f9f3f3106e3a3dd8cc4474954bccd34/coverage-7.13.5-cp314-cp314-win32.whl", hash = "sha256:35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc", size = 222360, upload-time = "2026-03-17T10:32:34.233Z" }, - { url = "https://files.pythonhosted.org/packages/8d/b7/4758d4f73fb536347cc5e4ad63662f9d60ba9118cb6785e9616b2ce5d7fa/coverage-7.13.5-cp314-cp314-win_amd64.whl", hash = "sha256:2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633", size = 223174, upload-time = "2026-03-17T10:32:36.369Z" }, - { url = "https://files.pythonhosted.org/packages/2c/f2/24d84e1dfe70f8ac9fdf30d338239860d0d1d5da0bda528959d0ebc9da28/coverage-7.13.5-cp314-cp314-win_arm64.whl", hash = "sha256:1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8", size = 221739, upload-time = "2026-03-17T10:32:38.736Z" }, - { url = "https://files.pythonhosted.org/packages/60/5b/4a168591057b3668c2428bff25dd3ebc21b629d666d90bcdfa0217940e84/coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b", size = 220351, upload-time = "2026-03-17T10:32:41.196Z" }, - { url = "https://files.pythonhosted.org/packages/f5/21/1fd5c4dbfe4a58b6b99649125635df46decdfd4a784c3cd6d410d303e370/coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c", size = 220612, upload-time = "2026-03-17T10:32:43.204Z" }, - { url = "https://files.pythonhosted.org/packages/d6/fe/2a924b3055a5e7e4512655a9d4609781b0d62334fa0140c3e742926834e2/coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9", size = 261985, upload-time = "2026-03-17T10:32:45.514Z" }, - { url = "https://files.pythonhosted.org/packages/d7/0d/c8928f2bd518c45990fe1a2ab8db42e914ef9b726c975facc4282578c3eb/coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29", size = 264107, upload-time = "2026-03-17T10:32:47.971Z" }, - { url = "https://files.pythonhosted.org/packages/ef/ae/4ae35bbd9a0af9d820362751f0766582833c211224b38665c0f8de3d487f/coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607", size = 266513, upload-time = "2026-03-17T10:32:50.1Z" }, - { url = "https://files.pythonhosted.org/packages/9c/20/d326174c55af36f74eac6ae781612d9492f060ce8244b570bb9d50d9d609/coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90", size = 267650, upload-time = "2026-03-17T10:32:52.391Z" }, - { url = "https://files.pythonhosted.org/packages/7a/5e/31484d62cbd0eabd3412e30d74386ece4a0837d4f6c3040a653878bfc019/coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3", size = 261089, upload-time = "2026-03-17T10:32:54.544Z" }, - { url = "https://files.pythonhosted.org/packages/e9/d8/49a72d6de146eebb0b7e48cc0f4bc2c0dd858e3d4790ab2b39a2872b62bd/coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab", size = 263982, upload-time = "2026-03-17T10:32:56.803Z" }, - { url = "https://files.pythonhosted.org/packages/06/3b/0351f1bd566e6e4dd39e978efe7958bde1d32f879e85589de147654f57bb/coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562", size = 261579, upload-time = "2026-03-17T10:32:59.466Z" }, - { url = "https://files.pythonhosted.org/packages/5d/ce/796a2a2f4017f554d7810f5c573449b35b1e46788424a548d4d19201b222/coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2", size = 265316, upload-time = "2026-03-17T10:33:01.847Z" }, - { url = "https://files.pythonhosted.org/packages/3d/16/d5ae91455541d1a78bc90abf495be600588aff8f6db5c8b0dae739fa39c9/coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea", size = 260427, upload-time = "2026-03-17T10:33:03.945Z" }, - { url = "https://files.pythonhosted.org/packages/48/11/07f413dba62db21fb3fad5d0de013a50e073cc4e2dc4306e770360f6dfc8/coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a", size = 262745, upload-time = "2026-03-17T10:33:06.285Z" }, - { url = "https://files.pythonhosted.org/packages/91/15/d792371332eb4663115becf4bad47e047d16234b1aff687b1b18c58d60ae/coverage-7.13.5-cp314-cp314t-win32.whl", hash = "sha256:0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215", size = 223146, upload-time = "2026-03-17T10:33:08.756Z" }, - { url = "https://files.pythonhosted.org/packages/db/51/37221f59a111dca5e85be7dbf09696323b5b9f13ff65e0641d535ed06ea8/coverage-7.13.5-cp314-cp314t-win_amd64.whl", hash = "sha256:301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43", size = 224254, upload-time = "2026-03-17T10:33:11.174Z" }, - { url = "https://files.pythonhosted.org/packages/54/83/6acacc889de8987441aa7d5adfbdbf33d288dad28704a67e574f1df9bcbb/coverage-7.13.5-cp314-cp314t-win_arm64.whl", hash = "sha256:9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45", size = 222276, upload-time = "2026-03-17T10:33:13.466Z" }, - { url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl", hash = "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61", size = 211346, upload-time = "2026-03-17T10:33:15.691Z" }, +version = "7.15.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/d0/55fe630f4cf94e3fcba868240fad8c8cdd1f764e2a932f8926347e6ec4cd/coverage-7.15.2.tar.gz", hash = "sha256:3df60dc267f0a2ca23cb7a9ab1109c62b9335ffbf519fcfe167157c28c09b81d", size = 927741, upload-time = "2026-07-15T18:56:19.558Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/03/060ce69008ac97bbc01b1411b3e55b61f6f015659400b46749b662107831/coverage-7.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b5bd92ff1ec22e535eab0de75fa6db021992791f461a2aceb7822c625a1187d", size = 221284, upload-time = "2026-07-15T18:53:29.52Z" }, + { url = "https://files.pythonhosted.org/packages/fc/a3/d936e8b53edd9684100a6aefaf3fcabaa54728fe33324436c8d279c047aa/coverage-7.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:44826758cfe73fcd0e6af5deb4ba6d5417cc1d13df3acb35c93484a11160f846", size = 221799, upload-time = "2026-07-15T18:53:31.708Z" }, + { url = "https://files.pythonhosted.org/packages/ae/a3/ca234b06aec7ee28226f11d39a696b4481fe5eddfce8e03bf39979bb8ffb/coverage-7.15.2-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:09f5c6ec5901f667bd97dd140b5b9a2586b10efec66f46fb1e6d8135f8b95bdf", size = 248544, upload-time = "2026-07-15T18:53:33.212Z" }, + { url = "https://files.pythonhosted.org/packages/2b/89/dda79527bb7573ba91828b2fb91b3105d87378d6a2749ca0c0924ce0addd/coverage-7.15.2-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1d16e3a7104ea84f03e614611b3edbf6fb6892554b3ab0fe7fbb3f2b2ef04376", size = 250374, upload-time = "2026-07-15T18:53:34.683Z" }, + { url = "https://files.pythonhosted.org/packages/67/c6/c33755a34572f81f49a8c0cdf6b622f35ccb3238b136e1909daf0cdd4319/coverage-7.15.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d46e62cb35d91e6e2589fda6d28074426b0e276422b5d2ebef2c6b11dc60dbfd", size = 252239, upload-time = "2026-07-15T18:53:36.205Z" }, + { url = "https://files.pythonhosted.org/packages/b9/6f/dc341741b375be53a5baeee5b4bf0f0e525d38caed428f7932d23bb7bcb1/coverage-7.15.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dfd3db045e95960ae3683059571e597fda7cc610106a8916f77c5839048c1deb", size = 254150, upload-time = "2026-07-15T18:53:37.863Z" }, + { url = "https://files.pythonhosted.org/packages/e9/8d/966a18a5b195cb4e77b14c53f5f3dce22b5da05e6de7fafd1e08f2d2067a/coverage-7.15.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:affd532502d34c0472d0cdb181325c89f1d2c44992fef0c17e88e7b1576259a1", size = 249234, upload-time = "2026-07-15T18:53:39.394Z" }, + { url = "https://files.pythonhosted.org/packages/c5/8b/8b2e367496ab48484d48e79984fec76cdc1b7cb5d3a00ee799a5602e3ec9/coverage-7.15.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d17d7512151fedfcc64c1821a8977fc9be0dbf495754669afcab7b57abc98ae9", size = 250276, upload-time = "2026-07-15T18:53:41.027Z" }, + { url = "https://files.pythonhosted.org/packages/63/92/1199318a200eb6c8c6ce0192c892c8710ac791abbe0f35099294620bbfda/coverage-7.15.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e26ff680768b8095e8874aabe0e9d3a47a2a9f176a8340d05f8604c56457c23a", size = 248283, upload-time = "2026-07-15T18:53:42.557Z" }, + { url = "https://files.pythonhosted.org/packages/56/da/be284a55c5619bda891a89c27dfd59324a2c6a14d755cf6aac6960ceebeb/coverage-7.15.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:7e8f27131dc7cd53de2c137dd207b3720919320b3c20d499dc30aa9ee6173287", size = 252093, upload-time = "2026-07-15T18:53:44.271Z" }, + { url = "https://files.pythonhosted.org/packages/d4/53/ee112da833ddd77b73c6d781a98029b45b584b136615b4900ed0569f887e/coverage-7.15.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:728a33676d4c3f0db977990a4bd421dcaa3be3e53b5b6273036fff6666008e89", size = 248552, upload-time = "2026-07-15T18:53:45.7Z" }, + { url = "https://files.pythonhosted.org/packages/82/6a/802cfc802e9113494c80bf3f284cd4d72faeb1f24e244f61046af364f2ca/coverage-7.15.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:29c052f7c83ccfcc5c577eaae025d2e4a9bb80daf03c0ac31c996e83b000ce88", size = 249154, upload-time = "2026-07-15T18:53:47.256Z" }, + { url = "https://files.pythonhosted.org/packages/2c/65/529808e91d651147edae408fd9e894abc3b8cad7f3e594bbc36719a3e13a/coverage-7.15.2-cp310-cp310-win32.whl", hash = "sha256:1268ac8fb9ddcd783d3948dbabaf80a5d53bfdaa0575e873e2139a692f797443", size = 223334, upload-time = "2026-07-15T18:53:48.768Z" }, + { url = "https://files.pythonhosted.org/packages/68/0f/0e1829d7001130876dfbc0b4e1c737ea7c155b809e3e4a98a0aa268e2369/coverage-7.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:9f4432898c4bf2fba0435bbe35dd4437d7264565e5a88a21f5b49d8662a6b629", size = 223959, upload-time = "2026-07-15T18:53:50.429Z" }, + { url = "https://files.pythonhosted.org/packages/7d/3a/54536704f507d4573bf9161c4d0dd3dd59b6d85e48c664e901b6844d8e33/coverage-7.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f1ec6f304b156669cfde653b4e9a953f5de87e247ea02ac599bce0ab2744036", size = 221414, upload-time = "2026-07-15T18:53:51.941Z" }, + { url = "https://files.pythonhosted.org/packages/b6/d9/8ba925d29743e3577b21e4d8c11a702b76bc93c41e7fdfd1177af63d4b8d/coverage-7.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d3361879d736f469f45723c11ea1a5bbdaf1f6928f0e632c940378b5aa9b660", size = 221913, upload-time = "2026-07-15T18:53:53.682Z" }, + { url = "https://files.pythonhosted.org/packages/09/54/a855f3aa0187f2b431ade4e4791b77b56282cfb5d201c83ec26a31b5b36a/coverage-7.15.2-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c6a98d698f9e2c8008d0370ec7fc452ebfcc530002ae2d0061170d768b992589", size = 252332, upload-time = "2026-07-15T18:53:55.467Z" }, + { url = "https://files.pythonhosted.org/packages/8e/d3/13ac97b4370640ba3452fc8559b06cc2f479ce3ba4a0b632a73e44c38a7d/coverage-7.15.2-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d50dd325e18ec25bfcc10cd7f99b04df1ab9ec76b0918c260e60817ad0643dee", size = 254243, upload-time = "2026-07-15T18:53:57.055Z" }, + { url = "https://files.pythonhosted.org/packages/88/83/5eca144942d8d0659d3f55176517f4a59cdc65eefd17146a0770935a3ebd/coverage-7.15.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67d7602480a47bdf5b675635403625553ebaa70d5a62a657c035149fd401cea0", size = 256352, upload-time = "2026-07-15T18:53:58.83Z" }, + { url = "https://files.pythonhosted.org/packages/4e/ba/d3db2e01a50fc88cdb4c0f19542bcf6f61489e34dc9aa3538413e2459a38/coverage-7.15.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cee0f89f4767a6057c8fbf168f8135f18be651300496086bd873e3189fed0487", size = 258313, upload-time = "2026-07-15T18:54:00.497Z" }, + { url = "https://files.pythonhosted.org/packages/78/b3/aba83416e9177df28e5186d856c19158c59fc0e7e814aaa61a4a2354ad1b/coverage-7.15.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a29ec5305a7335aacee2d799e3422e91e1c8a12474986e2b3b07e315c91be82f", size = 252449, upload-time = "2026-07-15T18:54:02.456Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a5/4b00ecac0194431ab451b0f6710f8e2517d04cef60f821b14dec4637d575/coverage-7.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:48ccc6395958eda89093ecdc35644c86f23a8b23a7f4d44958812b721aad67c1", size = 254043, upload-time = "2026-07-15T18:54:04.072Z" }, + { url = "https://files.pythonhosted.org/packages/75/b6/cfa209b4313ee7f1b34da47efcd789ea51c024ad35af390e00f5a3c10a2e/coverage-7.15.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:81f382c5a94b434ec1f6da607edb904c76d7212e618cd4d1bc9f97bed4120ef5", size = 252107, upload-time = "2026-07-15T18:54:06.745Z" }, + { url = "https://files.pythonhosted.org/packages/36/67/e8cac5a6954038c98d7fe7eb9802afe7ab3ecb637bb7cc00e69b4148b56d/coverage-7.15.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bbc808daf4f5cd567af8075ecc72d21c6dfef9a254709a621a84c217c935ebc0", size = 255873, upload-time = "2026-07-15T18:54:08.48Z" }, + { url = "https://files.pythonhosted.org/packages/2c/92/395cca9f330a86c3fe3471d73e2c102116c4c58fdc619dbbc125c6e93a54/coverage-7.15.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a4c46b247b5d4b78f613bd89fea926d32b25c6cc61a50bd1e99ba310348f3dad", size = 251826, upload-time = "2026-07-15T18:54:10.083Z" }, + { url = "https://files.pythonhosted.org/packages/51/60/3e91b20295439652424f426b7086ec5bf4fbe3f604c73eda22b986c4fd6b/coverage-7.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:094dd37f3ef7b2da8b068b583d1f4c40f91c65197e16c52a71962d5d537fc5db", size = 252735, upload-time = "2026-07-15T18:54:11.878Z" }, + { url = "https://files.pythonhosted.org/packages/a5/eb/8c07839005e5e3c6b3877d3a6e2a80ce766589f31dd2b6882b78d59a7b8c/coverage-7.15.2-cp311-cp311-win32.whl", hash = "sha256:a63b9e190711134d581c4d703df5df09851b1acf99792c7aacbbe9f41f0283c9", size = 223500, upload-time = "2026-07-15T18:54:13.525Z" }, + { url = "https://files.pythonhosted.org/packages/2e/98/59d83c257cd59f0fbaf9d9ddb26b744a576760dfd1ae16e516408894a02b/coverage-7.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:8bb9f4b4279187560796a4cdaca3b0a93dd97e48ee667df005f4ed9a97403688", size = 223973, upload-time = "2026-07-15T18:54:15.163Z" }, + { url = "https://files.pythonhosted.org/packages/ea/09/2d285c8bef5c4f695d120c1c96dc11715638aa8e134069f210bb6a62a9fe/coverage-7.15.2-cp311-cp311-win_arm64.whl", hash = "sha256:8c726b232659cbd2ae57ade46509eb068c9bd7a06df9fcbff6fe484870006934", size = 223519, upload-time = "2026-07-15T18:54:16.803Z" }, + { url = "https://files.pythonhosted.org/packages/6a/50/eb5bf42e531611a9f8d272556b1ed4de503f84a91413584094487cf69f8f/coverage-7.15.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1adac78e5abc7c5438f7a209c9ca69d06542f0bf481d728b6989ea80b813fdf9", size = 221587, upload-time = "2026-07-15T18:54:18.439Z" }, + { url = "https://files.pythonhosted.org/packages/06/d1/da99af464c335d4e023a6efcd7ec30f63b88a43c93745154ab74ffb31cea/coverage-7.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b868acc62aa5de3be7a9d05c2333bf8359ca987e43f9cb30ff8fbda6a024ab73", size = 221943, upload-time = "2026-07-15T18:54:20.062Z" }, + { url = "https://files.pythonhosted.org/packages/5b/8a/13c42723d61ca447eafa18732e8141dd6a63f2732e1c7e1502c182dd88d7/coverage-7.15.2-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6f6966fc30e6f06ca8f98fb0ce51eda6b111b3ee8d066a8b1ec9e77fa06ab55d", size = 253450, upload-time = "2026-07-15T18:54:21.765Z" }, + { url = "https://files.pythonhosted.org/packages/d7/29/99021303f98fbdcb63504b4d07bea4cc025b9b2dd907c4f07c85d50a0dab/coverage-7.15.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:68af907f595ab01a78f794932ff3bdf929c316d3000810d38dbc247129e26f8b", size = 256187, upload-time = "2026-07-15T18:54:23.4Z" }, + { url = "https://files.pythonhosted.org/packages/f9/a8/fd503715ed6ca9c5d742923aa5209257340b367a867b2ced0c7d4ba8a0b9/coverage-7.15.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:afa29e2eff3d5729267e2cb2fd4ce9d61c952932fb2694e34ccb5d9540c6a296", size = 257301, upload-time = "2026-07-15T18:54:25.183Z" }, + { url = "https://files.pythonhosted.org/packages/da/40/3f4b8fb409810036ebc2857d36adc0498c6e957b5df0290c5036b2e143f1/coverage-7.15.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bbf44513ceb1589e31948e20eafbde9deaface90e1a1afa5f5f77b4423d17ce6", size = 259562, upload-time = "2026-07-15T18:54:27.204Z" }, + { url = "https://files.pythonhosted.org/packages/0b/8a/9bdffbef47db77cce3d6b02a28f7e919b19f0106c4b080c2c2246040f885/coverage-7.15.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9deddf09eecb717b7f980414b43d90a5b22ff3967d2949ab29cb0aa83d9e9098", size = 253841, upload-time = "2026-07-15T18:54:29.134Z" }, + { url = "https://files.pythonhosted.org/packages/1b/1e/9031efde019d31a06646261fce6dfc5c3c74e951e27a71e5c9a424563178/coverage-7.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ae901f7e55ba405c84ee1cab3d3e962e4e871e4a2bcb9c90911adbd69b42ac5a", size = 255221, upload-time = "2026-07-15T18:54:31.142Z" }, + { url = "https://files.pythonhosted.org/packages/56/db/787acde872389fc84a9ef9d8cd1ccc658e391ab4cb5b28092a714426a394/coverage-7.15.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a0f47002c6eeb7c280228467a4cb0cc15ca2103a8421b986b2d3ec04a0f9bd8b", size = 253366, upload-time = "2026-07-15T18:54:32.886Z" }, + { url = "https://files.pythonhosted.org/packages/2f/9b/6f57bc4b93c842eef1695f8cdaf2318e35e7ba54f5ba80d84be213ab7858/coverage-7.15.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1cd7a5beb7af3e864a13b1f0fb26efd3695da43ef0daf71e586adfffaf34d5b2", size = 257434, upload-time = "2026-07-15T18:54:34.7Z" }, + { url = "https://files.pythonhosted.org/packages/88/26/b3186a21b2acc83e451118978905c81c7072c3333707804db09a78c096a2/coverage-7.15.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:97a5c5457a9fb1d6c4e06cfb5dc835871fbfb6a6a51addc9e925bdeff5ef7440", size = 252935, upload-time = "2026-07-15T18:54:36.548Z" }, + { url = "https://files.pythonhosted.org/packages/20/c2/c9f3376b2e717ea69ed7a6e9a5fcab968fb0b290db6cf4bd9a1fc7541b75/coverage-7.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0901cfe6c13bcd2302da4f83e884555d2a22bda6e4c476f09ef204ba20ca536e", size = 254807, upload-time = "2026-07-15T18:54:38.296Z" }, + { url = "https://files.pythonhosted.org/packages/f0/e1/dfc15401f4a8aaeb486e1ba3e9e3c40522a6e38bd0ecf0b3f29cb8082957/coverage-7.15.2-cp312-cp312-win32.whl", hash = "sha256:b171bdd71cb7ff792bf32e376173b0ace7e7963e7e57c58dfc42063a6a7174cd", size = 223641, upload-time = "2026-07-15T18:54:40.103Z" }, + { url = "https://files.pythonhosted.org/packages/91/40/81b6d809d320cd366ec5bdf8176575e897dcb8efe7fb4b489ef9e93e4d13/coverage-7.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:582edc45c2040543fef83341be23c43024a3ab3ae0c2d8bc498a06282905ad40", size = 224172, upload-time = "2026-07-15T18:54:41.882Z" }, + { url = "https://files.pythonhosted.org/packages/ef/28/9f14ec438149f7de557f45518f09b4a7917b795cc37083aa7db482693f8c/coverage-7.15.2-cp312-cp312-win_arm64.whl", hash = "sha256:a638db90c61cd219aeee65e83a24fdaa57269a741ae0cf773309208ac862cee3", size = 223556, upload-time = "2026-07-15T18:54:43.674Z" }, + { url = "https://files.pythonhosted.org/packages/fc/d5/f8c838e6b7282976f7c918884b792df7a0c42c5bba5d99c60ad2d221d56d/coverage-7.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1121caa19159a38b5463eaae4b1e1fde81e525b15ecc5e000cd5b1a108f743a8", size = 221606, upload-time = "2026-07-15T18:54:45.448Z" }, + { url = "https://files.pythonhosted.org/packages/bf/37/97c926376364f66298cc44893b89cdf17b8bc406376497c4061ae4b8a8ff/coverage-7.15.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a300c6934e0989c327b9e8a1e110329da4641149f872bbe9f70168be66da76c1", size = 221982, upload-time = "2026-07-15T18:54:47.341Z" }, + { url = "https://files.pythonhosted.org/packages/b7/30/a36050a6e83c2135ee0776f452ca3948224befc6d7f26acecc082d0c106a/coverage-7.15.2-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2617f8799d268fabdeef42a7e89ac3a23e1deee9025427db2df970f99a89a578", size = 252972, upload-time = "2026-07-15T18:54:49.2Z" }, + { url = "https://files.pythonhosted.org/packages/31/d3/06b5f1daf95f0f15ab05bd75f26ba5f3c8b33d0bb72f3aaa3cf41d1bad3a/coverage-7.15.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7dc2950a2992cd676d35c20ae63522836deeb034f08874699d14068710af3dc1", size = 255569, upload-time = "2026-07-15T18:54:51.098Z" }, + { url = "https://files.pythonhosted.org/packages/81/1c/9afb3f8de2b8d36960391c48559a2e3ff96594b58099f115921549ea8d0d/coverage-7.15.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9e36686f7a442185db2400b3df171aac520869faf9deb59df687d28659eda2a6", size = 256806, upload-time = "2026-07-15T18:54:53.145Z" }, + { url = "https://files.pythonhosted.org/packages/64/d8/b989f96061a5e32d82fddd1b1b9ff48a7c8f8ae7606f0e80fd9de54b1e33/coverage-7.15.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d29ca7bd67af6e12e74632d65f026eabc1364da5c254494cd914446a28a3ef7", size = 258936, upload-time = "2026-07-15T18:54:55.015Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fa/f99771f5110457c7b511c1935ca49ddf288218eaa84322e028b9334146ae/coverage-7.15.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:db9c8438057e5b0f6a22a0af99c0c1d26b57fbbdbd1be5861ddb8f897fcc3a2d", size = 253178, upload-time = "2026-07-15T18:54:57.527Z" }, + { url = "https://files.pythonhosted.org/packages/f6/96/c098a6044d119c751ceede7be91035fa8310170ec24a6523aff72f0a5793/coverage-7.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:63022c4c8dec1d0342f05c3ede99842fe3d007689acc45e86f123a1746e4a026", size = 254934, upload-time = "2026-07-15T18:54:59.41Z" }, + { url = "https://files.pythonhosted.org/packages/b2/a2/1457b3a7a50c8d77500103b97a046db863e2f59a1cf6d2f814595f349885/coverage-7.15.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6c0be82b4d4aa5b2704e08518e2252f3e3d110164bcca826816801052e48a7aa", size = 252898, upload-time = "2026-07-15T18:55:01.338Z" }, + { url = "https://files.pythonhosted.org/packages/6c/0e/76958874c471ecfcdde0d2b2747bb2c61bdbf34a40636f4ce9db9923e643/coverage-7.15.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4510fb9cdf6bb02dfa6af0be4a534b8102d086e22e4a33f8836df663da3d660d", size = 257056, upload-time = "2026-07-15T18:55:03.243Z" }, + { url = "https://files.pythonhosted.org/packages/7c/7c/3d7c4e3bf58baa40327dc7edc2272b17cf02299366d52763db1b0ca1556a/coverage-7.15.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:42ec3d989421b174a2ab607c1539f24127ad362757b7f1c0c0d7a2993f7eb37b", size = 252718, upload-time = "2026-07-15T18:55:05.029Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b8/1cecffed9ce14fb25be9ba42d37b6bb61485c9a3ddd43cd3dde36b6087d8/coverage-7.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e8f91bce78e32343af184c3b7fa28fcf5a9e2641f4b6623d392038f804939188", size = 254490, upload-time = "2026-07-15T18:55:06.889Z" }, + { url = "https://files.pythonhosted.org/packages/6c/2c/42984561bc7f4c045dca67516a0c50ee5ef8d84352dbeb5559dc86c4823e/coverage-7.15.2-cp313-cp313-win32.whl", hash = "sha256:434e68d531858205895eb0d74b73d20b84260de426387d53c422a5acda2cf050", size = 223647, upload-time = "2026-07-15T18:55:08.941Z" }, + { url = "https://files.pythonhosted.org/packages/41/9f/39c7c9245efc583beddf89a87683574e663ed93637f3afb6cd7b88405676/coverage-7.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:26c3b04a6377fd7c09800921fa934e3a17c0020439cd59df73e73ae1d4b6a78c", size = 224190, upload-time = "2026-07-15T18:55:10.789Z" }, + { url = "https://files.pythonhosted.org/packages/c7/de/3a2883cf8a213659280ef4b403059e17a9acaeb7fc7fd4105e1226ff2e6d/coverage-7.15.2-cp313-cp313-win_arm64.whl", hash = "sha256:3ed010aa1b69cda8e827aabfca9866216c980e2dca82ab9a78c5f83689964c8b", size = 223583, upload-time = "2026-07-15T18:55:12.678Z" }, + { url = "https://files.pythonhosted.org/packages/81/5f/aed265fd7a3551a394f36dfe41868aee709b7f95db4052205b4ad1563ac3/coverage-7.15.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:40f633c5c5fc783732f6312280122e859538fa24461235597c13d803ea9a108a", size = 221650, upload-time = "2026-07-15T18:55:14.527Z" }, + { url = "https://files.pythonhosted.org/packages/6b/2c/222ba12a545189017120f8eddfc1a0bd4616b47d5d4a8d99421edb2fe4c6/coverage-7.15.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:075560438765b7a2ef43bf7aa7758661b53d889df47f062a31bda6c1ade553a2", size = 221988, upload-time = "2026-07-15T18:55:16.674Z" }, + { url = "https://files.pythonhosted.org/packages/aa/38/304b5877ab46e6c290b4292cfcf3fe28245f0e5597cad7f6acc91fc7e0a4/coverage-7.15.2-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:25fd15dd40a0a2c51a500d664ca29053c09c3259d998407bf982b6e114696138", size = 253029, upload-time = "2026-07-15T18:55:18.856Z" }, + { url = "https://files.pythonhosted.org/packages/6c/58/821b533b8db9e44cf1d8a97bd525149ced40dde1d0093da02cb78e715244/coverage-7.15.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b9a6367e4aff723e8ee8190836836124284e8fcd4265e307c844010cfa074f3f", size = 255536, upload-time = "2026-07-15T18:55:21.027Z" }, + { url = "https://files.pythonhosted.org/packages/f1/f2/7aa06604c389d32ea7f0a6a988359a7eafc3cd3f8e7bc2e88cd2fdf0b877/coverage-7.15.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9854ca62c152874b2060772503535be2e8f53f70b8aaa7686b094888d872f984", size = 256881, upload-time = "2026-07-15T18:55:23.125Z" }, + { url = "https://files.pythonhosted.org/packages/a2/4f/1ef342339c7916d0096bc5888cc0f653882cc7bc8f897d5cb89143287c9b/coverage-7.15.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:913b6c56e110da40e035bbd168353bf7aaa2544a5eaccea5d98a4629aac156c7", size = 259196, upload-time = "2026-07-15T18:55:25.099Z" }, + { url = "https://files.pythonhosted.org/packages/fe/f4/7ed055d7a9c5ec13b161773a115a5ccc6b0081d568c31fad830806306cc7/coverage-7.15.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aaccad4129d735a8a4d526f26929894c9a4e8ef7034566f210b176749d6906e3", size = 253036, upload-time = "2026-07-15T18:55:27.018Z" }, + { url = "https://files.pythonhosted.org/packages/14/79/ea82cca18c242a3a38b6c017da39726aa62dcb64aa635abf79b92009975c/coverage-7.15.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a164b50081fc7357331c4024ef4d17b78ba325f8380d05f5a69599a7e05257ee", size = 254887, upload-time = "2026-07-15T18:55:29.084Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ba/a136db3c0d9562b00e10b72540dbf3a33cd3bc5b95060c9308e247494623/coverage-7.15.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:bfd341ccf78128e72c094bc70cc25b3ef309c33c7c2c66ba3ed4309549e02de1", size = 252852, upload-time = "2026-07-15T18:55:31.184Z" }, + { url = "https://files.pythonhosted.org/packages/17/17/ea334246b16b7d059953fad6fdefa11e33c68efbd3fe37b1098120a1fac2/coverage-7.15.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:1473b3ba8e7ee0f076117b1a72c23f579a2b9e2bb742f48a8d86ea27ca93f91a", size = 257128, upload-time = "2026-07-15T18:55:33.163Z" }, + { url = "https://files.pythonhosted.org/packages/ed/c3/074fb66d46d607855f710876b117cbda562c5ab08363528e78820449f937/coverage-7.15.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:17c432b5f73ad52ef46fb06019f6fa7c66ce381961cf0f7dfd1d3a4bd3a98145", size = 252668, upload-time = "2026-07-15T18:55:35.063Z" }, + { url = "https://files.pythonhosted.org/packages/e1/c1/f620850ada9b36435921c9a3a8057013422b1d964eb4bf37fe138724d192/coverage-7.15.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:77f0ef5011df53a4bd1b35211ab122287f8d9b8d7aa1c4553e5c2deb24b1d446", size = 254325, upload-time = "2026-07-15T18:55:37.125Z" }, + { url = "https://files.pythonhosted.org/packages/cc/31/a729ca3689404493af82ef8e6ff70bd88bdda8da89aeef6ca9b387aeb2b4/coverage-7.15.2-cp314-cp314-win32.whl", hash = "sha256:f653e5d7248c1191ec988a85c72edeab46c3ff44f90639a4ed4874ec0be90243", size = 223844, upload-time = "2026-07-15T18:55:39.078Z" }, + { url = "https://files.pythonhosted.org/packages/c6/83/5d809dc808fb1698c671f3e372259bb9158e64b7ea526fc6ab7de64de9fe/coverage-7.15.2-cp314-cp314-win_amd64.whl", hash = "sha256:9911f31aad8906abe337c271343485cf20df5e70df5d2f57f9f136e7b55f26bc", size = 224331, upload-time = "2026-07-15T18:55:41.346Z" }, + { url = "https://files.pythonhosted.org/packages/16/4e/35e488548e952795829e129995c4174df33bf432b591d1aa42c8d9e4e7ad/coverage-7.15.2-cp314-cp314-win_arm64.whl", hash = "sha256:e38def96ad59853824c97953fdcd2c320a84ba3ce99b417db78af8bb6c3db635", size = 223760, upload-time = "2026-07-15T18:55:43.518Z" }, + { url = "https://files.pythonhosted.org/packages/ed/49/dd2c86cd6374038f6e415fb5bfb86db5218553209c081384a020369dee79/coverage-7.15.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:835ec4e20b45f0a7f63ed78f94065aca00de033403df8377bfe8b9c6abc0a7be", size = 222384, upload-time = "2026-07-15T18:55:45.569Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/173ff17a1c0808e5a438f549f6f145d5ac7528f2791310b63523e3200ac7/coverage-7.15.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7466cc7ab6dc0db871d264bf99e8779f0917ee63d40730af0552f71535a6e072", size = 222647, upload-time = "2026-07-15T18:55:47.544Z" }, + { url = "https://files.pythonhosted.org/packages/84/f8/b8cba872162356fb44ac79c10309d987206a4461e32072fc29228dad7331/coverage-7.15.2-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e370c12133095ff18432de8c044962be85a5a96d90c6fcbce8e17e76236d2328", size = 264013, upload-time = "2026-07-15T18:55:49.768Z" }, + { url = "https://files.pythonhosted.org/packages/ee/67/a807a7586d0b8cae485308ddd55756f0806c92f8e0b411bacbf23c48edf3/coverage-7.15.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fe41909c9515c3bfdb5f02c4d1f857dba322d9a9a1178069b91eea77889df63a", size = 266135, upload-time = "2026-07-15T18:55:51.941Z" }, + { url = "https://files.pythonhosted.org/packages/ce/67/cd78771dc985f7e4ebdcc82b1a96d9a932af9e806f01f2f91a89f4c72e80/coverage-7.15.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6aa28cfb6488e5453b5b762d65f73aa586380f6693a04d58078ce228a29b06c0", size = 268555, upload-time = "2026-07-15T18:55:54.065Z" }, + { url = "https://files.pythonhosted.org/packages/18/3e/10134cf81275188c58568f324fc74aedff32c63ca4d5bbc513a91944a6f0/coverage-7.15.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bcc0aae933921d03096f53b0b03eeb702129fd406dee59f08d2efacc68681fa5", size = 269674, upload-time = "2026-07-15T18:55:56.066Z" }, + { url = "https://files.pythonhosted.org/packages/75/4a/771b77de446cba985dc414bbc5844bd21604da05dbc044286df8318a48a7/coverage-7.15.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7c63387e21ab21f512c69c9756a8c7dadd322c7275edb064064433c9a09c3743", size = 263101, upload-time = "2026-07-15T18:55:58.107Z" }, + { url = "https://files.pythonhosted.org/packages/5f/b5/70a7011da15f4071943361183aefa27847f3e3aec4fd335f1cb3d3a622b1/coverage-7.15.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e55510bc98ae943cece9e667a6c0fe94c6a92913720dea34243657a17993d0c", size = 266007, upload-time = "2026-07-15T18:56:00.468Z" }, + { url = "https://files.pythonhosted.org/packages/b4/0d/f9547e804ce7ad49646ffeffac26699510efbe6c0f751b66fdc960c4e825/coverage-7.15.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:2ff08701be2d1556fc78b326c80a3e8042da09352ecb3819105f8e386c8a3071", size = 263611, upload-time = "2026-07-15T18:56:02.615Z" }, + { url = "https://files.pythonhosted.org/packages/ac/59/f576a396659c0efd351f5c1544f67c3560e89c7761cabf7f65e412beeda5/coverage-7.15.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:38c9518b7103826c403a461544e3c2e77151e8676d06eaed85911a97e962584a", size = 267344, upload-time = "2026-07-15T18:56:04.622Z" }, + { url = "https://files.pythonhosted.org/packages/7c/5d/c2e4fce3579c0cb635024293f1a32bbe26df101b3e3a69f22243d1352b6c/coverage-7.15.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:dee88b1ed88587abd8c0269a1fc1f4cc77f7750d1dfde2869e2a123af420e67d", size = 262456, upload-time = "2026-07-15T18:56:06.641Z" }, + { url = "https://files.pythonhosted.org/packages/bb/dd/956287d69436b66094bc4b57ac2da71e43bfd2a5524e958900b9f582fcf8/coverage-7.15.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2fbeeeecea279727f8ac16c8e1133ddfeee793e985c86ae343d6a5ce744eef8c", size = 264771, upload-time = "2026-07-15T18:56:08.795Z" }, + { url = "https://files.pythonhosted.org/packages/2c/5a/6f979530c2734c575de77cf58f5f28d51f7123a94b5030fd9156fe5f363c/coverage-7.15.2-cp314-cp314t-win32.whl", hash = "sha256:cb0fddaa6884be6aae36ced9544b5e90f7d5f03845a2853bf47a14953a4e8688", size = 224151, upload-time = "2026-07-15T18:56:10.856Z" }, + { url = "https://files.pythonhosted.org/packages/54/7e/27f6b2a74d484742f4017553e710b01e396b23d809df3e95ca0bb9a2824b/coverage-7.15.2-cp314-cp314t-win_amd64.whl", hash = "sha256:77f091ea3a9cc611cd29f433565476bc1936c084ac8eee00ea0e7e70c27e4199", size = 224981, upload-time = "2026-07-15T18:56:12.928Z" }, + { url = "https://files.pythonhosted.org/packages/b1/48/284863423aa474240f6842bd00d680da22f4e6ea2e466618ef7c9c9e69a9/coverage-7.15.2-cp314-cp314t-win_arm64.whl", hash = "sha256:6fc448c377d6eeb00a47c673494bd9bae29280ca53987e1869e67ebedfe20658", size = 224294, upload-time = "2026-07-15T18:56:15.156Z" }, + { url = "https://files.pythonhosted.org/packages/ec/82/32e3bd191d498e64f6f911ad55d14006a0861e54869d2d32452326399e65/coverage-7.15.2-py3-none-any.whl", hash = "sha256:eb6bcae8d1a9d305351ecb108232441d11c5cfe9de840a04388ba5d2db8d735c", size = 213375, upload-time = "2026-07-15T18:56:17.305Z" }, ] [package.optional-dependencies] @@ -639,62 +744,59 @@ toml = [ [[package]] name = "cryptography" -version = "47.0.0" +version = "49.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ef/b2/7ffa7fe8207a8c42147ffe70c3e360b228160c1d85dc3faff16aaa3244c0/cryptography-47.0.0.tar.gz", hash = "sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb", size = 830863, upload-time = "2026-04-24T19:54:57.056Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/98/40dfe932134bdcae4f6ab5927c87488754bf9eb79297d7e0070b78dd58e9/cryptography-47.0.0-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0", size = 7912214, upload-time = "2026-04-24T19:53:03.864Z" }, - { url = "https://files.pythonhosted.org/packages/34/c6/2733531243fba725f58611b918056b277692f1033373dcc8bd01af1c05d4/cryptography-47.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973", size = 4644617, upload-time = "2026-04-24T19:53:06.909Z" }, - { url = "https://files.pythonhosted.org/packages/00/e3/b27be1a670a9b87f855d211cf0e1174a5d721216b7616bd52d8581d912ed/cryptography-47.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8", size = 4668186, upload-time = "2026-04-24T19:53:09.053Z" }, - { url = "https://files.pythonhosted.org/packages/81/b9/8443cfe5d17d482d348cee7048acf502bb89a51b6382f06240fd290d4ca3/cryptography-47.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b", size = 4651244, upload-time = "2026-04-24T19:53:11.217Z" }, - { url = "https://files.pythonhosted.org/packages/5d/5e/13ed0cdd0eb88ba159d6dd5ebfece8cb901dbcf1ae5ac4072e28b55d3153/cryptography-47.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92", size = 5252906, upload-time = "2026-04-24T19:53:13.532Z" }, - { url = "https://files.pythonhosted.org/packages/64/16/ed058e1df0f33d440217cd120d41d5dda9dd215a80b8187f68483185af82/cryptography-47.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7", size = 4701842, upload-time = "2026-04-24T19:53:15.618Z" }, - { url = "https://files.pythonhosted.org/packages/02/e0/3d30986b30fdbd9e969abbdf8ba00ed0618615144341faeb57f395a084fe/cryptography-47.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93", size = 4289313, upload-time = "2026-04-24T19:53:17.755Z" }, - { url = "https://files.pythonhosted.org/packages/df/fd/32db38e3ad0cb331f0691cb4c7a8a6f176f679124dee746b3af6633db4d9/cryptography-47.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac", size = 4650964, upload-time = "2026-04-24T19:53:20.062Z" }, - { url = "https://files.pythonhosted.org/packages/86/53/5395d944dfd48cb1f67917f533c609c34347185ef15eb4308024c876f274/cryptography-47.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f", size = 5207817, upload-time = "2026-04-24T19:53:22.498Z" }, - { url = "https://files.pythonhosted.org/packages/34/4f/e5711b28e1901f7d480a2b1b688b645aa4c77c73f10731ed17e7f7db3f0d/cryptography-47.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8", size = 4701544, upload-time = "2026-04-24T19:53:24.356Z" }, - { url = "https://files.pythonhosted.org/packages/22/22/c8ddc25de3010fc8da447648f5a092c40e7a8fadf01dd6d255d9c0b9373d/cryptography-47.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318", size = 4783536, upload-time = "2026-04-24T19:53:26.665Z" }, - { url = "https://files.pythonhosted.org/packages/66/b6/d4a68f4ea999c6d89e8498579cba1c5fcba4276284de7773b17e4fa69293/cryptography-47.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001", size = 4926106, upload-time = "2026-04-24T19:53:28.686Z" }, - { url = "https://files.pythonhosted.org/packages/54/ed/5f524db1fade9c013aa618e1c99c6ed05e8ffc9ceee6cda22fed22dda3f4/cryptography-47.0.0-cp311-abi3-win32.whl", hash = "sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203", size = 3258581, upload-time = "2026-04-24T19:53:31.058Z" }, - { url = "https://files.pythonhosted.org/packages/b2/dc/1b901990b174786569029f67542b3edf72ac068b6c3c8683c17e6a2f5363/cryptography-47.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa", size = 3775309, upload-time = "2026-04-24T19:53:33.054Z" }, - { url = "https://files.pythonhosted.org/packages/14/88/7aa18ad9c11bc87689affa5ce4368d884b517502d75739d475fc6f4a03c7/cryptography-47.0.0-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0", size = 7904299, upload-time = "2026-04-24T19:53:35.003Z" }, - { url = "https://files.pythonhosted.org/packages/07/55/c18f75724544872f234678fdedc871391722cb34a2aee19faa9f63100bb2/cryptography-47.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7", size = 4631180, upload-time = "2026-04-24T19:53:37.517Z" }, - { url = "https://files.pythonhosted.org/packages/ee/65/31a5cc0eaca99cec5bafffe155d407115d96136bb161e8b49e0ef73f09a7/cryptography-47.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1", size = 4653529, upload-time = "2026-04-24T19:53:39.775Z" }, - { url = "https://files.pythonhosted.org/packages/e5/bc/641c0519a495f3bfd0421b48d7cd325c4336578523ccd76ea322b6c29c7a/cryptography-47.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c", size = 4638570, upload-time = "2026-04-24T19:53:42.129Z" }, - { url = "https://files.pythonhosted.org/packages/2b/f2/300327b0a47f6dc94dd8b71b57052aefe178bb51745073d73d80604f11ab/cryptography-47.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829", size = 5238019, upload-time = "2026-04-24T19:53:44.577Z" }, - { url = "https://files.pythonhosted.org/packages/e9/5a/5b5cf994391d4bf9d9c7efd4c66aabe4d95227256627f8fea6cff7dfadbd/cryptography-47.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7", size = 4686832, upload-time = "2026-04-24T19:53:47.015Z" }, - { url = "https://files.pythonhosted.org/packages/dc/2c/ae950e28fd6475c852fc21a44db3e6b5bcc1261d1e370f2b6e42fa800fef/cryptography-47.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923", size = 4269301, upload-time = "2026-04-24T19:53:48.97Z" }, - { url = "https://files.pythonhosted.org/packages/67/fb/6a39782e150ffe5cc1b0018cb6ddc48bf7ca62b498d7539ffc8a758e977d/cryptography-47.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab", size = 4638110, upload-time = "2026-04-24T19:53:51.011Z" }, - { url = "https://files.pythonhosted.org/packages/8e/d7/0b3c71090a76e5c203164a47688b697635ece006dcd2499ab3a4dbd3f0bd/cryptography-47.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736", size = 5194988, upload-time = "2026-04-24T19:53:52.962Z" }, - { url = "https://files.pythonhosted.org/packages/63/33/63a961498a9df51721ab578c5a2622661411fc520e00bd83b0cc64eb20c4/cryptography-47.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7", size = 4686563, upload-time = "2026-04-24T19:53:55.274Z" }, - { url = "https://files.pythonhosted.org/packages/b7/bf/5ee5b145248f92250de86145d1c1d6edebbd57a7fe7caa4dedb5d4cf06a1/cryptography-47.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52", size = 4770094, upload-time = "2026-04-24T19:53:57.753Z" }, - { url = "https://files.pythonhosted.org/packages/92/43/21d220b2da5d517773894dacdcdb5c682c28d3fffce65548cb06e87d5501/cryptography-47.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd", size = 4913811, upload-time = "2026-04-24T19:54:00.236Z" }, - { url = "https://files.pythonhosted.org/packages/31/98/dc4ad376ac5f1a1a7d4a83f7b0c6f2bcad36b5d2d8f30aeb482d3a7d9582/cryptography-47.0.0-cp314-cp314t-win32.whl", hash = "sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63", size = 3237158, upload-time = "2026-04-24T19:54:02.606Z" }, - { url = "https://files.pythonhosted.org/packages/bc/da/97f62d18306b5133468bc3f8cc73a3111e8cdc8cf8d3e69474d6e5fd2d1b/cryptography-47.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b", size = 3758706, upload-time = "2026-04-24T19:54:04.433Z" }, - { url = "https://files.pythonhosted.org/packages/e0/34/a4fae8ae7c3bc227460c9ae43f56abf1b911da0ec29e0ebac53bb0a4b6b7/cryptography-47.0.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4", size = 7904072, upload-time = "2026-04-24T19:54:06.411Z" }, - { url = "https://files.pythonhosted.org/packages/01/64/d7b1e54fdb69f22d24a64bb3e88dc718b31c7fb10ef0b9691a3cf7eeea6e/cryptography-47.0.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27", size = 4635767, upload-time = "2026-04-24T19:54:08.519Z" }, - { url = "https://files.pythonhosted.org/packages/8b/7b/cca826391fb2a94efdcdfe4631eb69306ee1cff0b22f664a412c90713877/cryptography-47.0.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10", size = 4654350, upload-time = "2026-04-24T19:54:10.795Z" }, - { url = "https://files.pythonhosted.org/packages/4c/65/4b57bcc823f42a991627c51c2f68c9fd6eb1393c1756aac876cba2accae2/cryptography-47.0.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b", size = 4643394, upload-time = "2026-04-24T19:54:13.275Z" }, - { url = "https://files.pythonhosted.org/packages/f4/c4/2c5fbeea70adbbca2bbae865e1d605d6a4a7f8dbd9d33eaf69645087f06c/cryptography-47.0.0-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74", size = 5225777, upload-time = "2026-04-24T19:54:15.18Z" }, - { url = "https://files.pythonhosted.org/packages/7e/b8/ac57107ef32749d2b244e36069bb688792a363aaaa3acc9e3cf84c130315/cryptography-47.0.0-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515", size = 4688771, upload-time = "2026-04-24T19:54:17.835Z" }, - { url = "https://files.pythonhosted.org/packages/56/fc/9f1de22ff8be99d991f240a46863c52d475404c408886c5a38d2b5c3bb26/cryptography-47.0.0-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc", size = 4270753, upload-time = "2026-04-24T19:54:19.963Z" }, - { url = "https://files.pythonhosted.org/packages/00/68/d70c852797aa68e8e48d12e5a87170c43f67bb4a59403627259dd57d15de/cryptography-47.0.0-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca", size = 4642911, upload-time = "2026-04-24T19:54:21.818Z" }, - { url = "https://files.pythonhosted.org/packages/a5/51/661cbee74f594c5d97ff82d34f10d5551c085ca4668645f4606ebd22bd5d/cryptography-47.0.0-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76", size = 5181411, upload-time = "2026-04-24T19:54:24.376Z" }, - { url = "https://files.pythonhosted.org/packages/94/87/f2b6c374a82cf076cfa1416992ac8e8ec94d79facc37aec87c1a5cb72352/cryptography-47.0.0-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe", size = 4688262, upload-time = "2026-04-24T19:54:26.946Z" }, - { url = "https://files.pythonhosted.org/packages/14/e2/8b7462f4acf21ec509616f0245018bb197194ab0b65c2ea21a0bdd53c0eb/cryptography-47.0.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31", size = 4775506, upload-time = "2026-04-24T19:54:28.926Z" }, - { url = "https://files.pythonhosted.org/packages/70/75/158e494e4c08dc05e039da5bb48553826bd26c23930cf8d3cd5f21fa8921/cryptography-47.0.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7", size = 4912060, upload-time = "2026-04-24T19:54:30.869Z" }, - { url = "https://files.pythonhosted.org/packages/06/bd/0a9d3edbf5eadbac926d7b9b3cd0c4be584eeeae4a003d24d9eda4affbbd/cryptography-47.0.0-cp38-abi3-win32.whl", hash = "sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310", size = 3248487, upload-time = "2026-04-24T19:54:33.494Z" }, - { url = "https://files.pythonhosted.org/packages/60/80/5681af756d0da3a599b7bdb586fac5a1540f1bcefd2717a20e611ddade45/cryptography-47.0.0-cp38-abi3-win_amd64.whl", hash = "sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769", size = 3755737, upload-time = "2026-04-24T19:54:35.408Z" }, - { url = "https://files.pythonhosted.org/packages/1b/a0/928c9ce0d120a40a81aa99e3ba383e87337b9ac9ef9f6db02e4d7822424d/cryptography-47.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7", size = 3909893, upload-time = "2026-04-24T19:54:38.334Z" }, - { url = "https://files.pythonhosted.org/packages/81/75/d691e284750df5d9569f2b1ce4a00a71e1d79566da83b2b3e5549c84917f/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe", size = 4587867, upload-time = "2026-04-24T19:54:40.619Z" }, - { url = "https://files.pythonhosted.org/packages/07/d6/1b90f1a4e453009730b4545286f0b39bb348d805c11181fc31544e4f9a65/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475", size = 4627192, upload-time = "2026-04-24T19:54:42.849Z" }, - { url = "https://files.pythonhosted.org/packages/dc/53/cb358a80e9e359529f496870dd08c102aa8a4b5b9f9064f00f0d6ed5b527/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50", size = 4587486, upload-time = "2026-04-24T19:54:44.908Z" }, - { url = "https://files.pythonhosted.org/packages/8b/57/aaa3d53876467a226f9a7a82fd14dd48058ad2de1948493442dfa16e2ffd/cryptography-47.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab", size = 4626327, upload-time = "2026-04-24T19:54:47.813Z" }, - { url = "https://files.pythonhosted.org/packages/ab/9c/51f28c3550276bcf35660703ba0ab829a90b88be8cd98a71ef23c2413913/cryptography-47.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8", size = 3698916, upload-time = "2026-04-24T19:54:49.782Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/1f/99/d1c90d6041656cc6ee229dc99cd67fd0cd5aec3c5f7d72fffc27cc750054/cryptography-49.0.0.tar.gz", hash = "sha256:f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493", size = 854345, upload-time = "2026-06-12T20:02:30.512Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/22/adf66990e63584a68dfb50c24f48a125c07b1699899381c8151e63ed458c/cryptography-49.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:966fe0e9c67490071f14c0d2b1cb2dfb3023c5ce39457343931415f08382f2db", size = 4032100, upload-time = "2026-06-12T20:02:32.143Z" }, + { url = "https://files.pythonhosted.org/packages/09/41/3797cfaf69cae04a13ee78ebd83f0678d9c02b4779d21ce24445326f1a69/cryptography-49.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36d1709f992593689b45bda411498d62c6e365f2ca00b84657d4dadd24de16db", size = 4692978, upload-time = "2026-06-12T20:01:21.305Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8b/43011f7ebe515a8aa20d61f290a326cd890c2e738e16e59eaff8d9c3a412/cryptography-49.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e959b578856a3924bc0cbb710fc12c387b9412a951389f3ca61704a9e25f325", size = 4716422, upload-time = "2026-06-12T20:01:48.566Z" }, + { url = "https://files.pythonhosted.org/packages/4a/91/01ce7303a4579e6d3a6abef01bd322848e9ea7a219adcabc5048b9033571/cryptography-49.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:53ecee2e23f7169b6117e99fc8a944e5e50f79e69758a83b52a00cb98ab2b2d2", size = 4700503, upload-time = "2026-06-12T20:02:47.091Z" }, + { url = "https://files.pythonhosted.org/packages/62/99/a2c95cf8293f07491e9e27c20cc4dcd18176d944e674679adeb1d0173fd6/cryptography-49.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:2eda353d8a27bcbcaa4cbed18994a74ab4d19a2ca897db188ea269ab9b71419b", size = 5309779, upload-time = "2026-06-12T20:02:08.987Z" }, + { url = "https://files.pythonhosted.org/packages/20/2c/0622f20ff02b2ef32558733443805dc82fd4c275be01b2d19d14676f3a1b/cryptography-49.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2afe9051da7ae7bd5905da5a949280c7d2bb75682e188f650a9d0f2756b834c6", size = 4749683, upload-time = "2026-06-12T20:02:03.335Z" }, + { url = "https://files.pythonhosted.org/packages/a3/5b/c5246635d5fd3b64e0d45ae10e99fd32fe9676a79915ccfe5a61ba9af1a5/cryptography-49.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:0b82e28ee398a386f0807bba7884d30f25218855690f45115831bcce5d90822c", size = 4337874, upload-time = "2026-06-12T20:02:54.323Z" }, + { url = "https://files.pythonhosted.org/packages/6d/88/05563c7fe2e914e87d1a536d06fe83e66b4e1d95cb593e05aea375531da8/cryptography-49.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ccac2bfebc306b862133e3bb71f3f6ee8bb525240089b2d952e4144b3a6d5da7", size = 4700283, upload-time = "2026-06-12T20:01:34.822Z" }, + { url = "https://files.pythonhosted.org/packages/c4/b6/d7696e4e890d6ae1469935164c9e5215c557671cb78d6e3f458ccceaa632/cryptography-49.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:d0527ce944105f257f605a827d6ebead966c752038b6e8656abb9c5edee6fc68", size = 5265844, upload-time = "2026-06-12T20:01:24.09Z" }, + { url = "https://files.pythonhosted.org/packages/a9/3c/f3ad17eecc1a57b0ba236dc01f90e783c51f4a2f35f64777cc4f47a184b2/cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:cbc77da8c523d5abd028635ba850a6966fcee2c82e2bf65a41d1d8afe0f98be9", size = 4749290, upload-time = "2026-06-12T20:01:30.848Z" }, + { url = "https://files.pythonhosted.org/packages/4f/01/339573cf1023163a400b0b5d16f6d507de413b9f60be6fd1b77feeaf6737/cryptography-49.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b87e65d263b3e5d3bb92a57e2a6638e2f31110fa7aa890c7b2dbba42248d0a3f", size = 4834612, upload-time = "2026-06-12T20:01:29.246Z" }, + { url = "https://files.pythonhosted.org/packages/71/fd/577302e213a1be9468f92d1afef66fcf1ef83d516819d9992ca547f592bd/cryptography-49.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:66ec79c3904820572d7e987abdf304281f141d37ad9a489b8e97066e7b9b6459", size = 4980804, upload-time = "2026-06-12T20:01:42.853Z" }, + { url = "https://files.pythonhosted.org/packages/1f/09/f42b1d190c5ba75f72062a387f8030d1d75f6ab035788f1d9c4b01de6525/cryptography-49.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:e5dfc1e64de5677cec922ffa8da89c546d0415bf6efdf081842e5d44c84e1f0e", size = 3810026, upload-time = "2026-06-12T20:02:39.262Z" }, + { url = "https://files.pythonhosted.org/packages/ec/9e/db72b3ae7fc9cfad53e630e56c6ae83b9b6ff0bf3718ffb8012d20b3aabf/cryptography-49.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:73a205dce83953d131a4aa1e0fd917a2fd1c5b1eef251e9d7152efefcbf5caf7", size = 4013892, upload-time = "2026-06-12T20:02:10.735Z" }, + { url = "https://files.pythonhosted.org/packages/86/12/c48a424f38db03027be9f7ed5c7dc5de9933dbee992865f98b13727a009d/cryptography-49.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:196ecd6a36e4e9aa10270393bb98d8df88fccee0bf1e5128b91ae4eb4375896d", size = 4678835, upload-time = "2026-06-12T20:02:48.743Z" }, + { url = "https://files.pythonhosted.org/packages/68/28/8a3ad4653662c93fc44dc4e5d8fd374c25c42e07b34bbfbadf49cf57a5a8/cryptography-49.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7abcee80084cda3f7691f3eb1ce480d8df49cec637b429aa35986c1de71738aa", size = 4697239, upload-time = "2026-06-12T20:02:56.03Z" }, + { url = "https://files.pythonhosted.org/packages/a8/b2/2193fc74f81aee4f9b62733133b73b5176718932ed8f2e4b03fa040480a6/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:4ae387c9cb68ea569ca17e490d66d8142b81c3cc814bf179974b7d146e490bbb", size = 4685593, upload-time = "2026-06-12T20:02:50.666Z" }, + { url = "https://files.pythonhosted.org/packages/47/f1/1d3eaa243bfc5de4a187b22aa8c048b3e4980bfbe830ac46e6bac2e66947/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:f37d847238971164fdbc68ade6f6574aecc9c0af714190e2083429ff68f4ce9d", size = 5289961, upload-time = "2026-06-12T20:01:46.468Z" }, + { url = "https://files.pythonhosted.org/packages/58/39/2d51306721330c486495853eda1c567880ff036de15a14c4b74f399934af/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:c2bc30226390d60ea19d9f82b19db005fe0452154a23c1c410c12ea801e43561", size = 4731145, upload-time = "2026-06-12T20:02:16.832Z" }, + { url = "https://files.pythonhosted.org/packages/17/50/983e838c7fd0d87fd8c969bcdd328edaf5f756e38df5281637424c155873/cryptography-49.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:07cab27cc7b7e0fd28e5e26bb9eeedde5c135c868b46de4a27845abe94af6122", size = 4321719, upload-time = "2026-06-12T20:02:52.611Z" }, + { url = "https://files.pythonhosted.org/packages/a7/f5/8f571d7e27c55bce9f76f026143bcb1e040a4233149ecca0bea5fa5dd5f7/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:b20133d204d2bb56ba047642199603876c872026ca53e79c35b83772ab2cc505", size = 4685209, upload-time = "2026-06-12T20:02:07.282Z" }, + { url = "https://files.pythonhosted.org/packages/e7/84/0e27016a6fc5a0886f797018b26aa42f40c09a82332bff77822a451deaaa/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b970c6da94d5bb18629db453d14f2a1300f6bf59b61e9b82377931ef95504866", size = 5246285, upload-time = "2026-06-12T20:01:32.439Z" }, + { url = "https://files.pythonhosted.org/packages/11/2d/5e1fb307cb5931881516b464c98774b3f2c36b5d4bb9a2830253cf553cad/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d8ecde755e2e91bf773fc94e8c9d730cd7f2007004cb492263a794ec3899a1c8", size = 4730441, upload-time = "2026-06-12T20:02:01.469Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c0/bff5a02ee731d207d6a1ed51732549d8c53d2bc8da1d10ec6f2844201d68/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e3fb64c420688e5319ae25113a354015abbd8dffbfbc41781a1ea66fc7622ac3", size = 4815869, upload-time = "2026-06-12T20:01:36.574Z" }, + { url = "https://files.pythonhosted.org/packages/b9/26/814681d14248d95d73d5c3eea0c39a94eb8302df966f670a2c60de90974b/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32703d93296f5c1f4b53349ad3a250c2cae0fdecd3a3dd5d47e616d8d616af27", size = 4960948, upload-time = "2026-06-12T20:02:18.688Z" }, + { url = "https://files.pythonhosted.org/packages/4c/fe/93ecac273d3738939d023612ad12cca9a3740a5345d69fda04134c43fd96/cryptography-49.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:33cd0565932807baddb67b96dbee92f2c374b5c89dee09fd74079aeb8c8dba61", size = 3799153, upload-time = "2026-06-12T20:01:39.059Z" }, + { url = "https://files.pythonhosted.org/packages/19/2a/5bb823f5bedcf80718cea7fbc95ec5515cca3769633c4b01a32be7f30e7c/cryptography-49.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ec5e529fb80935c94fe7b729f9972b50e351a0e6b50aa294fd5cabb109fcc29a", size = 4025947, upload-time = "2026-06-12T20:01:25.745Z" }, + { url = "https://files.pythonhosted.org/packages/3d/df/40577043ca124e17012f408ddddaeb213b856336ac82ddb3bc915f39e29f/cryptography-49.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f78ff2c9ed8dc2d036b0f4d640e22522213d047c1b14e61205a7e55c80a494d4", size = 4692429, upload-time = "2026-06-12T20:01:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/2c/99/2d13299eb3dd27b02dcfaafcc91d6b5cb3329f7cbd6d8f51921acd566c1a/cryptography-49.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:35b151772baff2c74cba7fa290ceaff4c3b11c0c881eb93eb5dbc05a7cfbba18", size = 4700968, upload-time = "2026-06-12T20:02:45.383Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4d/9c0cd02f95e2602dd5e563da149ee0830abef3537be8b34dc56281ebe27a/cryptography-49.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0f21641cf4b30fca7aee061ced0ec7ad7b073518088b7c9969a297c0ae796c69", size = 4697758, upload-time = "2026-06-12T20:01:41.13Z" }, + { url = "https://files.pythonhosted.org/packages/24/01/186c825898477d77e2324d5360fefe622ff1d8d1963ec0554e2cada8ec77/cryptography-49.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9e82dcc8e56052715fb18b2429e3bca4823b1629136a2084fc45a9a5cecb9b64", size = 5298863, upload-time = "2026-06-12T20:02:24.579Z" }, + { url = "https://files.pythonhosted.org/packages/b8/7b/62cbbab75d0659865bf0273790031544a0b16c8072d258f9428dcd8190dc/cryptography-49.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6f2debedf9ca60cf1d5bd466475638af5130f89965605cd818484d19987d3a21", size = 4735983, upload-time = "2026-06-12T20:01:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/6c/72/3e798c064bc39e471008075d0f9bc9daf77a80879c092e4a8e170c585ed4/cryptography-49.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:8c25ceb16df5b9435f3f6a9829204985b0e0cbee3b48aacd432c7d2c850b44d9", size = 4334173, upload-time = "2026-06-12T20:01:44.743Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ee/6fca21d1ac73e06f8bef71940abfd4d2f6472b4bca284d770f32bd4086f6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:28d8b15e6275f12c8a207dc309dfa957903c927d08d0cc937ee3f63f200693cc", size = 4697298, upload-time = "2026-06-12T20:02:20.918Z" }, + { url = "https://files.pythonhosted.org/packages/67/d0/a5fcd3515f0bae49a7b6d0413cc1bdccdcc1fc0047037a0d480642cdc5d6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6fc361c34fb6aac015ce19435876635e5c6d21db31998b0920f675f131e043b8", size = 5254338, upload-time = "2026-06-12T20:02:22.737Z" }, + { url = "https://files.pythonhosted.org/packages/a0/84/84fe36f19caf857d61cb7fc9c63035a47ffabd84ea12d1d393148efa3615/cryptography-49.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2400ef9c9e2299a25614eb1dea3db54a69b1349efd043bfac9c67630d136df36", size = 4735650, upload-time = "2026-06-12T20:02:41.389Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a0/db537264e234f7273a73ec020873d6d6b39dfd8a53db78b550ca8320440e/cryptography-49.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:67e1d20ad9ef3a563c59ef22e7a8a0b8210bd26604369ea4a30a7c66aefe504e", size = 4834820, upload-time = "2026-06-12T20:01:51.847Z" }, + { url = "https://files.pythonhosted.org/packages/93/77/8df9eb486495979bccecd1062e2eaf435250e84437040295b57d09048b0b/cryptography-49.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:42b0684e0e40cf26122427802486f6d93aea593612603a94fbf260c7eb1e9c1b", size = 4967968, upload-time = "2026-06-12T20:02:12.524Z" }, + { url = "https://files.pythonhosted.org/packages/c2/e6/f60198ea8d9dfa15fff9ed4ca02ce362f6eadd9ba757dcc50634c4257b63/cryptography-49.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:026ac7423e6fa66872d3bf889be5974507da3944f866f704fa200eadacd00001", size = 3785547, upload-time = "2026-06-12T20:02:26.847Z" }, + { url = "https://files.pythonhosted.org/packages/63/d3/4a83af35d65e3fad632c926fad684c193ea4398569ccb0bbbc7fe8f5dc9a/cryptography-49.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fc1e275c2f1d97b1a6450b8b0ea3ebfa6e087a611c2b26cb2404d48588abab7b", size = 3993685, upload-time = "2026-06-12T20:02:14.883Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a7/f9dac0ab7f80368c56993a7bf638ef9935f825c91902798481fac0898138/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83782480a4a9da4d0feb51950131ba32e12e70813848b3343f6e18c28a66838", size = 4676239, upload-time = "2026-06-12T20:02:28.793Z" }, + { url = "https://files.pythonhosted.org/packages/d7/70/2ba3769dd0ae167e2f33dfa9592d45db6ff9a61d62ca1a5b3d1bdd09068f/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b39efa323140595abd3ecca8529d321ae50f55f3aa3ba9cc81ea56a6011953d5", size = 4715584, upload-time = "2026-06-12T20:01:27.495Z" }, + { url = "https://files.pythonhosted.org/packages/94/64/2923570ac1c0bd3a737aa366ac3abbbbde273042308b8cde95e2364a6e6a/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:b47db11c2c3525083296069b98ac5221907455e989ae0c2e3008bde851921615", size = 4675885, upload-time = "2026-06-12T20:01:55.49Z" }, + { url = "https://files.pythonhosted.org/packages/ab/f8/614dc7e051418cfe53d55173c1e24c6b0085e89996fe90508c2fdf769aef/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:084ef1af862eb07ec46d25f68689f2102a9fc0e05ce7b80f14f5fe51e4eef0f6", size = 4715449, upload-time = "2026-06-12T20:02:05.469Z" }, + { url = "https://files.pythonhosted.org/packages/aa/50/a9caea39ad19c431c1a3f8a31114df65b260cdfe67786b6c7e7c040c4c44/cryptography-49.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be9fcb48a55f023493482827d4f459bd263cc20efde64f204b97c123201850c6", size = 3783731, upload-time = "2026-06-12T20:02:43.319Z" }, ] [[package]] @@ -904,14 +1006,14 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.49" +version = "3.1.53" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/63/210aaa302d6a0a78daa67c5c15bbac2cad361722841278b0209b6da20855/gitpython-3.1.49.tar.gz", hash = "sha256:42f9399c9eb33fc581014bedd76049dfbaf6375aa2a5754575966387280315e1", size = 219367, upload-time = "2026-04-29T00:31:20.478Z" } +sdist = { url = "https://files.pythonhosted.org/packages/17/24/0e0c12cb6f7cb864779a9d2fefee9ca91838f6db402c8780c9d28a8d7ebe/gitpython-3.1.53.tar.gz", hash = "sha256:06ae8d9623b0ed0d67b8adeac5c7008d0a5a404b087a9e0d0c7163bdd3a6b497", size = 224597, upload-time = "2026-07-20T13:41:52.839Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/6f/b842bfa6f21d6f87c57f9abf7194225e55279d96d869775e19e9f7236fc5/gitpython-3.1.49-py3-none-any.whl", hash = "sha256:024b0422d7f84d15cd794844e029ffebd4c5d42a7eb9b936b458697ef550a02c", size = 212190, upload-time = "2026-04-29T00:31:18.412Z" }, + { url = "https://files.pythonhosted.org/packages/cf/a6/bff12b3238885eeef7d28ef908b24e0cba91c476c31cb876a00a0986ce2c/gitpython-3.1.53-py3-none-any.whl", hash = "sha256:187885556b64ab357bd4ea84e2c4cce2861a613a7f4268b3f7f7ba05f2ce4ab0", size = 216237, upload-time = "2026-07-20T13:41:51.473Z" }, ] [[package]] @@ -928,11 +1030,11 @@ wheels = [ [[package]] name = "idna" -version = "3.13" +version = "3.18" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" }, + { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, ] [[package]] @@ -1023,7 +1125,8 @@ dependencies = [ { name = "attrs" }, { name = "jsonschema-specifications" }, { name = "referencing" }, - { name = "rpds-py" }, + { name = "rpds-py", version = "0.30.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "rpds-py", version = "2026.6.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } wheels = [ @@ -1044,89 +1147,89 @@ wheels = [ [[package]] name = "librt" -version = "0.12.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c6/e0/dbd0f2a68a1c1a1991eb7921ff6014465d56608cdc9a9fb468a616210a37/librt-0.12.0.tar.gz", hash = "sha256:cb26faedbd09c6130e9c1b64d8000efec5076ffd18d606c6cd1cf02730e6d8b0", size = 203841, upload-time = "2026-06-30T16:14:29.671Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/66/c9d88366893b4b0df6b5375c27ebc9f14c43419d9e244b493be20e85bc74/librt-0.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fe3547407bbce45c09885591f90168325c5a31a6795b9a13f6b9ff3d25093d93", size = 144398, upload-time = "2026-06-30T16:12:03.947Z" }, - { url = "https://files.pythonhosted.org/packages/bd/f2/9be1c6da204701163ec3aaedbf893d2f656b363d8fa302af536ce6471eb4/librt-0.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5925eca673207204a3adca040a91bdd3738fc7ba48da647ccd55732692a35736", size = 148924, upload-time = "2026-06-30T16:12:05.583Z" }, - { url = "https://files.pythonhosted.org/packages/d8/f3/256824ee27649c6e0a693db25d391f97b43b52364f8efb466014a564bbc7/librt-0.12.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f9ef097a7711465a204454c69658bbb6b2a6be9bdef0eeeba9a042016d00688", size = 479654, upload-time = "2026-06-30T16:12:07.175Z" }, - { url = "https://files.pythonhosted.org/packages/a8/3f/f4adbb3f293a04bd3dc2eb91d814f5b1e221e6b4522585696ba6901a0b9a/librt-0.12.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:57abc8b65edf1a8e80e5472c81c108a7527202e5febfda9e00a684dbaeae534e", size = 472318, upload-time = "2026-06-30T16:12:08.758Z" }, - { url = "https://files.pythonhosted.org/packages/9d/b5/362c93f7b43d4ef84a3d5f156c8d4eeddb22badcf5529a1281c387abbbd7/librt-0.12.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e6f53732a8ae5012a3b6ae092da2933be74ec4169d16038f4af87a0019afea", size = 501555, upload-time = "2026-06-30T16:12:10.623Z" }, - { url = "https://files.pythonhosted.org/packages/24/1d/2d6abf059c3a4b88a6668e7bb81af332b14463028ac8f2b08a1212eb1ebc/librt-0.12.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:edb5f06cdb38d6ef9fd7ae06d62962d65c881b5f965d5e8a6c53e59c15ae4338", size = 494118, upload-time = "2026-06-30T16:12:12.503Z" }, - { url = "https://files.pythonhosted.org/packages/39/c1/f91f3094be2c76361d88aca613d8b7586d15b6026714d59d2e3dc0e35f44/librt-0.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1473ef42263dfee7553a5c460f11730a4409acf0d52629b284eb1e6b13eb460a", size = 516318, upload-time = "2026-06-30T16:12:14.192Z" }, - { url = "https://files.pythonhosted.org/packages/8e/e2/5211af94252458cbed7a6250163dff9c5a84aec29609121c828375a3b319/librt-0.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1d6f69a06295fb6ad8dcf92b4b2d15d211842005e86eedce64d88e0633592f58", size = 522294, upload-time = "2026-06-30T16:12:15.879Z" }, - { url = "https://files.pythonhosted.org/packages/90/9b/de31f5b9fdf7fa3699c4bbbecf82ebd52013d5d6b500b70b07b0ebacbd51/librt-0.12.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:3275d0270cd07ca9c2e140ae4da34e24a0350e98c6e3815dce96ead67cf0487d", size = 502494, upload-time = "2026-06-30T16:12:17.394Z" }, - { url = "https://files.pythonhosted.org/packages/b1/48/22c18dff89f3900dddb3e470e6f7febcda37ff3667b73097a848c9a608b2/librt-0.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a4834462ec68613024d063c7efe9b188e350d40fda9ba937372039883d2a8051", size = 543422, upload-time = "2026-06-30T16:12:19.006Z" }, - { url = "https://files.pythonhosted.org/packages/52/7b/74691b4b55944227245fffef063714e3ab9707ab1111eb0068512b428c7c/librt-0.12.0-cp310-cp310-win32.whl", hash = "sha256:bcf9b55ac089e8cf201d2146833e1097812c15dcea61911e84d6a2904cf78893", size = 97642, upload-time = "2026-06-30T16:12:20.386Z" }, - { url = "https://files.pythonhosted.org/packages/c5/dc/7f8fa369a1f7cc9b090fecd373659ada0e9bab1ae4a3ac9f163eabd04977/librt-0.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:c0a122002f7e0d5c93e84465c4b3fe86621402b7b92f1e2bc0784ebe67793112", size = 117583, upload-time = "2026-06-30T16:12:21.829Z" }, - { url = "https://files.pythonhosted.org/packages/9e/ab/628490f42d1eba82f3c7e5821aa62013e6df7f525b7a9e92c048f8d1cc1c/librt-0.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f13c1e8563102c2b17581cf37fcb2c6dae7ad485ccea93ae46258998c25f9a1", size = 143821, upload-time = "2026-06-30T16:12:23.248Z" }, - { url = "https://files.pythonhosted.org/packages/38/5f/793e8b6f4b6ac16e7d7198478c0af3670606fbb535c768d5f3e954781423/librt-0.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d1ddff067610a122387024c4df527493b909d41e54a6e5b2d0e6c1041d6dfa09", size = 148442, upload-time = "2026-06-30T16:12:24.582Z" }, - { url = "https://files.pythonhosted.org/packages/ad/92/c780fe37a9e0982f3bd8fd9a631d6b95d09a5a7201c6c50366ce843b7e42/librt-0.12.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8dc7ebb5f3eec062398e9d0ef1938acd21b589e74286c4a8906d0183318d91b", size = 478276, upload-time = "2026-06-30T16:12:26.101Z" }, - { url = "https://files.pythonhosted.org/packages/41/bb/226d444bc20d7dff4a19ec6c1ff2c13a76385eebddb59c9c00c923b67536/librt-0.12.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:198de569ea9d5f6f33808f1c00cc3db9de62bf4d6deafa3b052bd08255083038", size = 472337, upload-time = "2026-06-30T16:12:27.83Z" }, - { url = "https://files.pythonhosted.org/packages/12/79/98ac0840ee90a75d4e1155c79062860b12ccca508587ff2119fc086965f2/librt-0.12.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e958678a8bca56016aedc891b391c0e0813ea382a874b54a2c1b313c1d232720", size = 502087, upload-time = "2026-06-30T16:12:29.443Z" }, - { url = "https://files.pythonhosted.org/packages/6f/72/a6b1a0d080606a7f5f646b79a1496f21d709f8563877759ace9ce5adad73/librt-0.12.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575a6eca68c8437ed4a8e0f534e31d74b562ba1049a0ee4b5f09e114bcc21be1", size = 493202, upload-time = "2026-06-30T16:12:31.077Z" }, - { url = "https://files.pythonhosted.org/packages/69/cf/e1b036b45f2fc272205ee18bf272b47e8d684bf1a75af26db440c7504359/librt-0.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:86f241c50dc9e9a3f0db6dbb37a607c8205aa87b920802dabbd50b70d40f6939", size = 514139, upload-time = "2026-06-30T16:12:33.032Z" }, - { url = "https://files.pythonhosted.org/packages/40/34/b193b3e6985469a2f8afa86c90012329c86480b6ff4f2e4bd7b5b937e134/librt-0.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:113417b934fbf38220a9c7fe94578cefbe7dbb047adcb75aa197905af2b13724", size = 519486, upload-time = "2026-06-30T16:12:34.996Z" }, - { url = "https://files.pythonhosted.org/packages/31/9e/7de4947b1695f247c813f833e3c1e7b77b52e52a7dba2c35411cf806b58e/librt-0.12.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:762f17c0eb6b5d74e269126996cea8a89e35ab6464c5151619163abcd8623ae2", size = 499609, upload-time = "2026-06-30T16:12:36.663Z" }, - { url = "https://files.pythonhosted.org/packages/59/11/f3730e04e758b1fbf215359062ad2d5b6bd0b0ab5ac46b1c140628795be7/librt-0.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6aa93b3bd7f7588c628f6e9bf66485d3467fd9a1ccdb8975b770178f39f35697", size = 542205, upload-time = "2026-06-30T16:12:38.56Z" }, - { url = "https://files.pythonhosted.org/packages/1f/8f/710453617eabe20e18433864f335534c8aff63fbc68d8cd9dbc70a3d08f6/librt-0.12.0-cp311-cp311-win32.whl", hash = "sha256:aaa04b44d4fe86d824616b1f9c13e34c7c01ec0c96dd2abc4f59423696f788e2", size = 98067, upload-time = "2026-06-30T16:12:40.102Z" }, - { url = "https://files.pythonhosted.org/packages/42/53/401bff50a56e95daf151d911c99adf5732af2190e8f4d11886c9a229103c/librt-0.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:9aaeeddb8e7e4ae3bb9f944e0e618418cb91c0071d5ddbfcc3584b3cf59d39f0", size = 118346, upload-time = "2026-06-30T16:12:41.388Z" }, - { url = "https://files.pythonhosted.org/packages/e5/9a/a3a9078fe88bfc2d2d99dcf1c18593938ae830089cf84c3b2532a6c49d63/librt-0.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:18a2402fa3123ab76ecca670e6fb33038fde7c1e91181b885226ec4d30af2c2c", size = 104760, upload-time = "2026-06-30T16:12:43.112Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1a/5bec493821b0e85b91de4f234912b50133d1aedb875048eef27938ec3f96/librt-0.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9bce19aa7c05f91c989f9da7b567f81d21d57a2e6501e2b811aa0f3f79614c1a", size = 146756, upload-time = "2026-06-30T16:12:44.395Z" }, - { url = "https://files.pythonhosted.org/packages/b9/d0/cc04b48a57c1f275387f5578847214c4a6c21bfb24c6c8c8d6ba753fe403/librt-0.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0ace09f5bf4d982fe726015f102fb856658b41580597104e301e630ed1d8d86", size = 145537, upload-time = "2026-06-30T16:12:45.95Z" }, - { url = "https://files.pythonhosted.org/packages/9e/10/c02325556beb2aa158c9e549ddade8cc9a23b36cdad14756dbed730c1ff1/librt-0.12.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d007efe9243ede81ce75990ad7aa172da1e2024144b3eff17ba46a5fff1fff3c", size = 488637, upload-time = "2026-06-30T16:12:47.658Z" }, - { url = "https://files.pythonhosted.org/packages/cb/9e/7b49ca1c30baa9c8df96024aa09a97c35a97455e36004c9b5311703c56f3/librt-0.12.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:ad324a5e4858388a4864915b90a42efc8b374376393f14b9940f2454e791912b", size = 483651, upload-time = "2026-06-30T16:12:49.283Z" }, - { url = "https://files.pythonhosted.org/packages/4d/71/03c8c8cec39645fda451132ff9d6d662fc5aea42a1a188a77a4fddb35906/librt-0.12.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10a40cf74cdd97b6f8f905056db73f5d459783de2ca04c6ebd1bf47652818e7e", size = 518359, upload-time = "2026-06-30T16:12:50.999Z" }, - { url = "https://files.pythonhosted.org/packages/e0/ec/a9f357f94bbcba92277d22af22cff42ef706ae5d9d6d58b69bebf3a67954/librt-0.12.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:92e61c09de95217ae02a9d17f4f66cf073253cdc51bcfdc0f15c62c9a70baa85", size = 509510, upload-time = "2026-06-30T16:12:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/7a/34/717055325d028743aa01a7691ad59a63352a26a8ff2e7eeb0c9249514150/librt-0.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0461344061d6fc3718940f5855d95647831cef6d03a6c7506897f98222784ad4", size = 527302, upload-time = "2026-06-30T16:12:54.244Z" }, - { url = "https://files.pythonhosted.org/packages/95/f8/7612eeedb3395d92f7c6a84dca5f15e282d650483a4dc01aa5b9cffdfda3/librt-0.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e6dfe89074732c9287b3c0f5a6af575c9ede380a788013876cc7b14fe0da0361", size = 532568, upload-time = "2026-06-30T16:12:55.74Z" }, - { url = "https://files.pythonhosted.org/packages/79/1e/a9afe85d5bb8b65dc27be3809ed1d69082079e1e9717fd2c66aa9939600c/librt-0.12.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9efed79d51ad1383bba0855f613cca7aa91c943e709af2413ac7f4bb9936ce08", size = 521579, upload-time = "2026-06-30T16:12:57.884Z" }, - { url = "https://files.pythonhosted.org/packages/b3/1e/93aebb219d52c37ea578f83b0588cd7b040974e464d4e435086a48b4dc4d/librt-0.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1eac6cc0e23e448fb3c1446ed85ff796afb616eed5897c978d35dbec030b7c7c", size = 558743, upload-time = "2026-06-30T16:12:59.577Z" }, - { url = "https://files.pythonhosted.org/packages/3c/85/1680c0ec332f238e3145c5608d313ab0a43281e210a5dd87e3bc3cc25631/librt-0.12.0-cp312-cp312-win32.whl", hash = "sha256:0ab8ee0210047ae86ca023ccfbfe3df82077fd1c9bc021aebbf37d993ef64af0", size = 99200, upload-time = "2026-06-30T16:13:01.015Z" }, - { url = "https://files.pythonhosted.org/packages/30/0e/abca12d8904875aa2ad66327390a3f7b1b75ebc43c0a00fc763cecf32ea5/librt-0.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:51c8bfa12632c81b94401c101bcedd0c56c3a1f8fa3273ca3472b28cd2f54003", size = 119390, upload-time = "2026-06-30T16:13:02.493Z" }, - { url = "https://files.pythonhosted.org/packages/32/a5/4203481b6d3a3bb348c82ac71abf1fcb4cb3ae8422a24a8dee4cd3ac5bd7/librt-0.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:5eebd451f5def089369ba6d8ff0291303d035e8154f9f26f7633835c5b029ade", size = 105117, upload-time = "2026-06-30T16:13:03.952Z" }, - { url = "https://files.pythonhosted.org/packages/f2/87/568d948c8079c9ff3c9e8110cf85f1eb70218e1209af29d0b7b89aa4a60c/librt-0.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8d9a55760a34ae5ce70434aabb6a6c61c6c44a0ec58ca1cfd9cd86e4745d417d", size = 146808, upload-time = "2026-06-30T16:13:05.417Z" }, - { url = "https://files.pythonhosted.org/packages/e7/1d/bea471ecea210088847bb5f3c4b4b424d596518934c06679b78ca85d6e63/librt-0.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ff0b197e338b4cf432873e0d6ef025213fdea85311ec4d87d2ea88c28adf2409", size = 145503, upload-time = "2026-06-30T16:13:07.023Z" }, - { url = "https://files.pythonhosted.org/packages/eb/9e/984ad422b56de95fdce158f06b051655373784ebea0aba9a7fcbc41614d1/librt-0.12.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e69f120a20b69e2539d603bbd4d62db38399b10f8bf73a1cf445038a621e8af", size = 488421, upload-time = "2026-06-30T16:13:08.492Z" }, - { url = "https://files.pythonhosted.org/packages/50/03/1a2f94009b07ea71f8e1a4cfe53370565b56da9caa341b89e0699325e9f5/librt-0.12.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:fde3cde595e947fc8e755b0a21f919a1622483d07c662d00496e040773d22591", size = 483488, upload-time = "2026-06-30T16:13:10.169Z" }, - { url = "https://files.pythonhosted.org/packages/aa/3b/084bdc295823fbb6ab91670047adf8f420787f9e8794bf2d140b66dc196b/librt-0.12.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d977447315fa09ea4e8c7ae9b4e22f7659b5128161c1fd55ff786b5349f73503", size = 518428, upload-time = "2026-06-30T16:13:11.681Z" }, - { url = "https://files.pythonhosted.org/packages/c9/22/5a307390b93a115ffbecd95c64eecb4e56269680e45e9415ada7285f2cf4/librt-0.12.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ffac8a67e4143cea9a549d4822b93bc0bbaad73fc25aa0ab0ba5ec27d178677", size = 509744, upload-time = "2026-06-30T16:13:13.217Z" }, - { url = "https://files.pythonhosted.org/packages/b5/90/83f3cb6184f5d669660717b4b2e317c9ddaccf7ca5bb97f2196deac1a3b7/librt-0.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:94af1ed773ff104ef08ef3d669a0ba9d3a5916c609eb698cffe5d5476d66ff9b", size = 527749, upload-time = "2026-06-30T16:13:15.277Z" }, - { url = "https://files.pythonhosted.org/packages/7d/3b/f162be5cc88d47378e3a20776fe425fa1c2bece755da15e2783ebf06d3d6/librt-0.12.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:548199d21d22fb26398dfbbe0ba953a52465c66f3a49f38e6fddce1b127faf53", size = 532582, upload-time = "2026-06-30T16:13:17.074Z" }, - { url = "https://files.pythonhosted.org/packages/c9/28/6c5d2f6b7232fd24f284fc4cab37a459fe69a9096a09942f44cc5c55e073/librt-0.12.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c8f1f413b966a9dd3ecf80cd337b0ad7bb3de2474a4ff448ed3ebabfc3f803fc", size = 522235, upload-time = "2026-06-30T16:13:18.823Z" }, - { url = "https://files.pythonhosted.org/packages/a9/1c/bd115360587fdc22c8ae8fac14c040a556b442e2965d4370d2cf274c8b95/librt-0.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:55f13f95b629be5b6ab38918e439bf14169d6f9a8deaae55e0c14e12fb0c74b9", size = 559055, upload-time = "2026-06-30T16:13:20.509Z" }, - { url = "https://files.pythonhosted.org/packages/fe/5a/c26f49f576437014825a86faea3cec60c1ed17f976abd567b6c12b8e35a7/librt-0.12.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:8b2dc079dfe29e77a47a19073d2040fa4879aa3656501f1650f8402ddce0313c", size = 79809, upload-time = "2026-06-30T16:13:22.401Z" }, - { url = "https://files.pythonhosted.org/packages/69/0b/a55244261d9ad7375ac039b8af06d42602722e2e8b8d8d6b86e4a3888c02/librt-0.12.0-cp313-cp313-win32.whl", hash = "sha256:da58944be8270f2bfee628a9a2a60c1cf6a12c8bea8e2c9b6edf3e5414ca7793", size = 99308, upload-time = "2026-06-30T16:13:23.661Z" }, - { url = "https://files.pythonhosted.org/packages/c9/bf/ed9465e58d44c5a5637795547d0841c8934aab905ea452cac1adf14672cf/librt-0.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:1db4be3037e4ce065a071fa7deee93e78ebc25f448340a02a6c1c0b82c37e383", size = 119438, upload-time = "2026-06-30T16:13:25.188Z" }, - { url = "https://files.pythonhosted.org/packages/c0/44/3cad652aeb892e6e8ffe48d0fafa2bc652f28ec7ed3f4403fcbb1be4f948/librt-0.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:05fd2542892ad770b5dd45003fd080477cf220b611d3ee59b0792097eb0873a9", size = 105118, upload-time = "2026-06-30T16:13:26.533Z" }, - { url = "https://files.pythonhosted.org/packages/0e/51/3a0e05618c12423b6fc5141b590ec02a6efb645833edc8736a6c7b46d1ec/librt-0.12.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:b37ee42e09722284a6d9288fe44a191f7276060a3195939bb77c6502058dbb34", size = 145579, upload-time = "2026-06-30T16:13:27.909Z" }, - { url = "https://files.pythonhosted.org/packages/77/9e/fd399d099dfb4020f3f7c34e7e6210c389fa89f7d79ca92f5afb0395f278/librt-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ade11988728b3e4768dadc5696e82c60e9b35fc95335a9b4d1f5d69e753ccec7", size = 150139, upload-time = "2026-06-30T16:13:29.357Z" }, - { url = "https://files.pythonhosted.org/packages/7a/ee/610239fbd8c4b005443664c5d4c3bc1717daedd8c71369bf45011aa87194/librt-0.12.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f351ed425380e39bd86df382578aa5b8c5b98e2e265112de7379e7d030258150", size = 480457, upload-time = "2026-06-30T16:13:30.78Z" }, - { url = "https://files.pythonhosted.org/packages/0c/10/ceddc9010f26c541444be36e1153a79b64626694db2d33a524c719fa3e46/librt-0.12.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:857d2163e088c868967717ace8e980017fd868a735f3de010412af02bdc30319", size = 479002, upload-time = "2026-06-30T16:13:32.398Z" }, - { url = "https://files.pythonhosted.org/packages/4e/f1/b1523d9718e8192e5403e6b41a02742e17ba554369f0729b9f30ab590e2d/librt-0.12.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2befc80aa5f2f5b93f28abaaf11feff6677931dd548320e44c52deaa9399744", size = 510527, upload-time = "2026-06-30T16:13:34.615Z" }, - { url = "https://files.pythonhosted.org/packages/f6/0e/0f3ff43befb18a531615736791e52fb67eaa71ff7b89e6e5f7004b64cc6e/librt-0.12.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:be3694dcfa97c6715dd19ac73d3e1b21a805514a5785663e57fecacd3ff64e5a", size = 500988, upload-time = "2026-06-30T16:13:36.408Z" }, - { url = "https://files.pythonhosted.org/packages/a8/1a/0278ea4a9e599dc507c43839a87f2c764ad04bf69418e2d763d58659e55f/librt-0.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2d5f67e86f45638843d025b0828f2e9e55fc45ff9180d2618ccdeaf72a796050", size = 519318, upload-time = "2026-06-30T16:13:37.883Z" }, - { url = "https://files.pythonhosted.org/packages/59/55/090e10e62be2f35265e41601337f83ac9f83be9aca1bf92692e3a82effdd/librt-0.12.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:64572c85e4ab7d572c9b72cd76b5f90b21181b1459fa6b1aac6f8958c4fcff31", size = 527127, upload-time = "2026-06-30T16:13:39.682Z" }, - { url = "https://files.pythonhosted.org/packages/1f/34/8052c9ec678be6ba751279947831f089aa69b009000b985ce91d1979669a/librt-0.12.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:8b961912b0e688c1eb4658a46bdb0606b31918d65597fbe7356ca83aa653ffcc", size = 509766, upload-time = "2026-06-30T16:13:41.266Z" }, - { url = "https://files.pythonhosted.org/packages/6f/f8/8761b36189e9ec8dc20b49fa84cef22852c6c41fcda56f760f7fc1360da5/librt-0.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:722375903e3f079436a7a33da51ce73931536dd041f9feb01536f05d8e010c96", size = 552043, upload-time = "2026-06-30T16:13:43.197Z" }, - { url = "https://files.pythonhosted.org/packages/c8/98/7283971ef6b70269938b49c7b25f670ec6325d252265fbcc996f9b364379/librt-0.12.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:a5a96a8f536b65ef1bf910c09e7e71647edde5111f6e1b51f413c6fba5bfe71b", size = 79472, upload-time = "2026-06-30T16:13:44.64Z" }, - { url = "https://files.pythonhosted.org/packages/c3/5e/b30940dea935e8ac5bd0e0abb1985f5274590d557ac3a252ca0d5392ce52/librt-0.12.0-cp314-cp314-win32.whl", hash = "sha256:8ffc99c356f1777c506e1b69dc303879153ae2640ba15b8f3d4448bc87139149", size = 94246, upload-time = "2026-06-30T16:13:45.962Z" }, - { url = "https://files.pythonhosted.org/packages/7d/4e/0af9fe63f35fa304da3b05688f30ff6a329bcc59581b1cc51dc87fd30141/librt-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:1e68fb20798f455cda41d20a306a23c901218883f17a4bab1ed6e1331b265fb7", size = 114951, upload-time = "2026-06-30T16:13:47.279Z" }, - { url = "https://files.pythonhosted.org/packages/b1/8e/843c495d7db35e13b84cd533898fa89145c40dc255da0bc316d53d631464/librt-0.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:2df534f97916cf38ec9b1ddafeb68ae1a4cd4a54775ff26a797026774c0517cf", size = 100562, upload-time = "2026-06-30T16:13:48.699Z" }, - { url = "https://files.pythonhosted.org/packages/75/30/c686d0f978d5fd6867c5bbad96b015c9445746764d1c228e16a2d30d9382/librt-0.12.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:c09e581b1c2b8a62b809d4f4bd101ca3de93791e5b0ed1a14085d911be3dee3f", size = 153897, upload-time = "2026-06-30T16:13:50.017Z" }, - { url = "https://files.pythonhosted.org/packages/40/46/f6f2d77ce46628b48fb5280709013b5109cf3a2c46a2472093cdfc03519d/librt-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:976888d0d831402086e641018bcc3208e0a38f0835789da91f72894b2cb4161f", size = 156391, upload-time = "2026-06-30T16:13:51.462Z" }, - { url = "https://files.pythonhosted.org/packages/c2/46/cd790c7e19e460779471530ffab454541d6ea4a3b7d338cad7f16ff96995/librt-0.12.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:563c37cdb41d08fe1e3f08b201abac0e317ca18e88b91285466ee0a585797520", size = 564151, upload-time = "2026-06-30T16:13:53.146Z" }, - { url = "https://files.pythonhosted.org/packages/54/12/724559a15fb023cbdef7aee1e81fbfbc3ee22fd09009baa816cea63e3a60/librt-0.12.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b97eb1a3140e279cc76f85b0fb92b7eb3dfbe0471260ee878bc9dc4bf9a0d649", size = 546002, upload-time = "2026-06-30T16:13:54.665Z" }, - { url = "https://files.pythonhosted.org/packages/4b/7e/f9d8c257ab4909f101c7c13734367749e782fd8625545f0343502c2f09f1/librt-0.12.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:06e0623351ab9904cf628245f99c714586f4dd23dc740b88c8bc670d8401a847", size = 584204, upload-time = "2026-06-30T16:13:56.301Z" }, - { url = "https://files.pythonhosted.org/packages/9b/33/64665810575ac23b6cb6ef364de51309b7803620c12885b6e895ebc29591/librt-0.12.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:da12f017b2e404554be14d466cd992459feaa44f252b0f18d909a85266ce1237", size = 573688, upload-time = "2026-06-30T16:13:58.1Z" }, - { url = "https://files.pythonhosted.org/packages/0f/01/27522995c6627455abc7a939d57535fb1a7836d398ccedb3d7585f46039e/librt-0.12.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d97f31003a5c86b9e78155a829572c3a26484064fb7ac1d9695fe628bd93d029", size = 604719, upload-time = "2026-06-30T16:13:59.831Z" }, - { url = "https://files.pythonhosted.org/packages/ee/1f/099e61b1b688551d6d2ce9d4d2ae2242a938759db8551e6cbac7f7176ee5/librt-0.12.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:bd43a6c69876aef4f04eaae3d3b99b0be64755fda274002fa445b92480bf664e", size = 598183, upload-time = "2026-06-30T16:14:01.457Z" }, - { url = "https://files.pythonhosted.org/packages/bf/c1/050400249665503bdd5b83cec518fa7b183b609341c8dcd58161775c4226/librt-0.12.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c01755c72fca1dc6b8d5c2ed228b8e7b2ffe184675c22f0f05ebd8fe188b9250", size = 582559, upload-time = "2026-06-30T16:14:03.29Z" }, - { url = "https://files.pythonhosted.org/packages/da/d1/eef8f0e6722518b65a3d3bcd9309f9f44e208ce5d6728070820f988e7078/librt-0.12.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:625ae561d5fa36400856dcc27464400d047bc2d5e3446be88f437b03fefd72e4", size = 626375, upload-time = "2026-06-30T16:14:04.957Z" }, - { url = "https://files.pythonhosted.org/packages/8b/78/f0bb41a6f2bbd3c77bdcc66980dc0d69ca1192a0ecec25377afcc5e6db73/librt-0.12.0-cp314-cp314t-win32.whl", hash = "sha256:8d73191883553ee0739741544bf3b00aba2a1224e45d9580b30cbc29e21dc03b", size = 97752, upload-time = "2026-06-30T16:14:06.555Z" }, - { url = "https://files.pythonhosted.org/packages/92/24/e279c27972ab051a070237cfa45728fa51670c3f22f1a4d391711e9f4c31/librt-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e1cbb037324e759f0afa270229731ff0047772667f3cb38ef5df2cabf0175ede", size = 119562, upload-time = "2026-06-30T16:14:07.908Z" }, - { url = "https://files.pythonhosted.org/packages/06/e6/42a475bfca683b0cd5366f6dd06580062b7e567bb8534d225c877c2f14f3/librt-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:bca1472acbd473eff61059b4409f802c5a1bcb4cd0344d06f939df9c4c125d40", size = 104282, upload-time = "2026-06-30T16:14:09.29Z" }, +version = "0.13.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/2f/3908645ddddab7120b46295e541ead308109fa48dbec7d67d7a778870d60/librt-0.13.0.tar.gz", hash = "sha256:1d2a610c14ac0d0750ee0a3ab8548e83155258387891caaca04def4bf7289781", size = 211402, upload-time = "2026-07-08T12:26:29.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/2f/ec5241c38e7fa0fe6c26bfc450e78b9489a6c3c08b394b85d2c10e506975/librt-0.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:34e47058fcc69a313293d6dee94216a4f30c929ae6f2476e58c5ba635aa639d5", size = 148654, upload-time = "2026-07-08T12:24:30.622Z" }, + { url = "https://files.pythonhosted.org/packages/a5/1a/d651e18d3ee7aa2879322368c4f278bb7ecaa6b90caadfdec4ebfa8389f3/librt-0.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dbdd5b6509d0c2a8fe72cf494c299a61dbd58142a90a4190664ae159e4a7b547", size = 153537, upload-time = "2026-07-08T12:24:31.773Z" }, + { url = "https://files.pythonhosted.org/packages/45/18/10bff2122577246009d9619b6569596daf69b7648812f997ca9ca0426f60/librt-0.13.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e56ea4ee4df77585a6b5c138f6538680886024fa559f5b55bd14b12e98e67b2", size = 494336, upload-time = "2026-07-08T12:24:33.079Z" }, + { url = "https://files.pythonhosted.org/packages/67/69/87dfee871b852970f137fdeae8e2ca356c5ab38e6f21d2a3299535fc3159/librt-0.13.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f1f9cc4d09a46d9cb3c2063ae100629d3f52a6517c3c08c2f4c9828261883929", size = 485393, upload-time = "2026-07-08T12:24:34.324Z" }, + { url = "https://files.pythonhosted.org/packages/e9/d5/625447a8c0441ff5f15f4ac5e1d323fb9d4d256ebfde7a3c8e003f646057/librt-0.13.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f125f5d46b20f89dc5587a55cc416b4ba2a5b2ffda36d048ee120e17598a653a", size = 515382, upload-time = "2026-07-08T12:24:35.575Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d8/1c8c49ea04235960426444deece9092a6b3a9587a850a81bae2335317411/librt-0.13.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2608d3b39f9e0b4a66a130d9150c615cba40a5090d25eeeaa225e0e46de8c0ac", size = 509483, upload-time = "2026-07-08T12:24:36.923Z" }, + { url = "https://files.pythonhosted.org/packages/6f/65/f1760fc48050e215201a03506c32b7270159088d01f64557b53e39e74a45/librt-0.13.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9fd35e95ab5e45c3901d37110263c7db85a961110f5460588fe37f8c131f88a7", size = 532503, upload-time = "2026-07-08T12:24:38.203Z" }, + { url = "https://files.pythonhosted.org/packages/18/1b/793e281dcf494879eff99f642b63ebc9c7c58694a1c2d1e93362a22c7041/librt-0.13.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5f31b0aa13c9b04370d4da6be1ab7779776b3a075cceb6747a39a4be85fe1e40", size = 537027, upload-time = "2026-07-08T12:24:39.34Z" }, + { url = "https://files.pythonhosted.org/packages/69/45/0801bbb40c9eea795d3dd3ce91c4c5f3fe7d42d23ec4be3e8cb283bcc754/librt-0.13.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0b795f5fc70fbbb787ceaf79bb3a0d627bcc33c53de51741755263ec406b775a", size = 517100, upload-time = "2026-07-08T12:24:40.907Z" }, + { url = "https://files.pythonhosted.org/packages/a1/6c/eb5f514f8e29d4924bc0ff4601dd7b4175557e182e7c0721e84cffa39b8a/librt-0.13.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36b306a623aaad96fe4b378692b54f9c0789fccd833b9851753d5fbf6138cfde", size = 558653, upload-time = "2026-07-08T12:24:42.359Z" }, + { url = "https://files.pythonhosted.org/packages/b4/bf/f140100d1b59fe87ff40b5ecbb4e27924335b189a784e230ee465452f6c2/librt-0.13.0-cp310-cp310-win32.whl", hash = "sha256:a3762e75fcac8c9e4dacaaf438bffd9003e2ca2c531b756f3c0035deefa674c8", size = 104402, upload-time = "2026-07-08T12:24:43.668Z" }, + { url = "https://files.pythonhosted.org/packages/22/7c/57e40fef7cfb61869341cb28bdcefe8a950bebcbecca74a397bae14dce4a/librt-0.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:d63bae12a8aeb51380be3438e4dc4bd27354d0f8e19166b2f44e3e94d6f552dc", size = 125002, upload-time = "2026-07-08T12:24:44.793Z" }, + { url = "https://files.pythonhosted.org/packages/89/25/a6498964cfeec270c468cffdc118f69c29b412593610d55fa1327ca51ff4/librt-0.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1b5a7bbff495baedbd9b916c367d66854008f8f3b575908ded477c499dc60082", size = 148029, upload-time = "2026-07-08T12:24:45.961Z" }, + { url = "https://files.pythonhosted.org/packages/78/59/dc86d1bffd8e0c2818bace29d9f7783cfbb8e0673bf3673b5bbd5bbe0420/librt-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34bc7938b9fdf14fe32a406c19c71faf894c5cee7e7474bd0be2f17200b82d14", size = 153036, upload-time = "2026-07-08T12:24:47.257Z" }, + { url = "https://files.pythonhosted.org/packages/29/3f/b923826660f02f286186cd9303d52bb05ced0a13708edc104dc8480920e3/librt-0.13.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f40e56b61b41be5f7dec938cfeffd660668cf4b5e72c78e7bd671d66b7bc2c79", size = 493062, upload-time = "2026-07-08T12:24:48.483Z" }, + { url = "https://files.pythonhosted.org/packages/88/87/6c0980a9c9b1302cb68d108906697b89eceb55889bb1dcf77c109aa56ca5/librt-0.13.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:9c5d02b89de5acd0379a51ec44a89476fb03df6145442e1c8ecd6bee2f91b176", size = 485510, upload-time = "2026-07-08T12:24:49.727Z" }, + { url = "https://files.pythonhosted.org/packages/32/81/795ae3b9df5dd94079fb807e38191855e023e8c6249014ae6bc3f0d9a490/librt-0.13.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7db9a3ff32ef5f7d1703d93831a3316cdf0b537de6a1cc03cc8fdd09b9194e89", size = 515909, upload-time = "2026-07-08T12:24:51.135Z" }, + { url = "https://files.pythonhosted.org/packages/20/e5/182de15abce8907108a6fdb41487de65beb5099b74dc5841b19b099168db/librt-0.13.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3dbb2a31882456cadc7053378e81ad7ed7693db4ac9f98ab5f81ef034aa8ec9f", size = 508620, upload-time = "2026-07-08T12:24:52.358Z" }, + { url = "https://files.pythonhosted.org/packages/32/03/33978d32db76e1f66377e8f78e42a2ca3c162143331677d1f50bbad36cfb/librt-0.13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c6014e3c80f9c1fe268ef8b0e0ef113bac672cc032f2f93866e7ddad4f3e663d", size = 530363, upload-time = "2026-07-08T12:24:53.503Z" }, + { url = "https://files.pythonhosted.org/packages/e6/f5/b291fbd2d00f7d8287bcbf67b5aa0c6afed4bc26cef23e079629c47a2c04/librt-0.13.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:091b60a4d2174fc1ec5c34cdc0b72efb6224753d76b7da61ebeab7a191aec8bd", size = 534209, upload-time = "2026-07-08T12:24:55.138Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/6f41f17939d191bc21609f220da8509316bc62797f078545fe83be522e78/librt-0.13.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:66cb1138f384a191a6d75f986064841fcfdc0cea98f7bd9c9ab9b38049917588", size = 514254, upload-time = "2026-07-08T12:24:56.276Z" }, + { url = "https://files.pythonhosted.org/packages/af/c2/2e4befa5410a7443019c14abccc94ff619797171f6b72013635fb87f31d7/librt-0.13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:17221a7569f8f292aa0014226e48aa25b8c2b08da18088cd230953d0ea0f9cd1", size = 557611, upload-time = "2026-07-08T12:24:57.561Z" }, + { url = "https://files.pythonhosted.org/packages/ab/54/8b69f81448417adbc040a2185f4e2eece1e1994b7dcfaeed4662b30f98a5/librt-0.13.0-cp311-cp311-win32.whl", hash = "sha256:fc67741da44c6eaa90e01eafb586bbba9b51eb5b6ed381ee6f5ae72eb3316d21", size = 104906, upload-time = "2026-07-08T12:24:58.806Z" }, + { url = "https://files.pythonhosted.org/packages/76/5a/f4aaf37b50f2fde12c8c663b83fdd499cdc24f957f19543d7414bfcc9e25/librt-0.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:cc99dfb62b23c9207c33d0be8a2e2af7a42e21e6ea388b380a0c948c7b88953b", size = 125852, upload-time = "2026-07-08T12:25:00.065Z" }, + { url = "https://files.pythonhosted.org/packages/f2/99/bf1820e6feeabc2f218c24450ec0c995d6a91e8ba0fd3caf042c9e8adb2a/librt-0.13.0-cp311-cp311-win_arm64.whl", hash = "sha256:40ccd13c252d3fe473ffc8a57be7565abc8b64cf1b108344c859d5164f7f3e0c", size = 111832, upload-time = "2026-07-08T12:25:01.148Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/b2933ddae222dac338476abb872641169a5cfed2c2bb5444a5b07b32b0c3/librt-0.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30536798f4504c0fad0885b1d371b0539abb081e4570c9d7c641cb51141b49f0", size = 150990, upload-time = "2026-07-08T12:25:02.42Z" }, + { url = "https://files.pythonhosted.org/packages/90/ef/db98f744ca50e6efc9c95c70ee49b77aefac31f6a3fc7c83754a42d6a74f/librt-0.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:93d24ebb82aa4420b1409c389e7857bc35bd0b668007ac8172427d5c73cc8cc5", size = 155238, upload-time = "2026-07-08T12:25:03.681Z" }, + { url = "https://files.pythonhosted.org/packages/03/e7/a197e7bc72baf2c61ce7fdc6906a5054dc05bd8da0819aa894e4857bf87e/librt-0.13.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cb8a1adce42d8b75485a5d56a9623a50bcab995b6079f1dac59fc44034dd93d9", size = 503073, upload-time = "2026-07-08T12:25:05.049Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e7/7887712e27da7c1ab80fcabb1de6eb24243964f6557cae530d4b70706dbd/librt-0.13.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0763ca2ab66058174f9dee426dc64f5e0a89c24a7df8d3fe3f1836c04e25de4b", size = 496528, upload-time = "2026-07-08T12:25:06.26Z" }, + { url = "https://files.pythonhosted.org/packages/94/f0/f2283385bb6b950b26a1410f4ce51ec27231e0b3a4b925c46366d218b198/librt-0.13.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b222493da6e7b6199db9bd79502436cf5a27da3c1f7fa83c7e285444fc93fd03", size = 531786, upload-time = "2026-07-08T12:25:07.658Z" }, + { url = "https://files.pythonhosted.org/packages/36/11/69ac3b54766ffba5fd7e5acebfb048d66dbe1f9f2d14516c2b3edc59cf87/librt-0.13.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fadc63331f4388c3dc90090448f682a7e9feafc11481391c1e94f2f907a3976e", size = 524393, upload-time = "2026-07-08T12:25:09.121Z" }, + { url = "https://files.pythonhosted.org/packages/61/5f/d72f95fd444a926a3c14b4e24979474116988dd57a45be242077c45d3c22/librt-0.13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:70d9c62a4cffd9f23396cd5ef93fc5d11b31596b9b7d6306074abe3d5fcf09bd", size = 543026, upload-time = "2026-07-08T12:25:10.459Z" }, + { url = "https://files.pythonhosted.org/packages/c4/08/dcd9993ad192737a004ba263d549f8ea605b326b952e7d6205c7d4170b76/librt-0.13.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:66c0e7e6b02a155576df2c77ec933a70b72da726e248c494abf690923e624348", size = 546829, upload-time = "2026-07-08T12:25:11.716Z" }, + { url = "https://files.pythonhosted.org/packages/96/d5/6d9bb2f54e4109a956b7128836529653eb9d740f784bc47ed10a02c1000e/librt-0.13.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ac04bcd3328eb91d99dfedf6a60d9c1f15d3434e6f6daf922f0420f7d90b85c7", size = 535700, upload-time = "2026-07-08T12:25:13.144Z" }, + { url = "https://files.pythonhosted.org/packages/8c/f2/10946922503858a359492fa27f13e86228bde702116a740ac7b3cd185f24/librt-0.13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db327e7271e653c32040b85ae6188059c924b57d7e1e29f935523fa017cd4e82", size = 573566, upload-time = "2026-07-08T12:25:14.336Z" }, + { url = "https://files.pythonhosted.org/packages/48/a8/94f00e3c99479a18088af3685ea016c42f3c7d5d1964d8dbb40c08d7f1aa/librt-0.13.0-cp312-cp312-win32.whl", hash = "sha256:860bd1d8ba48456ce08feaf8d343a8aaeb2fa086f2bcaa2a923fa3f7a3ff9aa3", size = 106099, upload-time = "2026-07-08T12:25:16.159Z" }, + { url = "https://files.pythonhosted.org/packages/c9/7b/2da9c74c1ed25a89cc4e1c8e007ea2eb4a0f1fafa3e70d757fe3242c5c5c/librt-0.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:e54a315caf843c8d77e388cadc56ea9ded569935ee2d2347d7ea94992e5aa6fa", size = 126934, upload-time = "2026-07-08T12:25:17.275Z" }, + { url = "https://files.pythonhosted.org/packages/d0/65/aead61bbf3b5358593f9d4779d2a0e88eaf6ec191a6342dde36dd1df6371/librt-0.13.0-cp312-cp312-win_arm64.whl", hash = "sha256:c718e99a0992127af84385378460db624103b559ab260435abcfe77a4e4ed1c1", size = 112236, upload-time = "2026-07-08T12:25:18.425Z" }, + { url = "https://files.pythonhosted.org/packages/67/3b/18e7b63255297a2bdc9c25c8d6d4ca8eca9f63aceb1252c0f7427ac7099e/librt-0.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a468951af16155824e88bdd8326ebe5bdb371f3ec0ac04642994b98201d914f3", size = 151027, upload-time = "2026-07-08T12:25:19.638Z" }, + { url = "https://files.pythonhosted.org/packages/4d/68/e2248452c00d1a03b45fee1752cdc8f790a476efd2402b75181da88a9e61/librt-0.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ae01d8512cc17079e53425635327dbf3f7ff57a42c00dec348bf79791c56444c", size = 155152, upload-time = "2026-07-08T12:25:20.851Z" }, + { url = "https://files.pythonhosted.org/packages/0e/16/52b1c99bf19057a062aac39c900cbb81499f6f75d6c537c14463d247ba78/librt-0.13.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:32c26893cd085c1efe83219e78d866da23fb20a066101b8f68210004361d224c", size = 502499, upload-time = "2026-07-08T12:25:22.055Z" }, + { url = "https://files.pythonhosted.org/packages/9f/54/b811151805c795f55e0dedee6ec687b75f9982a8105d240ea3910737a77b/librt-0.13.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5929da1981a46bcf4b28b1b9499905f0ff58e2419da402a048234e9783acbc4b", size = 496108, upload-time = "2026-07-08T12:25:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/8f/f8/094d6b2bd93f3fdaa54db54cc788c4a365333bddad65ab02e04da0b1d004/librt-0.13.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94b85d664d777bab6c0d709416cb42938251fda9e221b79e3a2215d85df5f4f9", size = 531576, upload-time = "2026-07-08T12:25:24.648Z" }, + { url = "https://files.pythonhosted.org/packages/2e/40/541733d5755824f968f7ec39d78ffbd75d145964157ae5e69a09ec6d7326/librt-0.13.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:531b2df3e9fe96b1fcf73a6d165921e4656be5f58d631d384ebce344298368db", size = 524390, upload-time = "2026-07-08T12:25:25.898Z" }, + { url = "https://files.pythonhosted.org/packages/c6/b5/255673cfdbf5ba663339d36cd863c897289ab4337577e19f9405ce059f36/librt-0.13.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:109b84a9edf69ad89dc1f66358659e14a031baca95e3e5b0060bd903ede8efd6", size = 543053, upload-time = "2026-07-08T12:25:27.436Z" }, + { url = "https://files.pythonhosted.org/packages/9e/11/ab5005e9c9850710f21e354201bf090646349d3fabf5f951eaf70235729e/librt-0.13.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1304368a3e7ffc3e9db986796cc5326fdb5943a3567ecc137cff318e4240c0e7", size = 546387, upload-time = "2026-07-08T12:25:28.65Z" }, + { url = "https://files.pythonhosted.org/packages/a2/04/a5d7ce1d1df1afd15ca283dcdf7530ac073e12d69ae8c40879dda96f7868/librt-0.13.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e4f9b472e7d308d94b62c801982065661158c6ed02790d6c7ddb4337cea0f9c1", size = 535970, upload-time = "2026-07-08T12:25:30.171Z" }, + { url = "https://files.pythonhosted.org/packages/5a/76/927e267a6daa290174ac281b23c9804c8829b042ade9c6f24a065f540958/librt-0.13.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9f836c37478f167a81200d8c8b2c920a22224564bed2c23d7aeec760965c367a", size = 573582, upload-time = "2026-07-08T12:25:31.507Z" }, + { url = "https://files.pythonhosted.org/packages/10/24/b6c5213efe39c19f9e13605644d0cf063b4ddaa33ac2e45b088e23a70e2e/librt-0.13.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:4000d961ff9598ac6ea603c6c836a5ed49bc205ade5fc378b998dfe1e2c36628", size = 82189, upload-time = "2026-07-08T12:25:32.675Z" }, + { url = "https://files.pythonhosted.org/packages/4c/00/d29736be177a906ac0b84a5b04b4fbfa22c776dc2f366de4172b0f968c08/librt-0.13.0-cp313-cp313-win32.whl", hash = "sha256:79e44cff71750d299d61a678e49995b0d5935a9cda238c2574daeca3ba536927", size = 106193, upload-time = "2026-07-08T12:25:33.692Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ac/aff6fb45393cb8912f39dfb156ef6b2d1cadb207ff465fc8f66141054be8/librt-0.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:54dab44a847d5ad1acd05c8a83fe518ae685516ecf4d3f7cc6e3df2a66767650", size = 126962, upload-time = "2026-07-08T12:25:34.769Z" }, + { url = "https://files.pythonhosted.org/packages/d9/3a/d68cb2b334d53fd30fac81d3a489ce4ba0d9506f4df43fcf676b68352b19/librt-0.13.0-cp313-cp313-win_arm64.whl", hash = "sha256:d4cb6fbfdf874340ab5e51450753c0f817b6958a3621125ee695bbc3de866566", size = 112127, upload-time = "2026-07-08T12:25:35.981Z" }, + { url = "https://files.pythonhosted.org/packages/7b/66/f49ae0d592bd45b6941e9a8bafcb6a87cddcd501ee7874707e767f01b585/librt-0.13.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:25218d94b1d2cbc0ba1d8a3f9dc9af578d9646e5ed16443a70cde1dfdcce6d71", size = 149818, upload-time = "2026-07-08T12:25:37.203Z" }, + { url = "https://files.pythonhosted.org/packages/3d/50/51c76d74014d04fb95b6506d286808984b78a2f7a41039094e6b2194ac48/librt-0.13.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f26629539d4893c2957a16c41bb058e1e135c1f150f6a2e25ed047f64cf3f5c6", size = 154071, upload-time = "2026-07-08T12:25:39.399Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fe/f19b0f5f82d5a1f2da736586bc840abd00ce07d6388136ae80b7333883fc/librt-0.13.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a4517d47b2b8af26975a406fba7d314de9696d864252e0257c6ea90238cfe27f", size = 494168, upload-time = "2026-07-08T12:25:40.641Z" }, + { url = "https://files.pythonhosted.org/packages/94/bc/b8550c75775127fd31a5f20e8775997f7b527ad661fc8ddccd7497c064f7/librt-0.13.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f19e181de5b3a1148bb3420b8c4b0b0ea0fce6950099724ad151d6cea5acc180", size = 491054, upload-time = "2026-07-08T12:25:41.905Z" }, + { url = "https://files.pythonhosted.org/packages/30/14/4d0204867623df3f33f86efd3d3692ba5e01321443f4d6eab35a22697618/librt-0.13.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22034924f5b42d5a56371cf271771bfeaabf235a7a8b6264bef2d20013f786c6", size = 523006, upload-time = "2026-07-08T12:25:43.327Z" }, + { url = "https://files.pythonhosted.org/packages/19/0a/c45fc9a260934696bace1ac5df1e148ac92bd71767aee3bf7cd7a4534f4c/librt-0.13.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7897db4e95e22468bdda33d8e012ceacd0182abf001e6389d763f0def6286b9", size = 515058, upload-time = "2026-07-08T12:25:44.541Z" }, + { url = "https://files.pythonhosted.org/packages/13/0a/50c5ce45b326854ef8fa6ae4c36cf5142e5c55315eaf9e51d0ae73ac4da3/librt-0.13.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1ce61b3746545029d4f5c17d6bd74b676254ad98433086c846ffb5e8fa73f007", size = 534025, upload-time = "2026-07-08T12:25:45.825Z" }, + { url = "https://files.pythonhosted.org/packages/89/2d/08c413c8f93fc13b8103624fce38e5caa86cd08cbbc8465870ab287af54b/librt-0.13.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:46c330e82565962c761dbce7941be2cff7db674ee807455a8d0cadc5f9b759b0", size = 540557, upload-time = "2026-07-08T12:25:47.059Z" }, + { url = "https://files.pythonhosted.org/packages/b3/c1/93af71fb4a364952210051811dd4e40174e79656b050c89cacac18af3330/librt-0.13.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:375f5af8f99cbaa99dd293af986e3d57caabc9ba81a5d3f021603764854197a1", size = 523201, upload-time = "2026-07-08T12:25:48.392Z" }, + { url = "https://files.pythonhosted.org/packages/c1/6e/9766f07b676a4889d9f8bc2864e9ba5fff165653143ef4dda7df6aa34d16/librt-0.13.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9320d34c3376ae204b2cd176e8d4883a013934e0aef822f1aed9c536490c275d", size = 565740, upload-time = "2026-07-08T12:25:49.678Z" }, + { url = "https://files.pythonhosted.org/packages/a2/1e/664e3472ce2b6e10e9b83f29d4a36eb982ff6b5a169ae7567bba3a4c4ff5/librt-0.13.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:9af313c66157a69dc69ea0059a66961692250e0dc95af9c385a48ffb770a0d16", size = 81611, upload-time = "2026-07-08T12:25:50.857Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d4/8582a4d65e2234673685e07309d02c230b28a85724eb0acbf13f019b7f6e/librt-0.13.0-cp314-cp314-win32.whl", hash = "sha256:f2a7253458e34f33543551394ae4fe104b497ec2a65ac266074de64c1df82e37", size = 100106, upload-time = "2026-07-08T12:25:52.03Z" }, + { url = "https://files.pythonhosted.org/packages/63/ce/0cb99efe6086b46cd985dc26672166fae312a239690e75871f7fafbd3fc5/librt-0.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:a3dfe4edf10e8ed7e55b026a8bfc2c2a8704218b659cd4bffdf604fab966dc39", size = 121209, upload-time = "2026-07-08T12:25:53.166Z" }, + { url = "https://files.pythonhosted.org/packages/26/85/4f3ccb083a3c9b0d42e223acdb3c3f507953324a59cdcab4826e8e2e3b89/librt-0.13.0-cp314-cp314-win_arm64.whl", hash = "sha256:68a5faee4bba381cb93b5961f684a514cf0053cb92308ff9c792c2fea0b174c6", size = 106404, upload-time = "2026-07-08T12:25:54.253Z" }, + { url = "https://files.pythonhosted.org/packages/b2/77/333191499538c8e8189de7a4cba8e6f49ee949fd6d6e6324b21fd1522466/librt-0.13.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a38fb81d8376dfa2f8963b265fec07637802b0d01e2a127c19c66cb070fb24f5", size = 159231, upload-time = "2026-07-08T12:25:55.432Z" }, + { url = "https://files.pythonhosted.org/packages/7a/9e/2aa83758f22c278b837a1d8025898434ce2b8bff36678d5330ecaef56dff/librt-0.13.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d4c8d9bd5abce34b2e75edb3bf37ab0f34e49b1f915a40ae8468eb7c85bc5b46", size = 161300, upload-time = "2026-07-08T12:25:56.585Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c0/86791e936553ca763d6b3c2fb4d31d596cd00e14fa631c283a40ba01559a/librt-0.13.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:387e2f1d27e89bffe0d3f520f0da0662c973fd607ca16c1808f8a5085419485e", size = 582056, upload-time = "2026-07-08T12:25:58.144Z" }, + { url = "https://files.pythonhosted.org/packages/a8/d3/a9ec15984a185e000c4d2a16ba28bd623124ad4c38a10974c7ff78e3a893/librt-0.13.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:4f6db193d2e5e0ed60359b9a5a682cd67205d0d3b1e459a867dd4b5c4e7eaa7a", size = 562758, upload-time = "2026-07-08T12:25:59.544Z" }, + { url = "https://files.pythonhosted.org/packages/3c/af/dbe36b78b19c06a55097f99305e4ea9458e2273e6ae16a3cbecaad7ee978/librt-0.13.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d38604854e8d22faadf683ec6c02bb0f886e2ba56ef981a1c36ee275f21ea22", size = 602095, upload-time = "2026-07-08T12:26:00.991Z" }, + { url = "https://files.pythonhosted.org/packages/2a/a8/2966891b4dd2830f5203fbee92ac2c4947653a2390ba73dfa44244fad025/librt-0.13.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:371f7ce73026815dafd51c50ce38416e91428b28c4b2ec97cd39271164b0045c", size = 593452, upload-time = "2026-07-08T12:26:02.352Z" }, + { url = "https://files.pythonhosted.org/packages/61/f5/4df8bfc8405ecf8c0d525b4d69636f694bdd8620b313ec8b76e54a5926cc/librt-0.13.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3aaedf52171bee90860704c560bc798fe83b76247df47568e0197e9b13c735a0", size = 623729, upload-time = "2026-07-08T12:26:04.294Z" }, + { url = "https://files.pythonhosted.org/packages/d6/13/9ac202dffc8db06f75d06c08c2f9f6ff054be67d21272dcc078fa1cc0c57/librt-0.13.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:96bad8725a4f196a798366c25ce075d1f7543a4ec045ffc13e6a7ec095cdab04", size = 617077, upload-time = "2026-07-08T12:26:05.845Z" }, + { url = "https://files.pythonhosted.org/packages/6e/f0/ebe38610716aee5cb28efd95089bb90192096179802779381e1c5dcf239c/librt-0.13.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:6bf6a559ffe4a93bbea6cf31ddf01a7fd9ba342ef51f27beb178e318b74acd61", size = 599561, upload-time = "2026-07-08T12:26:07.21Z" }, + { url = "https://files.pythonhosted.org/packages/4f/5c/c2e72e236fff7abc716d5b1753b8b8cd3ea85ac46fe17d2e7c51d4e1c723/librt-0.13.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:301067672387902c55f94b51d5022304b36c966ea9fe1f21caab99a9bef487c9", size = 645511, upload-time = "2026-07-08T12:26:08.562Z" }, + { url = "https://files.pythonhosted.org/packages/0c/99/6203ce619dee940d6bfbe099ec3fe4be00a68e9d60f70abf906cf124fe66/librt-0.13.0-cp314-cp314t-win32.whl", hash = "sha256:5fdcf34f86de8fb66d7dc7589f96ba91c4aa46671200d400e6fd6f109a483f18", size = 104357, upload-time = "2026-07-08T12:26:09.828Z" }, + { url = "https://files.pythonhosted.org/packages/52/dd/843b6314087c41657c7036d7914d8f294bdf9b580aa8513ea0588c8e9a3d/librt-0.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:260c33e92263fa629b4f6d3c51967a1c2158fe6c33237aaa3ebeac586b085259", size = 126998, upload-time = "2026-07-08T12:26:10.975Z" }, + { url = "https://files.pythonhosted.org/packages/5f/5d/3dcec2884ba1b0806d1408612555c38dd5d68e90156b59f75f6e36435c3a/librt-0.13.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2f281549a4c52ac7bb97997f14353f8bd0e53a34ca0dad1c905cfd0b4a58ae99", size = 110771, upload-time = "2026-07-08T12:26:12.303Z" }, ] [[package]] @@ -1181,7 +1284,7 @@ linkify = [ [[package]] name = "markdown-it-py" -version = "4.0.0" +version = "4.2.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15'", @@ -1191,9 +1294,9 @@ resolution-markers = [ dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, ] [package.optional-dependencies] @@ -1288,15 +1391,15 @@ wheels = [ [[package]] name = "mdit-py-plugins" -version = "0.5.0" +version = "0.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655, upload-time = "2025-08-11T07:25:49.083Z" } +sdist = { url = "https://files.pythonhosted.org/packages/59/fc/f8d0863f8862f25602c0404d75568e89fb6b4109804645e5cdfb1be5cf56/mdit_py_plugins-0.6.1.tar.gz", hash = "sha256:a2bca0f039f39dbd35fb74ae1b5f998608c437463371f0ff7f49a19a17a114d0", size = 56114, upload-time = "2026-05-13T09:03:38.91Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f", size = 57205, upload-time = "2025-08-11T07:25:47.597Z" }, + { url = "https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-py3-none-any.whl", hash = "sha256:214c82fb2ac524472ab6a5bcab1de80f73b50443e187f401bfd77efbc7c6481d", size = 66663, upload-time = "2026-05-13T09:03:37.76Z" }, ] [[package]] @@ -1310,63 +1413,75 @@ wheels = [ [[package]] name = "msgpack" -version = "1.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4d/f2/bfb55a6236ed8725a96b0aa3acbd0ec17588e6a2c3b62a93eb513ed8783f/msgpack-1.1.2.tar.gz", hash = "sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e", size = 173581, upload-time = "2025-10-08T09:15:56.596Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f5/a2/3b68a9e769db68668b25c6108444a35f9bd163bb848c0650d516761a59c0/msgpack-1.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0051fffef5a37ca2cd16978ae4f0aef92f164df86823871b5162812bebecd8e2", size = 81318, upload-time = "2025-10-08T09:14:38.722Z" }, - { url = "https://files.pythonhosted.org/packages/5b/e1/2b720cc341325c00be44e1ed59e7cfeae2678329fbf5aa68f5bda57fe728/msgpack-1.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a605409040f2da88676e9c9e5853b3449ba8011973616189ea5ee55ddbc5bc87", size = 83786, upload-time = "2025-10-08T09:14:40.082Z" }, - { url = "https://files.pythonhosted.org/packages/71/e5/c2241de64bfceac456b140737812a2ab310b10538a7b34a1d393b748e095/msgpack-1.1.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b696e83c9f1532b4af884045ba7f3aa741a63b2bc22617293a2c6a7c645f251", size = 398240, upload-time = "2025-10-08T09:14:41.151Z" }, - { url = "https://files.pythonhosted.org/packages/b7/09/2a06956383c0fdebaef5aa9246e2356776f12ea6f2a44bd1368abf0e46c4/msgpack-1.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:365c0bbe981a27d8932da71af63ef86acc59ed5c01ad929e09a0b88c6294e28a", size = 406070, upload-time = "2025-10-08T09:14:42.821Z" }, - { url = "https://files.pythonhosted.org/packages/0e/74/2957703f0e1ef20637d6aead4fbb314330c26f39aa046b348c7edcf6ca6b/msgpack-1.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:41d1a5d875680166d3ac5c38573896453bbbea7092936d2e107214daf43b1d4f", size = 393403, upload-time = "2025-10-08T09:14:44.38Z" }, - { url = "https://files.pythonhosted.org/packages/a5/09/3bfc12aa90f77b37322fc33e7a8a7c29ba7c8edeadfa27664451801b9860/msgpack-1.1.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354e81bcdebaab427c3df4281187edc765d5d76bfb3a7c125af9da7a27e8458f", size = 398947, upload-time = "2025-10-08T09:14:45.56Z" }, - { url = "https://files.pythonhosted.org/packages/4b/4f/05fcebd3b4977cb3d840f7ef6b77c51f8582086de5e642f3fefee35c86fc/msgpack-1.1.2-cp310-cp310-win32.whl", hash = "sha256:e64c8d2f5e5d5fda7b842f55dec6133260ea8f53c4257d64494c534f306bf7a9", size = 64769, upload-time = "2025-10-08T09:14:47.334Z" }, - { url = "https://files.pythonhosted.org/packages/d0/3e/b4547e3a34210956382eed1c85935fff7e0f9b98be3106b3745d7dec9c5e/msgpack-1.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:db6192777d943bdaaafb6ba66d44bf65aa0e9c5616fa1d2da9bb08828c6b39aa", size = 71293, upload-time = "2025-10-08T09:14:48.665Z" }, - { url = "https://files.pythonhosted.org/packages/2c/97/560d11202bcd537abca693fd85d81cebe2107ba17301de42b01ac1677b69/msgpack-1.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c", size = 82271, upload-time = "2025-10-08T09:14:49.967Z" }, - { url = "https://files.pythonhosted.org/packages/83/04/28a41024ccbd67467380b6fb440ae916c1e4f25e2cd4c63abe6835ac566e/msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0", size = 84914, upload-time = "2025-10-08T09:14:50.958Z" }, - { url = "https://files.pythonhosted.org/packages/71/46/b817349db6886d79e57a966346cf0902a426375aadc1e8e7a86a75e22f19/msgpack-1.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296", size = 416962, upload-time = "2025-10-08T09:14:51.997Z" }, - { url = "https://files.pythonhosted.org/packages/da/e0/6cc2e852837cd6086fe7d8406af4294e66827a60a4cf60b86575a4a65ca8/msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef", size = 426183, upload-time = "2025-10-08T09:14:53.477Z" }, - { url = "https://files.pythonhosted.org/packages/25/98/6a19f030b3d2ea906696cedd1eb251708e50a5891d0978b012cb6107234c/msgpack-1.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c", size = 411454, upload-time = "2025-10-08T09:14:54.648Z" }, - { url = "https://files.pythonhosted.org/packages/b7/cd/9098fcb6adb32187a70b7ecaabf6339da50553351558f37600e53a4a2a23/msgpack-1.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e", size = 422341, upload-time = "2025-10-08T09:14:56.328Z" }, - { url = "https://files.pythonhosted.org/packages/e6/ae/270cecbcf36c1dc85ec086b33a51a4d7d08fc4f404bdbc15b582255d05ff/msgpack-1.1.2-cp311-cp311-win32.whl", hash = "sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e", size = 64747, upload-time = "2025-10-08T09:14:57.882Z" }, - { url = "https://files.pythonhosted.org/packages/2a/79/309d0e637f6f37e83c711f547308b91af02b72d2326ddd860b966080ef29/msgpack-1.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68", size = 71633, upload-time = "2025-10-08T09:14:59.177Z" }, - { url = "https://files.pythonhosted.org/packages/73/4d/7c4e2b3d9b1106cd0aa6cb56cc57c6267f59fa8bfab7d91df5adc802c847/msgpack-1.1.2-cp311-cp311-win_arm64.whl", hash = "sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406", size = 64755, upload-time = "2025-10-08T09:15:00.48Z" }, - { url = "https://files.pythonhosted.org/packages/ad/bd/8b0d01c756203fbab65d265859749860682ccd2a59594609aeec3a144efa/msgpack-1.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa", size = 81939, upload-time = "2025-10-08T09:15:01.472Z" }, - { url = "https://files.pythonhosted.org/packages/34/68/ba4f155f793a74c1483d4bdef136e1023f7bcba557f0db4ef3db3c665cf1/msgpack-1.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb", size = 85064, upload-time = "2025-10-08T09:15:03.764Z" }, - { url = "https://files.pythonhosted.org/packages/f2/60/a064b0345fc36c4c3d2c743c82d9100c40388d77f0b48b2f04d6041dbec1/msgpack-1.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f", size = 417131, upload-time = "2025-10-08T09:15:05.136Z" }, - { url = "https://files.pythonhosted.org/packages/65/92/a5100f7185a800a5d29f8d14041f61475b9de465ffcc0f3b9fba606e4505/msgpack-1.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42", size = 427556, upload-time = "2025-10-08T09:15:06.837Z" }, - { url = "https://files.pythonhosted.org/packages/f5/87/ffe21d1bf7d9991354ad93949286f643b2bb6ddbeab66373922b44c3b8cc/msgpack-1.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9", size = 404920, upload-time = "2025-10-08T09:15:08.179Z" }, - { url = "https://files.pythonhosted.org/packages/ff/41/8543ed2b8604f7c0d89ce066f42007faac1eaa7d79a81555f206a5cdb889/msgpack-1.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620", size = 415013, upload-time = "2025-10-08T09:15:09.83Z" }, - { url = "https://files.pythonhosted.org/packages/41/0d/2ddfaa8b7e1cee6c490d46cb0a39742b19e2481600a7a0e96537e9c22f43/msgpack-1.1.2-cp312-cp312-win32.whl", hash = "sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029", size = 65096, upload-time = "2025-10-08T09:15:11.11Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ec/d431eb7941fb55a31dd6ca3404d41fbb52d99172df2e7707754488390910/msgpack-1.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b", size = 72708, upload-time = "2025-10-08T09:15:12.554Z" }, - { url = "https://files.pythonhosted.org/packages/c5/31/5b1a1f70eb0e87d1678e9624908f86317787b536060641d6798e3cf70ace/msgpack-1.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69", size = 64119, upload-time = "2025-10-08T09:15:13.589Z" }, - { url = "https://files.pythonhosted.org/packages/6b/31/b46518ecc604d7edf3a4f94cb3bf021fc62aa301f0cb849936968164ef23/msgpack-1.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4efd7b5979ccb539c221a4c4e16aac1a533efc97f3b759bb5a5ac9f6d10383bf", size = 81212, upload-time = "2025-10-08T09:15:14.552Z" }, - { url = "https://files.pythonhosted.org/packages/92/dc/c385f38f2c2433333345a82926c6bfa5ecfff3ef787201614317b58dd8be/msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7", size = 84315, upload-time = "2025-10-08T09:15:15.543Z" }, - { url = "https://files.pythonhosted.org/packages/d3/68/93180dce57f684a61a88a45ed13047558ded2be46f03acb8dec6d7c513af/msgpack-1.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1fdf7d83102bf09e7ce3357de96c59b627395352a4024f6e2458501f158bf999", size = 412721, upload-time = "2025-10-08T09:15:16.567Z" }, - { url = "https://files.pythonhosted.org/packages/5d/ba/459f18c16f2b3fc1a1ca871f72f07d70c07bf768ad0a507a698b8052ac58/msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e", size = 424657, upload-time = "2025-10-08T09:15:17.825Z" }, - { url = "https://files.pythonhosted.org/packages/38/f8/4398c46863b093252fe67368b44edc6c13b17f4e6b0e4929dbf0bdb13f23/msgpack-1.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fffee09044073e69f2bad787071aeec727183e7580443dfeb8556cbf1978d162", size = 402668, upload-time = "2025-10-08T09:15:19.003Z" }, - { url = "https://files.pythonhosted.org/packages/28/ce/698c1eff75626e4124b4d78e21cca0b4cc90043afb80a507626ea354ab52/msgpack-1.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5928604de9b032bc17f5099496417f113c45bc6bc21b5c6920caf34b3c428794", size = 419040, upload-time = "2025-10-08T09:15:20.183Z" }, - { url = "https://files.pythonhosted.org/packages/67/32/f3cd1667028424fa7001d82e10ee35386eea1408b93d399b09fb0aa7875f/msgpack-1.1.2-cp313-cp313-win32.whl", hash = "sha256:a7787d353595c7c7e145e2331abf8b7ff1e6673a6b974ded96e6d4ec09f00c8c", size = 65037, upload-time = "2025-10-08T09:15:21.416Z" }, - { url = "https://files.pythonhosted.org/packages/74/07/1ed8277f8653c40ebc65985180b007879f6a836c525b3885dcc6448ae6cb/msgpack-1.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9", size = 72631, upload-time = "2025-10-08T09:15:22.431Z" }, - { url = "https://files.pythonhosted.org/packages/e5/db/0314e4e2db56ebcf450f277904ffd84a7988b9e5da8d0d61ab2d057df2b6/msgpack-1.1.2-cp313-cp313-win_arm64.whl", hash = "sha256:e69b39f8c0aa5ec24b57737ebee40be647035158f14ed4b40e6f150077e21a84", size = 64118, upload-time = "2025-10-08T09:15:23.402Z" }, - { url = "https://files.pythonhosted.org/packages/22/71/201105712d0a2ff07b7873ed3c220292fb2ea5120603c00c4b634bcdafb3/msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00", size = 81127, upload-time = "2025-10-08T09:15:24.408Z" }, - { url = "https://files.pythonhosted.org/packages/1b/9f/38ff9e57a2eade7bf9dfee5eae17f39fc0e998658050279cbb14d97d36d9/msgpack-1.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939", size = 84981, upload-time = "2025-10-08T09:15:25.812Z" }, - { url = "https://files.pythonhosted.org/packages/8e/a9/3536e385167b88c2cc8f4424c49e28d49a6fc35206d4a8060f136e71f94c/msgpack-1.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99e2cb7b9031568a2a5c73aa077180f93dd2e95b4f8d3b8e14a73ae94a9e667e", size = 411885, upload-time = "2025-10-08T09:15:27.22Z" }, - { url = "https://files.pythonhosted.org/packages/2f/40/dc34d1a8d5f1e51fc64640b62b191684da52ca469da9cd74e84936ffa4a6/msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931", size = 419658, upload-time = "2025-10-08T09:15:28.4Z" }, - { url = "https://files.pythonhosted.org/packages/3b/ef/2b92e286366500a09a67e03496ee8b8ba00562797a52f3c117aa2b29514b/msgpack-1.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:04fb995247a6e83830b62f0b07bf36540c213f6eac8e851166d8d86d83cbd014", size = 403290, upload-time = "2025-10-08T09:15:29.764Z" }, - { url = "https://files.pythonhosted.org/packages/78/90/e0ea7990abea5764e4655b8177aa7c63cdfa89945b6e7641055800f6c16b/msgpack-1.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8e22ab046fa7ede9e36eeb4cfad44d46450f37bb05d5ec482b02868f451c95e2", size = 415234, upload-time = "2025-10-08T09:15:31.022Z" }, - { url = "https://files.pythonhosted.org/packages/72/4e/9390aed5db983a2310818cd7d3ec0aecad45e1f7007e0cda79c79507bb0d/msgpack-1.1.2-cp314-cp314-win32.whl", hash = "sha256:80a0ff7d4abf5fecb995fcf235d4064b9a9a8a40a3ab80999e6ac1e30b702717", size = 66391, upload-time = "2025-10-08T09:15:32.265Z" }, - { url = "https://files.pythonhosted.org/packages/6e/f1/abd09c2ae91228c5f3998dbd7f41353def9eac64253de3c8105efa2082f7/msgpack-1.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:9ade919fac6a3e7260b7f64cea89df6bec59104987cbea34d34a2fa15d74310b", size = 73787, upload-time = "2025-10-08T09:15:33.219Z" }, - { url = "https://files.pythonhosted.org/packages/6a/b0/9d9f667ab48b16ad4115c1935d94023b82b3198064cb84a123e97f7466c1/msgpack-1.1.2-cp314-cp314-win_arm64.whl", hash = "sha256:59415c6076b1e30e563eb732e23b994a61c159cec44deaf584e5cc1dd662f2af", size = 66453, upload-time = "2025-10-08T09:15:34.225Z" }, - { url = "https://files.pythonhosted.org/packages/16/67/93f80545eb1792b61a217fa7f06d5e5cb9e0055bed867f43e2b8e012e137/msgpack-1.1.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:897c478140877e5307760b0ea66e0932738879e7aa68144d9b78ea4c8302a84a", size = 85264, upload-time = "2025-10-08T09:15:35.61Z" }, - { url = "https://files.pythonhosted.org/packages/87/1c/33c8a24959cf193966ef11a6f6a2995a65eb066bd681fd085afd519a57ce/msgpack-1.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a668204fa43e6d02f89dbe79a30b0d67238d9ec4c5bd8a940fc3a004a47b721b", size = 89076, upload-time = "2025-10-08T09:15:36.619Z" }, - { url = "https://files.pythonhosted.org/packages/fc/6b/62e85ff7193663fbea5c0254ef32f0c77134b4059f8da89b958beb7696f3/msgpack-1.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5559d03930d3aa0f3aacb4c42c776af1a2ace2611871c84a75afe436695e6245", size = 435242, upload-time = "2025-10-08T09:15:37.647Z" }, - { url = "https://files.pythonhosted.org/packages/c1/47/5c74ecb4cc277cf09f64e913947871682ffa82b3b93c8dad68083112f412/msgpack-1.1.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:70c5a7a9fea7f036b716191c29047374c10721c389c21e9ffafad04df8c52c90", size = 432509, upload-time = "2025-10-08T09:15:38.794Z" }, - { url = "https://files.pythonhosted.org/packages/24/a4/e98ccdb56dc4e98c929a3f150de1799831c0a800583cde9fa022fa90602d/msgpack-1.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f2cb069d8b981abc72b41aea1c580ce92d57c673ec61af4c500153a626cb9e20", size = 415957, upload-time = "2025-10-08T09:15:40.238Z" }, - { url = "https://files.pythonhosted.org/packages/da/28/6951f7fb67bc0a4e184a6b38ab71a92d9ba58080b27a77d3e2fb0be5998f/msgpack-1.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d62ce1f483f355f61adb5433ebfd8868c5f078d1a52d042b0a998682b4fa8c27", size = 422910, upload-time = "2025-10-08T09:15:41.505Z" }, - { url = "https://files.pythonhosted.org/packages/f0/03/42106dcded51f0a0b5284d3ce30a671e7bd3f7318d122b2ead66ad289fed/msgpack-1.1.2-cp314-cp314t-win32.whl", hash = "sha256:1d1418482b1ee984625d88aa9585db570180c286d942da463533b238b98b812b", size = 75197, upload-time = "2025-10-08T09:15:42.954Z" }, - { url = "https://files.pythonhosted.org/packages/15/86/d0071e94987f8db59d4eeb386ddc64d0bb9b10820a8d82bcd3e53eeb2da6/msgpack-1.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:5a46bf7e831d09470ad92dff02b8b1ac92175ca36b087f904a0519857c6be3ff", size = 85772, upload-time = "2025-10-08T09:15:43.954Z" }, - { url = "https://files.pythonhosted.org/packages/81/f2/08ace4142eb281c12701fc3b93a10795e4d4dc7f753911d836675050f886/msgpack-1.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d99ef64f349d5ec3293688e91486c5fdb925ed03807f64d98d205d2713c60b46", size = 70868, upload-time = "2025-10-08T09:15:44.959Z" }, +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/f9/c0a1c127f9049db9155afc316952ea571720dd01833ff5e4d7e8e6352dbb/msgpack-1.2.1.tar.gz", hash = "sha256:04c721c2c7448767e9e3f2520a475663d8ee0f09c31890f6d2bd70fd636a9647", size = 183960, upload-time = "2026-06-18T16:13:52.594Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/16/f70100614b69feb3ade7285f08c9c52d6cda0a5c03f3f5e2facd63acb211/msgpack-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8c7b398c56ff125feae96c2737abfec5595f1fa0aa186df60c56040b8accb95c", size = 82926, upload-time = "2026-06-18T16:12:31.531Z" }, + { url = "https://files.pythonhosted.org/packages/e4/3c/08ecd5cdfe4e2de43aec79062028ad0f7b2d9b1fea5430068c198ba570da/msgpack-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1548006a91aa93c5da81f3bdcebc1a0d10cea2d25969754fbe848da622b2b895", size = 82730, upload-time = "2026-06-18T16:12:32.894Z" }, + { url = "https://files.pythonhosted.org/packages/19/9f/a70c9cb1a04ecc134005149367dcfe35d167284e8f65035a1e4156ad17b5/msgpack-1.2.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1dabedcd0f23559f3596428c6589c1cd8c6eaed3a0d720795b07b0225d769203", size = 400729, upload-time = "2026-06-18T16:12:34.052Z" }, + { url = "https://files.pythonhosted.org/packages/fa/7f/5ce020168cf0439041526e95aa068c722c016aee21624e331aeabeee2e8e/msgpack-1.2.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83efa1c898e0fc5380fc0cabbf75164c52e3b5cbb45973710d75821928380c73", size = 407625, upload-time = "2026-06-18T16:12:35.239Z" }, + { url = "https://files.pythonhosted.org/packages/79/70/fb7668ce0386819303047057aef6fc1da73b584291d9cff82b821744e2ef/msgpack-1.2.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:01e2dd6c9b19d333a00282330cc8a73d38d8dabc306dc5b42cd668c3ac82e833", size = 377891, upload-time = "2026-06-18T16:12:36.684Z" }, + { url = "https://files.pythonhosted.org/packages/3d/dc/9ebe654a73c3aed2e40aa6b52e3c2a02b5f53ef0085fa235a45d5b367f87/msgpack-1.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:350cb813d0af6e65d2f7ef0d729f7ff5be5a8bce03665892f43e5883d4ecc1b8", size = 391987, upload-time = "2026-06-18T16:12:37.839Z" }, + { url = "https://files.pythonhosted.org/packages/42/eb/b67cf64218a2fa25e1c671fe1d3dbb06cbeb973e71bc4b822da079862d0b/msgpack-1.2.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:ee1d9ed27d0497b848923746cf762ed2e7db24f4be7eec8e5cbe8c766aa707b7", size = 374603, upload-time = "2026-06-18T16:12:39.221Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2e/9ee200cde32fd1a0101b4006202fde554c1860adfb9bf7bff31ea4c08df8/msgpack-1.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:633727297ed063441fd1cda2288865487f33ad14eeb8831afb5f0c396a62cfce", size = 405121, upload-time = "2026-06-18T16:12:40.524Z" }, + { url = "https://files.pythonhosted.org/packages/43/b6/f10117be7ca7a51e8feed699a907b8e663a8cd66e115ae6b4fb30cc7945c/msgpack-1.2.1-cp310-cp310-win32.whl", hash = "sha256:298872ecf9e61950f1c6af4ca969b859ee91783bb920ef6e6172697d0c8aad74", size = 64088, upload-time = "2026-06-18T16:12:41.762Z" }, + { url = "https://files.pythonhosted.org/packages/ba/93/89976c696fb0224662239d952c47b4d1661b34d79a332ef5584facaa8579/msgpack-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2ff164c1b0bcb740b073b99e945234d0212852fa378e44a208c425379140dbeb", size = 70113, upload-time = "2026-06-18T16:12:42.78Z" }, + { url = "https://files.pythonhosted.org/packages/f4/6b/e9b1cdc042c4458801d2545ed782a95f3d6ba8e270cce8745b8603c7f748/msgpack-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:29a3f6e9667868429d8240dfd063ea5ffdc1321c13d783aa23827a38de0dcb22", size = 82812, upload-time = "2026-06-18T16:12:45.022Z" }, + { url = "https://files.pythonhosted.org/packages/0c/3a/dd518a1bf78ed1e9ad8afe57307c079a00eafe4b3068932a27ca1ea56b4f/msgpack-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aded5bdf32609dc7987a49bbbd15a8ef096193f96dd8bbeb791de729e650acf5", size = 82739, upload-time = "2026-06-18T16:12:46.025Z" }, + { url = "https://files.pythonhosted.org/packages/70/e0/7ba9e1542bf0771a27b8b37c1316e3f95ae9d748fd765284655c476ad4ef/msgpack-1.2.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:146ee4e9ce80b365c6d4c47073da9da7bcec473e58194ceee5dd7620ace77e06", size = 414233, upload-time = "2026-06-18T16:12:47.029Z" }, + { url = "https://files.pythonhosted.org/packages/03/8d/671d81534ea0e2b0e8a121be100020da09eb78861fe3aa8f3ef7dcd3bed1/msgpack-1.2.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a28d076ca7c82b9c8728ad90b7147489449557038bed50e4241eb832395169b4", size = 423843, upload-time = "2026-06-18T16:12:48.19Z" }, + { url = "https://files.pythonhosted.org/packages/d2/b6/e5c737515ed1f166664b87601b532f58cbb73d8aa6a90b99f7c2c5037e8e/msgpack-1.2.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7d31c0ac0c640f877804c67cb2bc9f4e23dc2db97e96c2e67fa27d38283b41f8", size = 390772, upload-time = "2026-06-18T16:12:49.624Z" }, + { url = "https://files.pythonhosted.org/packages/a8/46/62ed8c2e87d7021eab19921594d961ef3aa3794eec76c716dc30f3bfd433/msgpack-1.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8ff92d7feeaf5bc26c51495b69e2f99ed97ab79346fb6555f44be7dd2ac6503b", size = 409559, upload-time = "2026-06-18T16:12:50.936Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/59aa3887b860bbf43532835e192b1c388a17590d6068ae4f8b2bc74c906e/msgpack-1.2.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:779197a6513bab3c3632265e3d0f7cb3227e62510841a6f34f1eaa37efbb345e", size = 387838, upload-time = "2026-06-18T16:12:52.161Z" }, + { url = "https://files.pythonhosted.org/packages/09/11/f8563e471093420cf6478cb3271a0175d8402b82d879783d4035d2d03360/msgpack-1.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:67f6dd22fa72a93752643f07889796d62739a13415ee630169a8ce764f86cf9f", size = 421732, upload-time = "2026-06-18T16:12:53.556Z" }, + { url = "https://files.pythonhosted.org/packages/57/cf/e673683c4c6c90c1022b24c65af4b03eda72b182a1176ef6449069d66acc/msgpack-1.2.1-cp311-cp311-win32.whl", hash = "sha256:91054a783328e0ea7954b8771095705c8d2243b814743fbaadf14552c9c52c5d", size = 64091, upload-time = "2026-06-18T16:12:54.821Z" }, + { url = "https://files.pythonhosted.org/packages/3f/07/ca212739d179f9083bff2c7c08c24101c3555a334fadc2b876b18768a3ae/msgpack-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2eda0b7ebb1283a98d3e4492ac933c8af6aff59fd3df1c3ed024f536af4b1dc8", size = 70462, upload-time = "2026-06-18T16:12:55.898Z" }, + { url = "https://files.pythonhosted.org/packages/6d/be/6798347b425e26f35db82e69dd83c09716c856a3714e7bffc4c0860fd830/msgpack-1.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:6ee967f7c7e1df2890c671ff2ee51a28ded0efc95da3e507176dee881ce36c66", size = 65059, upload-time = "2026-06-18T16:12:57.053Z" }, + { url = "https://files.pythonhosted.org/packages/bc/dd/9e8cbd8f5582ca4b590336f2b91ee5662f6a6ca562b565abaf696a0f81ff/msgpack-1.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2ef59c659f289eddf8aa6623823f19fa2f40a4029266889eac7a2505dd210c35", size = 83531, upload-time = "2026-06-18T16:12:58.249Z" }, + { url = "https://files.pythonhosted.org/packages/50/2e/ebdb85a8da151397a2790363676b7ed7c125924fe618e4c6d8befb0cc62c/msgpack-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d3567748a5107cb40cdf66a275430c2f87c07777698f4bfd25c35f44d533258c", size = 82657, upload-time = "2026-06-18T16:12:59.396Z" }, + { url = "https://files.pythonhosted.org/packages/26/aa/753ad8b007b464e1d8aa0c8e650b9c5f4f725e658fc5ac8a7635c55b7f6e/msgpack-1.2.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60926b75d00c8e816ef98f3034f484a8bc64242d66839cef4cf7e503142316a0", size = 410634, upload-time = "2026-06-18T16:13:00.383Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/6adabd4f6d5e686f97dd02ce7fce3fe4cf672cbac36b8f67ff4040e8ad8b/msgpack-1.2.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:020e881a764b20d8d7ca1a54fc01b8175519d108e3c3f194fddc200bda95951a", size = 419989, upload-time = "2026-06-18T16:13:01.776Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cc/85039b7b0eb168aaad7383a23c97e291a11f08351cb45a606ce865e4e3f1/msgpack-1.2.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4202c74688ca06591f78cb18988228bd4cca2cc75d57b60008372892d2f1e6e6", size = 377544, upload-time = "2026-06-18T16:13:03.637Z" }, + { url = "https://files.pythonhosted.org/packages/ed/bf/35963899493b32030c85fc513b723ae66144ac70c11ebc52e889e16e3d99/msgpack-1.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8b267ce94efb76fbd1b3373511420074ee3187f0f7811bf394531de13294735a", size = 400842, upload-time = "2026-06-18T16:13:05.012Z" }, + { url = "https://files.pythonhosted.org/packages/a6/df/8e2ac970c8f99264cd9997d1c73df5466bc19da3301d7dc5500862a9b089/msgpack-1.2.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f1d0f8f98ade9634e01fb704a408f9336c0a8f1117b369f5db83dc7551d8b1", size = 374108, upload-time = "2026-06-18T16:13:06.232Z" }, + { url = "https://files.pythonhosted.org/packages/17/dd/fa8bd265110dfa51c20cb529f9e6d240a16fafe7e645004c6af2d01353ba/msgpack-1.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f02cf17a6ca1abe29b5f980644f7551f94d71f2011509b26d8625ce038f0df64", size = 414939, upload-time = "2026-06-18T16:13:07.478Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b9/8377a5ad8953fc0437c70cc98d9ae29f27fe5ac5109fbec0812085865735/msgpack-1.2.1-cp312-cp312-win32.whl", hash = "sha256:0c0d9802354507bcba62af19c17918e3eb437cc25e6f50657d511b5856a77aac", size = 64504, upload-time = "2026-06-18T16:13:08.822Z" }, + { url = "https://files.pythonhosted.org/packages/57/7f/ce1e377df7e62461fefd9eb23bfb93a4a523f40a517b377b8f844d836828/msgpack-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:5c24aa15d5963051e1a5c62b12c50cd705992502b5ec1f3bece6046f33c9fc24", size = 71421, upload-time = "2026-06-18T16:13:09.828Z" }, + { url = "https://files.pythonhosted.org/packages/8f/32/ebfe84c9929f08f188d56c7a2fd913406a9ddad76a634697c1c43b8112e6/msgpack-1.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:4227224aaec8f7fbcbfbd4272319347b2bb4030366502600f8c45588c5187b07", size = 64775, upload-time = "2026-06-18T16:13:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ac/dcddcab6f6c20ecb387ca5e980371cdb3f87ff69aeca388be97eebc4c074/msgpack-1.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0a70e3cf2804a300d921bb0940426e35f4e489a23adfb77a808892241db0a064", size = 83151, upload-time = "2026-06-18T16:13:12.173Z" }, + { url = "https://files.pythonhosted.org/packages/64/71/fbcfa83a1d6a9c6091942d1cfd070962244664b87427a9a49a6897b1b219/msgpack-1.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:491cc39455ca765fad51fb451bf2915eb2cf41192ab5801ce8d67c1d614fe056", size = 82351, upload-time = "2026-06-18T16:13:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/e3/10/ddf7b06db879e8792d13934ddda09ff20bd2a583fd84c9b59aae9b0e650b/msgpack-1.2.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f310233ef7fb9c14e201c93639fe5f5260b005f56f0b29048e999c30935596cc", size = 407518, upload-time = "2026-06-18T16:13:14.233Z" }, + { url = "https://files.pythonhosted.org/packages/79/d3/36a46a8ed992b781acbc05928bd5bee3c810cb0c3563bf81a7b0c04a1a76/msgpack-1.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:787c9bebb5833e8f6fc8abca3c0597683d8d87f56a8842b6b89c75a5f3176e2d", size = 416405, upload-time = "2026-06-18T16:13:15.435Z" }, + { url = "https://files.pythonhosted.org/packages/f9/84/e8e9598b557c0ba6ddae901a73780a4c75ac667dddf59414b1e56a42fb34/msgpack-1.2.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dc871b997a9370d855b7394465f2f350e847a5b806dd38dcc9c989e7d87da155", size = 376257, upload-time = "2026-06-18T16:13:17.022Z" }, + { url = "https://files.pythonhosted.org/packages/40/16/738fe6d875ad7e2a9429c165322a4ec088f4f273cdfae63d96a89c467961/msgpack-1.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:85f57e960d877f2977f6430896191b04a21f8901b3b4baf2e4604329f4db5402", size = 397469, upload-time = "2026-06-18T16:13:18.287Z" }, + { url = "https://files.pythonhosted.org/packages/ca/be/6d5952df75a7f24f35833af764c3a6860780364cb3a0030beb8099e1b2b4/msgpack-1.2.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:1233ee2dd0cefba127583de50ea654677277047d238303521db35def3d7b2e7c", size = 372802, upload-time = "2026-06-18T16:13:19.685Z" }, + { url = "https://files.pythonhosted.org/packages/e1/39/e2ef7dbf0473bcb8dc7c50bf782a892d67414877b63e47fc88eb189ef5e6/msgpack-1.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e3dc2feb0876209d9c38aa56cb1de169bd6c4348f1aa48271f241226590993e6", size = 411273, upload-time = "2026-06-18T16:13:21.028Z" }, + { url = "https://files.pythonhosted.org/packages/ef/c5/133f4512a56e983a93445c836c9d94d88f3bc2e0980ff4b9e577bd8416ce/msgpack-1.2.1-cp313-cp313-win32.whl", hash = "sha256:6d09badf350af2be9d189184e04e64cf54ad93569ab3d96fca58bd3e84aad707", size = 64471, upload-time = "2026-06-18T16:13:22.293Z" }, + { url = "https://files.pythonhosted.org/packages/e2/98/577e10b055096a7dd40732358cabaf7180a20c79ed1dcdbb618e4b9deac7/msgpack-1.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:33f14fba63278b714efe6ad07e50ea5f03d91537aa6a1c5f1ceca4cf44013ca9", size = 71274, upload-time = "2026-06-18T16:13:23.455Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ee/0c0048e7cfbef23c6a94791b8959ab28155232e7956de8a305b5ff588f05/msgpack-1.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc5febcd4c99effbc02b528e49d6fd0760b2b7d48c05239e345a5fa6e743d9a", size = 64795, upload-time = "2026-06-18T16:13:24.687Z" }, + { url = "https://files.pythonhosted.org/packages/77/58/cce442852c6b9e1639c7c8ac8fd9143121cb32dab0f308df4d1426a8eb9c/msgpack-1.2.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:05f340e47e7e47d2da8db9b53e1bb1d294369e9ef45a747441309f6650b8351d", size = 83610, upload-time = "2026-06-18T16:13:25.724Z" }, + { url = "https://files.pythonhosted.org/packages/60/5c/15b4c7a0182f75ffa90751958ba36a9c01cafee367d49a3edc10ed140b01/msgpack-1.2.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:810b916696c86ef0deb3b74588480224df4c1b071136c34183e4a2a4284d7ac7", size = 83138, upload-time = "2026-06-18T16:13:26.781Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a6/99e58722feaffc5f2fbcc0c8c0d1451ab9f84097f7af87291b46af2390f4/msgpack-1.2.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ca0dacff965c47afdc3749a8469d7302a8f801d6a28758d55120d75e66ce6889", size = 406090, upload-time = "2026-06-18T16:13:28.072Z" }, + { url = "https://files.pythonhosted.org/packages/19/03/8c63e8cf52958534ef688625965ab04c269a6cadd8caef16758b380a821a/msgpack-1.2.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e2bf9280bceb5efca998435904b5d3e9fdbcc11d90dc9df30aec7973252b720", size = 412106, upload-time = "2026-06-18T16:13:29.427Z" }, + { url = "https://files.pythonhosted.org/packages/63/d2/155d9e71b40e41fd934bc0c48b9b2770f22263e1ac20aad8e29fdca7be3f/msgpack-1.2.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aa6c4be5d1c02a42b066ca6ddb71adf36432868fdcdb6ee87e634e86e0674190", size = 374851, upload-time = "2026-06-18T16:13:30.631Z" }, + { url = "https://files.pythonhosted.org/packages/98/48/deaf2326262a8d5ea3295ce9649912ecd3f551ba7ec8e33c665d2ba583f3/msgpack-1.2.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec0e675d59150a6269ddc9139087c722292664a37d071a849c05c473350f1f2d", size = 396168, upload-time = "2026-06-18T16:13:31.977Z" }, + { url = "https://files.pythonhosted.org/packages/10/2a/b4410f906c2ec0008f1608d3ab5143afc3ad3f4e6da0fed3ea2231d0bef4/msgpack-1.2.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:dd3bfe82d53edfe4b7fc9a7ec9761e23a7a5b1dac22264505af428253c29ed24", size = 371959, upload-time = "2026-06-18T16:13:33.282Z" }, + { url = "https://files.pythonhosted.org/packages/59/86/1edc67270099a528fa2093ea60fe191233cd238e4bd30cfacf7db79fc959/msgpack-1.2.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5ad5467fc3f68b5468e06c5f788d712e9f8ffc8b0cd1bcb160c105c1ee92dae7", size = 408457, upload-time = "2026-06-18T16:13:34.567Z" }, + { url = "https://files.pythonhosted.org/packages/82/90/8b630fef07d8c5ab457b71ff2c217910c83d333c7a68472c186e87cc504a/msgpack-1.2.1-cp314-cp314-win32.whl", hash = "sha256:98b58bdb89c46190e4609bb36abe17c6d4105ad13f9c5f8f6f64d320f8ced3fb", size = 65942, upload-time = "2026-06-18T16:13:36.056Z" }, + { url = "https://files.pythonhosted.org/packages/16/f1/467b81e98b24dd3885d7b1857728797b4ffc76a7a7483af4fb321a07de3c/msgpack-1.2.1-cp314-cp314-win_amd64.whl", hash = "sha256:74847557e28ce71bd3c438a447ca90e4b507e997ddbdef8a12a7b283b86c156b", size = 72627, upload-time = "2026-06-18T16:13:37.079Z" }, + { url = "https://files.pythonhosted.org/packages/a7/1d/5d8c4c89985feb6acefb82a09e501c60392261856d2408d20bfe4f0360b1/msgpack-1.2.1-cp314-cp314-win_arm64.whl", hash = "sha256:b50b727bd652bdc37d950336c848ef20ec54a4cafc38dce19b1cd86ad625d0f7", size = 66908, upload-time = "2026-06-18T16:13:38.23Z" }, + { url = "https://files.pythonhosted.org/packages/1b/02/ad2afb678b4de94496cd432b581759b756a92c1192d8c767edd6b132efdc/msgpack-1.2.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8d00f177ca88a77c1cf848d204a38f249751650b601cb6532acc68805d8a8273", size = 86000, upload-time = "2026-06-18T16:13:39.44Z" }, + { url = "https://files.pythonhosted.org/packages/54/74/0b797484013128837f3b1cbb6cea019277c4de4e377dc512b4d9a0f92940/msgpack-1.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5bb9c386f0a329c035ddbab4b72d1028bf9627add8dda41070288563d57ed1b1", size = 86544, upload-time = "2026-06-18T16:13:40.447Z" }, + { url = "https://files.pythonhosted.org/packages/a9/b4/b774d7eb95561739907fec675582f83203cf41c597a418c2589b4bfb8e9d/msgpack-1.2.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20466cca18c49c7292a8984bc15d65857b171e7264bdcb5f96baf8be238791fc", size = 427661, upload-time = "2026-06-18T16:13:41.574Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f9/3243191dc9937e00756c8bc1b0272fed8f23758e43df2a3b46f533e5090f/msgpack-1.2.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:196300e7e5d6e74d50f1607ab9c06c4a1484c383cd22defd727902591f7e8dde", size = 426375, upload-time = "2026-06-18T16:13:42.936Z" }, + { url = "https://files.pythonhosted.org/packages/23/c7/1693111db9944ba4ad4b67a1e788400d78a0b6af7a6523dc7e4e58f8274b/msgpack-1.2.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575957e79cd51903a4e8495a242442949641e08f1efd5197b43bebd3ea7682b4", size = 380495, upload-time = "2026-06-18T16:13:44.306Z" }, + { url = "https://files.pythonhosted.org/packages/3e/2b/92f86956a0c13e8662f7e2ad630c4eb4db07497b967589bd5245e018b2c1/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8c2ed1e48cc0f460bf3c7780e7137ff21a4e18433451916f2442c1b21036cd7d", size = 410897, upload-time = "2026-06-18T16:13:45.629Z" }, + { url = "https://files.pythonhosted.org/packages/da/ea/1479f72d200313a76fc2f823a79d1e07ed052ab7b8a0280640aa7b95de42/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5f6277e5f783c36786a145e0247fc189a03f35f84b251646e53592d2bc12b355", size = 378519, upload-time = "2026-06-18T16:13:46.998Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/fa006060ffa1011d32bfae826fe766fe73e02982183601633b7121058ab3/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f9389552ecf4784886345ead0647e4edc96bee37cbab05b75540f542f766c48c", size = 419815, upload-time = "2026-06-18T16:13:48.205Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/aab6c946570496b78e67804721f3d5e2d62a93081b9b37df77764ef56347/msgpack-1.2.1-cp314-cp314t-win32.whl", hash = "sha256:c1c79a604a2969a868a78b6ebd27a887e00c624f14f66b3038e0590cb23332d1", size = 70914, upload-time = "2026-06-18T16:13:49.385Z" }, + { url = "https://files.pythonhosted.org/packages/13/0a/e608956488a2af014cfe6e3d665e090b8ee42aa14b07f8f95b8880d66b09/msgpack-1.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:f12038a35fabd52e56a3547bab42401af49a45caa6dd00b34c44de235bc93ee2", size = 77999, upload-time = "2026-06-18T16:13:50.467Z" }, + { url = "https://files.pythonhosted.org/packages/d2/8a/27e2e57055176e366a46b85d02d68e7a5bcfbdd8474c9706375d965f24d3/msgpack-1.2.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0adcf06ffde0777c0e1a9b771a2b1c4226ba1bbf748c8efcc02fcdeca3299107", size = 71160, upload-time = "2026-06-18T16:13:51.498Z" }, ] [[package]] @@ -1509,7 +1624,7 @@ wheels = [ [[package]] name = "mypy" -version = "2.2.0" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ast-serialize" }, @@ -1519,52 +1634,52 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/7e/be536678c6ae49ef058aba4b483d8c7bc104f471479016066f345bc1f5f8/mypy-2.2.0.tar.gz", hash = "sha256:2cdd99d48590dce6f6b7f1961eda75386364398fcdaad86923bc0f0231bf9baf", size = 3950939, upload-time = "2026-07-08T01:37:27.335Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5f/f1/a818c375094e20a74ec51444cce6979cedd61d476f860c2f084ea8653bd2/mypy-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:97d21f3a1582ef30d0b77f9ca3ad88b4263f3c5aea9e7380cb5d7175160aec7e", size = 14903842, upload-time = "2026-07-08T01:33:27.944Z" }, - { url = "https://files.pythonhosted.org/packages/33/15/f332590488a8e4bb4a24036484c8bc750fe01fbef09701451a8790ac4c44/mypy-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2529017942b951cc43db2e2712b71cc3aa7e9d90567630c03ed63d430aeec61a", size = 13902986, upload-time = "2026-07-08T01:36:59.24Z" }, - { url = "https://files.pythonhosted.org/packages/38/9f/7ae37860922d264b536790a3307caa195eb8abb733f2e81608229bbb0f07/mypy-2.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0823d7f273f3b4a49df7573eac271ddbf77a0e5f53e24d294a4f0f77ad22e1d7", size = 14132163, upload-time = "2026-07-08T01:34:16.111Z" }, - { url = "https://files.pythonhosted.org/packages/b2/6d/25c31c85a793340a4a9be593f8fe2cea08fd7b615f8b602b3f52f2d822f6/mypy-2.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d78a0fc90704894bc9948d78affad14b882b08183a7c30412d185748aaa9418b", size = 15070110, upload-time = "2026-07-08T01:34:44.933Z" }, - { url = "https://files.pythonhosted.org/packages/cb/67/7adf1caa143f6a0d9c564de24e0c1ed48340185110c3b918adc2f447192b/mypy-2.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6efab25fa3568569fda06928743382900860c48be9200c1758ef5ce94b532714", size = 15371554, upload-time = "2026-07-08T01:34:27.688Z" }, - { url = "https://files.pythonhosted.org/packages/49/cb/ceca928213076f540d9b068c3655c52d43549f124c1f6dece5ecb747bbeb/mypy-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:daeaf5287091d68f674c91416cabab0f80f36e347ed17fded38d7ebde682e9d1", size = 11063618, upload-time = "2026-07-08T01:36:13.235Z" }, - { url = "https://files.pythonhosted.org/packages/41/24/08caa177a4f2e0c44b96d5ad85f2754761b45bb6d65841451ef5dc9edb86/mypy-2.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:f8d97940a0259e09c219903579720b2df12170c0c3a3b3799837c1fb63deb44e", size = 10070720, upload-time = "2026-07-08T01:37:13.251Z" }, - { url = "https://files.pythonhosted.org/packages/96/2e/1ea8028583fef6561d146b51d738d91268201313ecf69e603e808a740e74/mypy-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea6fe1a30f3e7dc574d641497ffead2428046b0f8bc5804d13b4e4392fdc317b", size = 14739569, upload-time = "2026-07-08T01:35:33.202Z" }, - { url = "https://files.pythonhosted.org/packages/ba/67/c0607da57d78358b3b4fbfa90ee8ca5c6bd1dbb997c9648904ad4d8861d8/mypy-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6965829a6d847a0925f51149472bbeb7a39332fb4801972fdfd9cedd9f8d43a4", size = 13821442, upload-time = "2026-07-08T01:33:45.991Z" }, - { url = "https://files.pythonhosted.org/packages/bb/56/0407007d4ec7a762bac20724af1f0a57a9d860186c39e73105b6b8396fa2/mypy-2.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a906bfc9c4c5de3ece6dc4726f8076d56ce9be1720baf0c6f84e926c10262a4", size = 14049813, upload-time = "2026-07-08T01:35:44.282Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d1/d718e006c8fed4bece7a1bebeea6dcd05f31433af552fc45a82fef426379/mypy-2.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:91df92625cb3452758f27f4965b000fb05ad89b00c282cc3430a7bd6b0e5389e", size = 14978473, upload-time = "2026-07-08T01:36:54.064Z" }, - { url = "https://files.pythonhosted.org/packages/82/03/dae7299c45a84efb1590875f92652a5beb2da98a2cff9a567995e2583fe4/mypy-2.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d42893d15894fd34f395090e2d78315ba7c637d5ee221683e02893f578c2f548", size = 15224649, upload-time = "2026-07-08T01:35:15.988Z" }, - { url = "https://files.pythonhosted.org/packages/ae/8e/738e4e73d030f20852a81383c74319ca4a9a4fdaadc3a75823588fe2c833/mypy-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3abaeec02cdc72e30a147d99eb81852b6b745a2c8d19607e25241d79b1abbce", size = 11049851, upload-time = "2026-07-08T01:34:39.31Z" }, - { url = "https://files.pythonhosted.org/packages/94/09/6c58caedb3fa5831a9b179687cd7dc252c66a61dca4800e5ba19c8eff82b/mypy-2.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:c39bdb7ceab252d15011e26d3a254b4aaa3bbf121b551febfa301df9b0c69abe", size = 10060307, upload-time = "2026-07-08T01:33:21.852Z" }, - { url = "https://files.pythonhosted.org/packages/d1/be/fbaba7b0ee89874fb11668416dec9e5585c190b676b0796cff26a9290fe8/mypy-2.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:484a2be712b245ac6e89847141f1f50c612b0a924aa25917e63e6cfcf4da07cd", size = 14928025, upload-time = "2026-07-08T01:37:24.376Z" }, - { url = "https://files.pythonhosted.org/packages/c5/8f/f79a7c5a76671b0f563d4beaa7d99fe90df4500d2c1d2ba1be0432121bcf/mypy-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fb0a020dc68480d40e484675558ed637140df1ccbf896a81ba68bca85f2b50a0", size = 13793027, upload-time = "2026-07-08T01:34:33.937Z" }, - { url = "https://files.pythonhosted.org/packages/b2/b9/3db0086bab611d34e26061b86189e6f71de6d22a9b81699a93b006eabcf6/mypy-2.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc361340732ce7108fa0308812caf02bb6868f16112f1efd35bcad88badf3327", size = 14108322, upload-time = "2026-07-08T01:36:08.316Z" }, - { url = "https://files.pythonhosted.org/packages/58/29/4f1e13979a848de2a0fd385462354b58358b6e8b3d9661663e308f6e3d5d/mypy-2.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b0179a3a0b833f724a65f22613607cf7ea941ab17ec34fa283f8d6dfe21d9fa9", size = 15190198, upload-time = "2026-07-08T01:36:20.168Z" }, - { url = "https://files.pythonhosted.org/packages/14/f7/7759f6294d9d25d86671957d0974a215a2a24d429526e26a2f603de951c5/mypy-2.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9e0899b13da1e4ba44b880550f247402ce90ffecc71c54b220bcbe7ecb34f394", size = 15424222, upload-time = "2026-07-08T01:33:39.398Z" }, - { url = "https://files.pythonhosted.org/packages/d7/1b/05b212bef4d2234b5f0b551ea53ce0680d8075b2e79861c765f70b590945/mypy-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:511320b17467402e2906130e185abffffa3d7648aff1444fc2abb61f4c8a087d", size = 11135191, upload-time = "2026-07-08T01:35:03.019Z" }, - { url = "https://files.pythonhosted.org/packages/92/51/495e7122f6589948b36d3820a046461906756a0eb1b6dedc13ebfec7815e/mypy-2.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:7589f370b33dcdd95708f5340f13a67c2c49140957f934b42ef63064d343cca0", size = 10132502, upload-time = "2026-07-08T01:34:04.508Z" }, - { url = "https://files.pythonhosted.org/packages/a3/5f/2d7a9ac5646274cd6e77ce3abcc2a9ece760c2b21f4c4b9f301711e07855/mypy-2.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6968f27347ef539c443ddfd6897e79db525ddb8c856aa8fbf14c34f310ca5193", size = 14931618, upload-time = "2026-07-08T01:33:51.702Z" }, - { url = "https://files.pythonhosted.org/packages/b2/8a/1adaa7caaa104f87021b1ac71252d62e646e9b623d77900ac7a0ae252bf3/mypy-2.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3df226d2a0ae2c3b03845af217800a68e2965d4b14914c99b78d3a2c8ae23299", size = 13857718, upload-time = "2026-07-08T01:35:27.555Z" }, - { url = "https://files.pythonhosted.org/packages/1d/15/b11586b5aebbb82213e297fc30a6fcf3bed6a9deea3739cd8dd87621f3fd/mypy-2.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fc53553996aca2094216ad9306a6f06c5265d206c1bcb54dd367560bd3557825", size = 14059704, upload-time = "2026-07-08T01:33:57.363Z" }, - { url = "https://files.pythonhosted.org/packages/03/db/071e05ab442596bdf7a845e830d5ef7128a0175281038245b171a6b16873/mypy-2.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:996abf2f0bebf572556c60720e8dc0cf5292b64060fa68d7f2bc9caa48e01b6f", size = 15128719, upload-time = "2026-07-08T01:33:33.855Z" }, - { url = "https://files.pythonhosted.org/packages/f3/1c/c4b84eafb85ee315da72471523cc1bf7d7c42164085c42333601da7a8817/mypy-2.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ec287c2381898c652bf8ff79448627fe1a9ee76d22005181fac7315a485c7108", size = 15378692, upload-time = "2026-07-08T01:34:10.468Z" }, - { url = "https://files.pythonhosted.org/packages/68/a4/59a0ee94877fdfe2958cec9b6add72a75393063c79cb60ab4026dd5e10c2/mypy-2.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:c2c967a7685fa93fcf1a778b3ebe76e756b28ba14655f539d7b61ff3da69352a", size = 11150911, upload-time = "2026-07-08T01:35:21.603Z" }, - { url = "https://files.pythonhosted.org/packages/90/e4/6a9144be50180ed43d8c92de9b03dff504daa92b5bcc0353e8960799a23b/mypy-2.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:d59a4b80351ec92e5f7415fcdd008bd77fcbefc7adf9cbc7ffe4eb9f71617734", size = 10125389, upload-time = "2026-07-08T01:36:36.164Z" }, - { url = "https://files.pythonhosted.org/packages/73/32/0aa8d8d197023ca6040f7b25a486cb47037b6350b0d3bae657c8f85fb43f/mypy-2.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1f6c3d76853071409ac58fc0aadfb276a22af5f190fdaa02152a858088a39ebd", size = 14926083, upload-time = "2026-07-08T01:36:02.365Z" }, - { url = "https://files.pythonhosted.org/packages/e2/7c/35bbe0cb10e6699f90e988e537aaf4282a6c16e37f58848a242eb0a98bde/mypy-2.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bdaa177e80cc3292824d4ef3670b5b58771ee8d57c290e0c9c89e7968212332c", size = 13879985, upload-time = "2026-07-08T01:36:31.093Z" }, - { url = "https://files.pythonhosted.org/packages/f9/0c/1597fbebd873e9b63452317740ae3dd32692cec5da180cc65acd96cd28cf/mypy-2.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80923e6d6e7878291f537ee11052f974954c20cb569798429a5dc265eb780b47", size = 14076883, upload-time = "2026-07-08T01:34:21.789Z" }, - { url = "https://files.pythonhosted.org/packages/68/35/2ec021a83ec01b5d522639f78d8b36adade7fa4821db0f48fd6d82e861f3/mypy-2.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f24bd465a09077c8d64be8f19a6646db467a55490fd315fe7871afe6bb9645", size = 15103567, upload-time = "2026-07-08T01:36:47.717Z" }, - { url = "https://files.pythonhosted.org/packages/53/3a/8cb3529f6d6800c7d069935e5c83a05d80263847b8a947cf6b0b16a9e958/mypy-2.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:db34595464869f474708e769413d1d739fc33a69850f253757b9a4cc20bc1fec", size = 15354641, upload-time = "2026-07-08T01:36:41.592Z" }, - { url = "https://files.pythonhosted.org/packages/d6/4d/320bc9a9553f8a9db5e847ec5ded762ef7ed7403c76c4ba2e8181c80e2f0/mypy-2.2.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:b48092132c7b0ef4322773fecae62fc5b0bc339be348badeec8af502122a4a51", size = 7694355, upload-time = "2026-07-08T01:37:03.291Z" }, - { url = "https://files.pythonhosted.org/packages/90/05/bf3b349e2f885cd3aab488111bb9049439c28bc028dac5073350d3df8fbe/mypy-2.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:6fc0e98b95e31755ca06d89f75fafa7820fbb3ea2caace6d83cba17625cd0acb", size = 11329146, upload-time = "2026-07-08T01:35:38.318Z" }, - { url = "https://files.pythonhosted.org/packages/41/a5/558b06e6cfe17ab88bb38f7b370b6bc68a74ba177c9e138db9748e422d2d/mypy-2.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:bc73a5b4d40e8a3e6b12ef82eb0c90430964e34016a36c2aff4e3bfe37ba41f0", size = 10316586, upload-time = "2026-07-08T01:36:25.458Z" }, - { url = "https://files.pythonhosted.org/packages/0b/21/f0b96f19a9b8ba111a45ffbe9508e818b7f6990469b38f6888943f7bfd3a/mypy-2.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:6257bd4b4c0ae2148548b869a1ff3758e38645b92c8fe65eca401866c3c551c1", size = 15922565, upload-time = "2026-07-08T01:35:56.282Z" }, - { url = "https://files.pythonhosted.org/packages/18/f2/1dbcb20b0865d5e992541450a8c73f2fcc90f8bd7d8a4b81313e16934870/mypy-2.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:dfa22b3ae862ac1ce76f5976ddd402651b5f090bcfd49c6d0484b8983a29eaf8", size = 14816515, upload-time = "2026-07-08T01:34:58.167Z" }, - { url = "https://files.pythonhosted.org/packages/84/a2/18cce9c7d5b4d14010d1f13836da11b234dda917b17ca8671fc32c136997/mypy-2.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30a430bf26fe8cf372f3933fbd83e633d6561868803645a20e4e6d4523f52a3b", size = 15272246, upload-time = "2026-07-08T01:37:08.72Z" }, - { url = "https://files.pythonhosted.org/packages/ce/71/24d720c7924829bd675cbde2d0fa779f50abf676ca617f53d6a8bfef5fa7/mypy-2.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d58655a60e823b1a4c9ebcda072897fb0193c2f3e6f8e7c433e152aa4cb00233", size = 16226295, upload-time = "2026-07-08T01:34:51.861Z" }, - { url = "https://files.pythonhosted.org/packages/b7/5e/785730990fc863ad8340b4ab44ac4ca23270aecff92c180ccdf27f9f5869/mypy-2.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d4452c955caf14e28bb046cbd0c3671272e6381630a8b81b0da9713558148890", size = 16493275, upload-time = "2026-07-08T01:35:09.337Z" }, - { url = "https://files.pythonhosted.org/packages/93/33/55b1edf16f639f153972380d6977b81f65509c5b8f9c86b58b94b7990b03/mypy-2.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:68f5b7f7f755200f68c7181e3dfb28be9858162257690e539759c9f57721e388", size = 11749038, upload-time = "2026-07-08T01:35:50.071Z" }, - { url = "https://files.pythonhosted.org/packages/61/36/67424748a4e65e97f0e05bf00df379dfb6c2d817f82cc3a4ce5c96d99beb/mypy-2.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:78d201accfafce3801d978f2b8dbbd473a9ce364cc0a0dfd9192fe47d977e129", size = 10704254, upload-time = "2026-07-08T01:37:17.971Z" }, - { url = "https://files.pythonhosted.org/packages/28/cb/142c2097ca02c0d295b00625ff946808bdda65acda17d163c680d8a6a474/mypy-2.2.0-py3-none-any.whl", hash = "sha256:ecc138da861e932d1344214da4bae866b21900a9c2778824b51fe2fb47f5180e", size = 2726094, upload-time = "2026-07-08T01:34:00.075Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/12/af/4e516a05d3ca2eb9283e9ec45b2c02225c1514dd6da49fd3c9eaa6639370/mypy-2.3.0.tar.gz", hash = "sha256:465965d41cd9a2726694e983e8ce7113259327bec798115d1e1dfa2a52fb666e", size = 3988104, upload-time = "2026-07-13T11:34:53.387Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/09/f2f5f45dae0c9a0891e4751a73312730e009395102e5d72a22a976cca41f/mypy-2.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1fa8d916ac3b705af733c4c1e6c9ebe38fd0d52beb15b105c3e8355b55e6ecdc", size = 14927774, upload-time = "2026-07-13T11:28:38.224Z" }, + { url = "https://files.pythonhosted.org/packages/56/b9/345367effd3a6877275a94d481614bfca983f45e028c6290e2cc54603811/mypy-2.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:28e1e2af8cd8fff551fd30f2fe4b03fb76764ac8b1ba6c6a1bd00ad32b412db3", size = 14000127, upload-time = "2026-07-13T11:30:19.57Z" }, + { url = "https://files.pythonhosted.org/packages/99/6c/a10b7a7b9f0a755fb94e27ae834d4cea9ad6c5221f9325eef8f182641feb/mypy-2.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3e77244df3843048c3f927182916730e40c124cbaa43905c1fb86cb382aa0805", size = 14229437, upload-time = "2026-07-13T11:28:17.765Z" }, + { url = "https://files.pythonhosted.org/packages/d9/bd/a26a602acb1bbf849fa4bdac4bc657ee2f11c0c2a764a2cc87a5304e865c/mypy-2.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9559ab18a9c9957dfa3004ab57cd4bac5f26a724329a9584e583367f0c2e1117", size = 15171457, upload-time = "2026-07-13T11:29:01.834Z" }, + { url = "https://files.pythonhosted.org/packages/7f/14/124f462bef69bcbc90b9358088460b6091954a3e004852fcd9948db617a5/mypy-2.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:09abd66d8685e73f8f7d17b847c3e104d9a7b164a8706ea87d6c96a3d45816d5", size = 15478281, upload-time = "2026-07-13T11:32:23.413Z" }, + { url = "https://files.pythonhosted.org/packages/db/a4/8bdca6a8ac8d856d82ed049144af2721245a135c2e8001d3890c93975852/mypy-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e91adad1ca81742ac7ef9893959911df867752206b37135185e88dfb3c89494", size = 11148008, upload-time = "2026-07-13T11:34:17.332Z" }, + { url = "https://files.pythonhosted.org/packages/83/41/490eea348e60ba50decec20bc750605444149a5d7a8cc560042f90ba2c75/mypy-2.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:6f99ec626e3c3a2f7c0b22c5b90ddb5dabb1c18729c971e9bdaca1f1766d2cee", size = 10142329, upload-time = "2026-07-13T11:32:52.116Z" }, + { url = "https://files.pythonhosted.org/packages/e6/b9/d75b3082b05f1b3028828aeb18e74ae5ab0a0936051bbf1f32f59f654747/mypy-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3419d00717afbc5265b50dd14b1278f29ea4884dd398ab67873489ac093fd329", size = 14838725, upload-time = "2026-07-13T11:32:44.655Z" }, + { url = "https://files.pythonhosted.org/packages/a9/50/79a65c6ea6e115bc73296038a4543b2d5c91f07912b918a2c616a2514bba/mypy-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cfca8ee88544090f86b6dcce05ec55d66eb48a762412ac2507810ba4bd793b6f", size = 13911128, upload-time = "2026-07-13T11:32:02.021Z" }, + { url = "https://files.pythonhosted.org/packages/90/48/e11ed7716c26953ca321f726e452e374dbf81a6f2b8b212ec02af29b6b8f/mypy-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:75cbb4b9ef04a0c84a957f07abc4504fbf64b8dcc145675101f2d3a78a4b1d6a", size = 14146742, upload-time = "2026-07-13T11:33:03.313Z" }, + { url = "https://files.pythonhosted.org/packages/06/72/6807565b1c4861ef66f7fdd98b51c61556356eab80235717b46c53bb8627/mypy-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:982e3d53dd23d0a4cef67dd66791fdbede0cf38f9eb617bf47663554c51e1e36", size = 15081418, upload-time = "2026-07-13T11:31:13.899Z" }, + { url = "https://files.pythonhosted.org/packages/00/80/1ea14c5d80e589e415973db3e47c78c2219a305b808b2b506395342c1d79/mypy-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85c5385b93012ffa3b31479ab579aef5415f4f3a32c6cf1ae07a984d2a0ff461", size = 15328164, upload-time = "2026-07-13T11:31:35.723Z" }, + { url = "https://files.pythonhosted.org/packages/37/28/8223157404a3d51920078459c37f80fbdc590e1d8ea049dc5ce48643022a/mypy-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:13b1b16e2fa39f3b2e33fb1c468abc7a69369fa2e886b4b87b5afc81472325cd", size = 11136472, upload-time = "2026-07-13T11:27:37.018Z" }, + { url = "https://files.pythonhosted.org/packages/6f/cc/ea27e5959c5f258585a756b252031f3b313583d81b5064b2bebc41d3706b/mypy-2.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:b5cd2f027a972a4a5f2278a11fac9747f5f81a53a30b714d74950b6807e55568", size = 10135800, upload-time = "2026-07-13T11:30:08.92Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/0e7e592619e2133596a47cdd642534b0456545c218430bd3b9d8fefdd1b1/mypy-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d53fc67b9d28a43c6199077f49fea0f05839e36cf6158500331c9549225e5a5", size = 15026523, upload-time = "2026-07-13T11:34:49.206Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/1e1731df090a857df2807177a4626863e5ac0f0256513c35780efe53986f/mypy-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fbc00cee7bdbb9291979ddc9d08034a29dfcda4932628c9bbc28c1edd589df0c", size = 14032189, upload-time = "2026-07-13T11:33:57.168Z" }, + { url = "https://files.pythonhosted.org/packages/44/95/cab921f4a806e171f34113e6181dd23c55358ccf6a80741269ef594a410e/mypy-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:04e617030eca5221909c8b7d8d7fd1c637948199aa2100b2ad9813feb07e1491", size = 14198696, upload-time = "2026-07-13T11:32:12.767Z" }, + { url = "https://files.pythonhosted.org/packages/66/80/e6d008bb19fe446e3662d85e0e2717bf9f2d611a2164fb29d6e067dbf46c/mypy-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56c184d2c20ca6b6378d58d1960270a767f41f5e44acbbd27f05effef4f4e1d7", size = 15286904, upload-time = "2026-07-13T11:34:27.594Z" }, + { url = "https://files.pythonhosted.org/packages/db/83/94397c9293608a364aa03e8084fb34ede4ae976a260384b9b52929308135/mypy-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3961a4a34b05f7c74b0f05aa51fbfe99a2d1e126038df40318d15c8f558b7ef3", size = 15528342, upload-time = "2026-07-13T11:34:07.819Z" }, + { url = "https://files.pythonhosted.org/packages/cf/96/d8b37d819adec6cfccfb1fd3afc1735d94717ddeafb45536db9c6943e09b/mypy-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b1942b9314d4c784b8ea1dbab4972603290e5dd5630f06675f13aec97526bc4c", size = 11218346, upload-time = "2026-07-13T11:28:27.745Z" }, + { url = "https://files.pythonhosted.org/packages/2b/cd/cd9f725b19b19e5b530a154cf9bcf9e94279c5d55b3c34fb42b3aa48ea1b/mypy-2.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:be51653d7669d7d7955d613b8d0bb57d5b652eaf71a873ddf65ac87254dd2595", size = 10204525, upload-time = "2026-07-13T11:31:02.552Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ae/f7d056eb0294586a572d0d0d89580ec633c064db520f11d37d5a2fb833bd/mypy-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:91ad22a52ae2c7e621c2f67c94d5a17f66b3209a4cff5cf8a573579835c69e97", size = 14947298, upload-time = "2026-07-13T11:27:47.734Z" }, + { url = "https://files.pythonhosted.org/packages/32/d5/db3e7af01e7844d21662c6ddc1f7825ec7cb4053f0391ac02faf3638396f/mypy-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:99ac767cc5d3b64c8d0ae226ead10c96694f94e4e7da1668642225dcd4e75aac", size = 13950768, upload-time = "2026-07-13T11:27:57.726Z" }, + { url = "https://files.pythonhosted.org/packages/d9/fb/43c031f0190513d1ec248ed037eceb742ddd2a4d74bbf406658a28173837/mypy-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de6d2c484742a4d7b0ed6d07b143375624d3b899c5749c7b3c947f56261f48a6", size = 14151586, upload-time = "2026-07-13T11:29:18.615Z" }, + { url = "https://files.pythonhosted.org/packages/ec/c3/f8b2ffc60883084da91be51af58e88a7ffd4ff9795acb7d902ff88d31eb1/mypy-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7da939dd335cfd2ad788bdfd081c9f4e47634ab995e5a45eb15fd1e5bc052f8b", size = 15227411, upload-time = "2026-07-13T11:30:29.904Z" }, + { url = "https://files.pythonhosted.org/packages/83/2e/16b917fc7adcf03f1aadddfc93aab804ffb234b1ab09c0ffd6d92a5d34a2/mypy-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7247eb2824f996722a949530183394921ca71deb9680052a338cf53cff7925c2", size = 15478790, upload-time = "2026-07-13T11:33:14.686Z" }, + { url = "https://files.pythonhosted.org/packages/c0/88/aaa65a93c73d0cdae7e42f8adb302bf6885bb281302084f99d0290a35347/mypy-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:75b0984bb3cbd76bb5c9291a8671f7ae66ca3b51c7584c358fc2e923259f0757", size = 11234919, upload-time = "2026-07-13T11:33:39.28Z" }, + { url = "https://files.pythonhosted.org/packages/35/19/b40de63f1a80e63bc2d40f0679a6a8dbd34e95176c8122119bdf406aa552/mypy-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:d78fcf900b59cb7e82cb7e3a235e31b462d9333d92285bd1e4952d355b8ffba1", size = 10201510, upload-time = "2026-07-13T11:31:52.619Z" }, + { url = "https://files.pythonhosted.org/packages/a4/58/fa0ae047da911f540284009b4f44b96fe09d83c076d7c103e9d645f46303/mypy-2.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ea317b060ce83e26050f8f9e4d7d6bf44ed7597c8ff9990bccffbb9d1d8522db", size = 14941909, upload-time = "2026-07-13T11:32:34.332Z" }, + { url = "https://files.pythonhosted.org/packages/15/14/2ba1d61452d7c2a7fe12741e8d374e52b183476b07aa7f9e2a0d02b0720a/mypy-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:094af99f92638aa92852326188b85a89e50f4a472f44827c03362228482f0762", size = 13967581, upload-time = "2026-07-13T11:30:00.587Z" }, + { url = "https://files.pythonhosted.org/packages/ed/5a/483fb9e5ffbbb1a28dccc7b0a13d141b17ac769b6c9f488c0a0c63698962/mypy-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de121747278144fc9ae7caa2e978cf5df12aebc82933182f5b3b86081a30baef", size = 14168807, upload-time = "2026-07-13T11:28:48.6Z" }, + { url = "https://files.pythonhosted.org/packages/ae/77/70d7a10732063beb74ad713682cf871e88f5c5fa39bfc8beff8a524bf9cb/mypy-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37fa4de896a84e2dc9200d91e614c22563b43d1a266789d4bbac7b22ebe6192b", size = 15200144, upload-time = "2026-07-13T11:31:25.283Z" }, + { url = "https://files.pythonhosted.org/packages/56/72/766218ac783be4fdfcd699b90037b63017348a3e86fb2c1fbfb18302637d/mypy-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f1b3a98dfd21058bc759bb3337d5d1f61d0fdf9f3cf9c00f4291790fb5427bff", size = 15460389, upload-time = "2026-07-13T11:29:29.077Z" }, + { url = "https://files.pythonhosted.org/packages/38/4e/8a9db7411ecb8ec0cb1fd05dba432f28bafffcd38b4e887714a4a0506689/mypy-2.3.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:944c665d984157cb96a679dfb7a4a81dd1d36b24b9c284b699514e6e626b82d4", size = 7753664, upload-time = "2026-07-13T11:29:08.147Z" }, + { url = "https://files.pythonhosted.org/packages/65/4c/c3f8bfd6ed0e5e38b5a244403b27f821d433443df5a15a278417c10a3a3c/mypy-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:4359424140d985192c778c1ce2c114a10c1ca58a381ed79cfa70d37df94b299f", size = 11417237, upload-time = "2026-07-13T11:33:47.467Z" }, + { url = "https://files.pythonhosted.org/packages/3c/00/89a32eaf5ccf174bc4f90db0eaea5d70636c01b8d49f384bdab2e8834390/mypy-2.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:3dd0bed92c4bdec57c42505b96416fb9e6a5aa7be84d2809bcd5f2ecec2860d7", size = 10389252, upload-time = "2026-07-13T11:31:43.81Z" }, + { url = "https://files.pythonhosted.org/packages/31/56/104f93d69aa9f339b6b9d3b0a7faa699b8b466c942cf3ae86cc2a2ec0915/mypy-2.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:691fdc37132b1ae628d834f672e74de83462d9fb4aff621835767fb43a8dd373", size = 16385495, upload-time = "2026-07-13T11:29:49.818Z" }, + { url = "https://files.pythonhosted.org/packages/d2/03/f1d2123313f55efafdd27706960f43a771c62f1b68426c76043f3ab9ebf3/mypy-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:aec15d465d477558fd842757b487849007311cf3897849cdda0e3162ac0ac556", size = 15098155, upload-time = "2026-07-13T11:30:40.301Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5d/d5f9200399b445e81726c4f23becee33f233aee81c72680b1ef3a258b641/mypy-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b352b7e49f5e6576009e8df730e1ff4f915cb565b851b396d2ffe2f5a6f5da88", size = 15514155, upload-time = "2026-07-13T11:34:38.569Z" }, + { url = "https://files.pythonhosted.org/packages/cd/ce/69977c555f08faa3190cfde44189b89dbd56861b1ab97aa18fc5f3a2e4a3/mypy-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c6c6bf687b17f90dbfcad95b960d32eaa0154c00da45f03ab50bf8952e047fe", size = 16766351, upload-time = "2026-07-13T11:33:29.195Z" }, + { url = "https://files.pythonhosted.org/packages/bc/92/6648b6caa3ab9e00f9ac0c2a78307805f873dd48139b24a6f6f7c3667bbf/mypy-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f4ed18f111bfe2d599bca7468e7f9251042c1c2118f762c8de2766a56d773c60", size = 17043490, upload-time = "2026-07-13T11:30:53.927Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ab/0dc91d80f3f016634c68d451f294a97320fe903a9b6f90b9e57b3f7f1717/mypy-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0b025a93cffb9781d231f232be07a17912f35f10a313c24f301c81e842870654", size = 12146869, upload-time = "2026-07-13T11:29:38.874Z" }, + { url = "https://files.pythonhosted.org/packages/85/b5/4c964d02634ba81f4d1c84838e5c5b18ab06d13ed568960f5d6318495ccc/mypy-2.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:adebc76aab4f3495a88b41d48aa4aff0c03f2822501da76625afcca5975f19e5", size = 10965113, upload-time = "2026-07-13T11:28:07.056Z" }, + { url = "https://files.pythonhosted.org/packages/2c/fa/fdc54fe583ba3cafbcedfb70eeeaf03849f75b1827a07096c7bd996f582d/mypy-2.3.0-py3-none-any.whl", hash = "sha256:6b1cdb579446b60432432b2b2403a6201b4b475a004d7f488511c9ba177c9e88", size = 2753292, upload-time = "2026-07-13T11:33:18.48Z" }, ] [[package]] @@ -1598,7 +1713,7 @@ wheels = [ [[package]] name = "myst-parser" -version = "5.0.0" +version = "5.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15'", @@ -1608,15 +1723,15 @@ resolution-markers = [ dependencies = [ { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } }, { name = "jinja2" }, - { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" } }, + { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" } }, { name = "mdit-py-plugins" }, { name = "pyyaml" }, { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/33/fa/7b45eef11b7971f0beb29d27b7bfe0d747d063aa29e170d9edd004733c8a/myst_parser-5.0.0.tar.gz", hash = "sha256:f6f231452c56e8baa662cc352c548158f6a16fcbd6e3800fc594978002b94f3a", size = 98535, upload-time = "2026-01-15T09:08:18.036Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/dc/603751677fff302f34396e206b610f556a59d7fe58b9a2145f54e96b48e8/myst_parser-5.1.0.tar.gz", hash = "sha256:ab69322dc6719dcc7f296479dbb70181b66df6ed315064f92dbc85c0e1bf2f02", size = 101182, upload-time = "2026-05-13T09:38:19.361Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/ac/686789b9145413f1a61878c407210e41bfdb097976864e0913078b24098c/myst_parser-5.0.0-py3-none-any.whl", hash = "sha256:ab31e516024918296e169139072b81592336f2fef55b8986aa31c9f04b5f7211", size = 84533, upload-time = "2026-01-15T09:08:16.788Z" }, + { url = "https://files.pythonhosted.org/packages/09/dc/f3dfb7488b770f3f67e6545085bf2abea5172e88f57b8ad25ef860ca704c/myst_parser-5.1.0-py3-none-any.whl", hash = "sha256:9c91c52b3cdb4d94a6506e4fab4e2f296c7623a0da0dcbe6de1565c3dad67a8a", size = 85817, upload-time = "2026-05-13T09:38:17.904Z" }, ] [[package]] @@ -1657,7 +1772,7 @@ dependencies = [ dev = [ { name = "mypy" }, { name = "myst-parser", version = "4.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "myst-parser", version = "5.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "myst-parser", version = "5.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-clarity" }, @@ -1710,7 +1825,7 @@ requires-dist = [ { name = "ruamel-yaml" }, { name = "setuptools", specifier = "<81" }, { name = "tabulate" }, - { name = "textual", specifier = "==8.2.4" }, + { name = "textual", specifier = "==8.2.7" }, { name = "trogon" }, ] @@ -1808,86 +1923,139 @@ wheels = [ [[package]] name = "numpy" -version = "2.4.4" +version = "2.4.6" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version == '3.11.*'", +] +sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/49/ec46835a70be8fa6446c495126ac84fdb28cb2558e1620ffb87a10c8b64c/numpy-2.4.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0280e0356c0829a18d9de1cb7eee50ec22ca639878d7240307ca0943d73cd2c4", size = 16969194, upload-time = "2026-05-18T23:33:13.503Z" }, + { url = "https://files.pythonhosted.org/packages/0e/0d/f5957185c0ee2f3e12f78715aa9e3b353fd83633316c8532b38faa37e3f6/numpy-2.4.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:110f8b71aacb688ec69062bb7f6938a0f8acb01b7c1c4beb453c65b6d234584d", size = 14964111, upload-time = "2026-05-18T23:33:17.795Z" }, + { url = "https://files.pythonhosted.org/packages/ad/40/40a40ee0ddf7ceb782c49af278894b686e586d65d8c1889c8b5da01a3d7d/numpy-2.4.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:4cfe66903cc32a9921a6733d96b19bb6abf310397581bbad89c228f5abaf0ee8", size = 5469159, upload-time = "2026-05-18T23:33:20.654Z" }, + { url = "https://files.pythonhosted.org/packages/63/13/f9a8046535cb21deae82f8d03de9617e08882d274fad2539630761888228/numpy-2.4.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8155154c7c691289fe18f510b5d4657c68c67989f293f0535a91360392ff6538", size = 6798936, upload-time = "2026-05-18T23:33:22.987Z" }, + { url = "https://files.pythonhosted.org/packages/33/a8/6fa8c1a345a8c85dbb21932c447bee07c30a2c2a3f31e369c0a84b300147/numpy-2.4.6-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ab0a9c4ffb1a6d95ef519fe4247dba8eb6b18ad93999f76b7f657039acabd47", size = 15966692, upload-time = "2026-05-18T23:33:26.62Z" }, + { url = "https://files.pythonhosted.org/packages/02/03/74fe2a4cb3817d94d86402f2506554130a2f01414e299b5a843e5a8a957f/numpy-2.4.6-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89cd468399cfd2504718f0ba50e410dca55a170b61a02ad92bb18c8a65186e93", size = 16918164, upload-time = "2026-05-18T23:33:29.955Z" }, + { url = "https://files.pythonhosted.org/packages/c5/80/3615be3313f7e7696609bc194b9f0101da809df79e859bdb84e0cd043f46/numpy-2.4.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2d37ab77531417474168eb79d6d80b14f821a966818505d03013d0833edb7a8", size = 17322877, upload-time = "2026-05-18T23:33:34.724Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ac/a691e0fe2675e370d0e08ff905adc49a1c8830e8cae03efe4477e92cd55d/numpy-2.4.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f407cb6b8e9d6d8c626bc73c945db1706035af8fd632295547bf1c9e46d092d6", size = 18651487, upload-time = "2026-05-18T23:33:38.217Z" }, + { url = "https://files.pythonhosted.org/packages/15/a7/9bc1cd626d7bf6869bfedf27b91b6ab5dd607758bf8e959d6fa80c6a59cb/numpy-2.4.6-cp311-cp311-win32.whl", hash = "sha256:ddea102b48f9e339f3948bf22040944184627a30fdf7f858667673b9c5f033c8", size = 6233945, upload-time = "2026-05-18T23:33:41.331Z" }, + { url = "https://files.pythonhosted.org/packages/c5/31/7fc6239c12bce7e931463251cca4426c465e1876ba3cc785402ef4dd8f4e/numpy-2.4.6-cp311-cp311-win_amd64.whl", hash = "sha256:1e254a00cdf42b1e4d5b3d68d33af63268d41340d8885df2ab6470f2e1500147", size = 12608406, upload-time = "2026-05-18T23:33:44.131Z" }, + { url = "https://files.pythonhosted.org/packages/27/83/140f85a466595a16382996a1bf06b2b54bcd597488921b0c9daaeeda72af/numpy-2.4.6-cp311-cp311-win_arm64.whl", hash = "sha256:ed9749eef4cbd126da3dc1d6bcb3a57f5eb7ac6a6484146bdbf743f552dfc577", size = 10479528, upload-time = "2026-05-18T23:33:50.725Z" }, + { url = "https://files.pythonhosted.org/packages/95/2a/3d7b5ac8aac24feaf9ad7ed58f45b0bbc06d37e4338ae84c9f2298b570f9/numpy-2.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", size = 16689119, upload-time = "2026-05-18T23:33:54.065Z" }, + { url = "https://files.pythonhosted.org/packages/ea/12/92c4c131527599e8288d6918e888d88726f84d805d784b771f32408aeaef/numpy-2.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb", size = 14699246, upload-time = "2026-05-18T23:33:57.621Z" }, + { url = "https://files.pythonhosted.org/packages/ad/fe/c0a6b7b2ca128a8fb228575147073b660656734b8ebe4d76c8fd748dcc79/numpy-2.4.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", size = 5204410, upload-time = "2026-05-18T23:34:00.302Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d4/9770d14ba719432bb90a421bfd443872ed0f70f7264b64bec12ea363d5fd/numpy-2.4.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", size = 6551240, upload-time = "2026-05-18T23:34:02.852Z" }, + { url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012, upload-time = "2026-05-18T23:34:05.485Z" }, + { url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538, upload-time = "2026-05-18T23:34:09.265Z" }, + { url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706, upload-time = "2026-05-18T23:34:13.053Z" }, + { url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541, upload-time = "2026-05-18T23:34:17.024Z" }, + { url = "https://files.pythonhosted.org/packages/f6/81/e1b27545deedce7f4a0b348618c6b62d74e36a4dc9ccd42f3eb2f85eee32/numpy-2.4.6-cp312-cp312-win32.whl", hash = "sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45", size = 5962825, upload-time = "2026-05-18T23:34:20.3Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751", size = 12321687, upload-time = "2026-05-18T23:34:23.095Z" }, + { url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482, upload-time = "2026-05-18T23:34:25.876Z" }, + { url = "https://files.pythonhosted.org/packages/fb/82/bdab26d7438c6791ca31b7c024ca37c1eab8b726ba236129005cd4a06e45/numpy-2.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", size = 16684648, upload-time = "2026-05-18T23:34:29.41Z" }, + { url = "https://files.pythonhosted.org/packages/1b/30/a80189bcc7f5e4258b3fbc3968d909d1756f54d023299ecc39ad6fdb9ef8/numpy-2.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", size = 14693902, upload-time = "2026-05-18T23:34:33.013Z" }, + { url = "https://files.pythonhosted.org/packages/97/12/70b5d0d7c15e1ebb8a6a84a8caa1d19e181d84fb58bb6d70aca29099dec1/numpy-2.4.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", size = 5198992, upload-time = "2026-05-18T23:34:36.132Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/ebd2a8f8a83541f8d38cc5667e8c2b69cecfd30da6e45693e8158857d44b/numpy-2.4.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", size = 6546944, upload-time = "2026-05-18T23:34:38.484Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392, upload-time = "2026-05-18T23:34:41.257Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220, upload-time = "2026-05-18T23:34:45.075Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800, upload-time = "2026-05-18T23:34:49.065Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600, upload-time = "2026-05-18T23:34:52.709Z" }, + { url = "https://files.pythonhosted.org/packages/f7/da/2ccc6c2fe8898dee01d90c75c5f5f914a23daf99e3e0f59516a08760c8b5/numpy-2.4.6-cp313-cp313-win32.whl", hash = "sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", size = 5961134, upload-time = "2026-05-18T23:34:55.618Z" }, + { url = "https://files.pythonhosted.org/packages/b5/cd/9cc4dc876fb065d5c220aae4d5e14826b2715331bb7618ce1fb07a679d99/numpy-2.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", size = 12318598, upload-time = "2026-05-18T23:34:58.928Z" }, + { url = "https://files.pythonhosted.org/packages/39/1e/c0bcba1f8694116485fe28fd1be698c278fcda4141c5b0e53a2aed8b12a8/numpy-2.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", size = 10222272, upload-time = "2026-05-18T23:35:02.167Z" }, + { url = "https://files.pythonhosted.org/packages/63/6d/cc5619247c8f4204e507f5883528372e4ac4bb189e579fb859a12e480b1f/numpy-2.4.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", size = 14821197, upload-time = "2026-05-18T23:35:05.468Z" }, + { url = "https://files.pythonhosted.org/packages/00/58/f1c39161c87d9e9bed660f1ed4bafc0e403d5ec9650b6dd77aead07d489b/numpy-2.4.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe", size = 5326287, upload-time = "2026-05-18T23:35:08.693Z" }, + { url = "https://files.pythonhosted.org/packages/af/57/3917ab0fd97f271a8694513581b8a36c655f111c446852c302f04ccdb6fc/numpy-2.4.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", size = 6646763, upload-time = "2026-05-18T23:35:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070, upload-time = "2026-05-18T23:35:14.79Z" }, + { url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752, upload-time = "2026-05-18T23:35:18.836Z" }, + { url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024, upload-time = "2026-05-18T23:35:22.52Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398, upload-time = "2026-05-18T23:35:26.398Z" }, + { url = "https://files.pythonhosted.org/packages/8a/90/0ac3bc947217e66dec77e7cbc6a1979d1af70b6461b82f620d3bccd5e4c8/numpy-2.4.6-cp313-cp313t-win32.whl", hash = "sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", size = 6084971, upload-time = "2026-05-18T23:35:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/77/71/5673e351671a1d2bd6063b91b44f70c0affea7d1516fa7a6572941ba4aa1/numpy-2.4.6-cp313-cp313t-win_amd64.whl", hash = "sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", size = 12458532, upload-time = "2026-05-18T23:35:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/3f/88/19d3503c5046e688f049274b27a3ef3d771152fa80d3ba3d01a3dff61abe/numpy-2.4.6-cp313-cp313t-win_arm64.whl", hash = "sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", size = 10291881, upload-time = "2026-05-18T23:35:35.465Z" }, + { url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458, upload-time = "2026-05-18T23:35:38.353Z" }, + { url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559, upload-time = "2026-05-18T23:35:42.14Z" }, + { url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716, upload-time = "2026-05-18T23:35:45.377Z" }, + { url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947, upload-time = "2026-05-18T23:35:47.926Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" }, + { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" }, + { url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" }, + { url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" }, + { url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672, upload-time = "2026-05-18T23:36:16.473Z" }, + { url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731, upload-time = "2026-05-18T23:36:19.767Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805, upload-time = "2026-05-18T23:36:22.266Z" }, + { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" }, + { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" }, + { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" }, + { url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" }, + { url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" }, + { url = "https://files.pythonhosted.org/packages/de/12/b422cc84439adc0d00de605bf4a308890ae5c26f2c71fbd73e5d08fbb0dd/numpy-2.4.6-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:55cced7c52e981362f708ad635198e97a752dfba412cc03c23bbf3bd8d5cd662", size = 16847511, upload-time = "2026-05-18T23:36:50.673Z" }, + { url = "https://files.pythonhosted.org/packages/44/53/f481bef68011740f8849418d82db07230e825013f31f4eef5ba5b805316a/numpy-2.4.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d6da64deb6b8ed903e7560180a92f2d804ee1ba5eeb849ac2748b8c1aba1f6d7", size = 14889064, upload-time = "2026-05-18T23:36:53.879Z" }, + { url = "https://files.pythonhosted.org/packages/7f/57/42ed575c10ced8af951d426bc4e1f8aff16fd851db33f067036215a7f860/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:68a5124b13fa6cc2086764a20005d30bc0548146f7f5322f02fce212ca14317f", size = 5394157, upload-time = "2026-05-18T23:36:57.194Z" }, + { url = "https://files.pythonhosted.org/packages/6a/ef/f66cc724fcc36c1e364c67f51ae9146090b8b584f27d58b97fdae3edd737/numpy-2.4.6-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:948424b06129ce883307e8cff868c31396d8dc7630a59c61d70d98dbe70f222c", size = 6708728, upload-time = "2026-05-18T23:36:59.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/9c/c531f2293b91265d8b48e9b329f54fdd7ffae73cb4134ea10cca4237e9cc/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbbdb29840ca3d91ee0fece42fc29278886d908280bfec0a5846c6f901a3eb0", size = 15798374, upload-time = "2026-05-18T23:37:02.674Z" }, + { url = "https://files.pythonhosted.org/packages/1a/b0/413077f6b1153ed3cba361401c6783bbad6114804a000cc22eb71c13e190/numpy-2.4.6-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ad03c0965fb3c692200e74d458ca28c1dbb4ce96f9a479a8aa041ad5fabca02", size = 16747286, upload-time = "2026-05-18T23:37:06.327Z" }, + { url = "https://files.pythonhosted.org/packages/15/ce/e5ec180bc41812edcd8daeb8639d205622c0e8c02259d8ab25a0201b3c2a/numpy-2.4.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73", size = 12504263, upload-time = "2026-05-18T23:37:09.715Z" }, +] + +[[package]] +name = "numpy" +version = "2.5.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ "python_full_version >= '3.15'", "python_full_version >= '3.12' and python_full_version < '3.15'", - "python_full_version == '3.11.*'", ] -sdist = { url = "https://files.pythonhosted.org/packages/d7/9f/b8cef5bffa569759033adda9481211426f12f53299629b410340795c2514/numpy-2.4.4.tar.gz", hash = "sha256:2d390634c5182175533585cc89f3608a4682ccb173cc9bb940b2881c8d6f8fa0", size = 20731587, upload-time = "2026-03-29T13:22:01.298Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/c6/4218570d8c8ecc9704b5157a3348e486e84ef4be0ed3e38218ab473c83d2/numpy-2.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f983334aea213c99992053ede6168500e5f086ce74fbc4acc3f2b00f5762e9db", size = 16976799, upload-time = "2026-03-29T13:18:15.438Z" }, - { url = "https://files.pythonhosted.org/packages/dd/92/b4d922c4a5f5dab9ed44e6153908a5c665b71acf183a83b93b690996e39b/numpy-2.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:72944b19f2324114e9dc86a159787333b77874143efcf89a5167ef83cfee8af0", size = 14971552, upload-time = "2026-03-29T13:18:18.606Z" }, - { url = "https://files.pythonhosted.org/packages/8a/dc/df98c095978fa6ee7b9a9387d1d58cbb3d232d0e69ad169a4ce784bde4fd/numpy-2.4.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:86b6f55f5a352b48d7fbfd2dbc3d5b780b2d79f4d3c121f33eb6efb22e9a2015", size = 5476566, upload-time = "2026-03-29T13:18:21.532Z" }, - { url = "https://files.pythonhosted.org/packages/28/34/b3fdcec6e725409223dd27356bdf5a3c2cc2282e428218ecc9cb7acc9763/numpy-2.4.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:ba1f4fc670ed79f876f70082eff4f9583c15fb9a4b89d6188412de4d18ae2f40", size = 6806482, upload-time = "2026-03-29T13:18:23.634Z" }, - { url = "https://files.pythonhosted.org/packages/68/62/63417c13aa35d57bee1337c67446761dc25ea6543130cf868eace6e8157b/numpy-2.4.4-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a87ec22c87be071b6bdbd27920b129b94f2fc964358ce38f3822635a3e2e03d", size = 15973376, upload-time = "2026-03-29T13:18:26.677Z" }, - { url = "https://files.pythonhosted.org/packages/cf/c5/9fcb7e0e69cef59cf10c746b84f7d58b08bc66a6b7d459783c5a4f6101a6/numpy-2.4.4-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df3775294accfdd75f32c74ae39fcba920c9a378a2fc18a12b6820aa8c1fb502", size = 16925137, upload-time = "2026-03-29T13:18:30.14Z" }, - { url = "https://files.pythonhosted.org/packages/7e/43/80020edacb3f84b9efdd1591120a4296462c23fd8db0dde1666f6ef66f13/numpy-2.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d4e437e295f18ec29bc79daf55e8a47a9113df44d66f702f02a293d93a2d6dd", size = 17329414, upload-time = "2026-03-29T13:18:33.733Z" }, - { url = "https://files.pythonhosted.org/packages/fd/06/af0658593b18a5f73532d377188b964f239eb0894e664a6c12f484472f97/numpy-2.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6aa3236c78803afbcb255045fbef97a9e25a1f6c9888357d205ddc42f4d6eba5", size = 18658397, upload-time = "2026-03-29T13:18:37.511Z" }, - { url = "https://files.pythonhosted.org/packages/e6/ce/13a09ed65f5d0ce5c7dd0669250374c6e379910f97af2c08c57b0608eee4/numpy-2.4.4-cp311-cp311-win32.whl", hash = "sha256:30caa73029a225b2d40d9fae193e008e24b2026b7ee1a867b7ee8d96ca1a448e", size = 6239499, upload-time = "2026-03-29T13:18:40.372Z" }, - { url = "https://files.pythonhosted.org/packages/bd/63/05d193dbb4b5eec1eca73822d80da98b511f8328ad4ae3ca4caf0f4db91d/numpy-2.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:6bbe4eb67390b0a0265a2c25458f6b90a409d5d069f1041e6aff1e27e3d9a79e", size = 12614257, upload-time = "2026-03-29T13:18:42.95Z" }, - { url = "https://files.pythonhosted.org/packages/87/c5/8168052f080c26fa984c413305012be54741c9d0d74abd7fbeeccae3889f/numpy-2.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:fcfe2045fd2e8f3cb0ce9d4ba6dba6333b8fa05bb8a4939c908cd43322d14c7e", size = 10486775, upload-time = "2026-03-29T13:18:45.835Z" }, - { url = "https://files.pythonhosted.org/packages/28/05/32396bec30fb2263770ee910142f49c1476d08e8ad41abf8403806b520ce/numpy-2.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:15716cfef24d3a9762e3acdf87e27f58dc823d1348f765bbea6bef8c639bfa1b", size = 16689272, upload-time = "2026-03-29T13:18:49.223Z" }, - { url = "https://files.pythonhosted.org/packages/c5/f3/a983d28637bfcd763a9c7aafdb6d5c0ebf3d487d1e1459ffdb57e2f01117/numpy-2.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23cbfd4c17357c81021f21540da84ee282b9c8fba38a03b7b9d09ba6b951421e", size = 14699573, upload-time = "2026-03-29T13:18:52.629Z" }, - { url = "https://files.pythonhosted.org/packages/9b/fd/e5ecca1e78c05106d98028114f5c00d3eddb41207686b2b7de3e477b0e22/numpy-2.4.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b3b60bb7cba2c8c81837661c488637eee696f59a877788a396d33150c35d842", size = 5204782, upload-time = "2026-03-29T13:18:55.579Z" }, - { url = "https://files.pythonhosted.org/packages/de/2f/702a4594413c1a8632092beae8aba00f1d67947389369b3777aed783fdca/numpy-2.4.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e4a010c27ff6f210ff4c6ef34394cd61470d01014439b192ec22552ee867f2a8", size = 6552038, upload-time = "2026-03-29T13:18:57.769Z" }, - { url = "https://files.pythonhosted.org/packages/7f/37/eed308a8f56cba4d1fdf467a4fc67ef4ff4bf1c888f5fc980481890104b1/numpy-2.4.4-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f9e75681b59ddaa5e659898085ae0eaea229d054f2ac0c7e563a62205a700121", size = 15670666, upload-time = "2026-03-29T13:19:00.341Z" }, - { url = "https://files.pythonhosted.org/packages/0a/0d/0e3ecece05b7a7e87ab9fb587855548da437a061326fff64a223b6dcb78a/numpy-2.4.4-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:81f4a14bee47aec54f883e0cad2d73986640c1590eb9bfaaba7ad17394481e6e", size = 16645480, upload-time = "2026-03-29T13:19:03.63Z" }, - { url = "https://files.pythonhosted.org/packages/34/49/f2312c154b82a286758ee2f1743336d50651f8b5195db18cdb63675ff649/numpy-2.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62d6b0f03b694173f9fcb1fb317f7222fd0b0b103e784c6549f5e53a27718c44", size = 17020036, upload-time = "2026-03-29T13:19:07.428Z" }, - { url = "https://files.pythonhosted.org/packages/7b/e9/736d17bd77f1b0ec4f9901aaec129c00d59f5d84d5e79bba540ef12c2330/numpy-2.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fbc356aae7adf9e6336d336b9c8111d390a05df88f1805573ebb0807bd06fd1d", size = 18368643, upload-time = "2026-03-29T13:19:10.775Z" }, - { url = "https://files.pythonhosted.org/packages/63/f6/d417977c5f519b17c8a5c3bc9e8304b0908b0e21136fe43bf628a1343914/numpy-2.4.4-cp312-cp312-win32.whl", hash = "sha256:0d35aea54ad1d420c812bfa0385c71cd7cc5bcf7c65fed95fc2cd02fe8c79827", size = 5961117, upload-time = "2026-03-29T13:19:13.464Z" }, - { url = "https://files.pythonhosted.org/packages/2d/5b/e1deebf88ff431b01b7406ca3583ab2bbb90972bbe1c568732e49c844f7e/numpy-2.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:b5f0362dc928a6ecd9db58868fca5e48485205e3855957bdedea308f8672ea4a", size = 12320584, upload-time = "2026-03-29T13:19:16.155Z" }, - { url = "https://files.pythonhosted.org/packages/58/89/e4e856ac82a68c3ed64486a544977d0e7bdd18b8da75b78a577ca31c4395/numpy-2.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:846300f379b5b12cc769334464656bc882e0735d27d9726568bc932fdc49d5ec", size = 10221450, upload-time = "2026-03-29T13:19:18.994Z" }, - { url = "https://files.pythonhosted.org/packages/14/1d/d0a583ce4fefcc3308806a749a536c201ed6b5ad6e1322e227ee4848979d/numpy-2.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:08f2e31ed5e6f04b118e49821397f12767934cfdd12a1ce86a058f91e004ee50", size = 16684933, upload-time = "2026-03-29T13:19:22.47Z" }, - { url = "https://files.pythonhosted.org/packages/c1/62/2b7a48fbb745d344742c0277f01286dead15f3f68e4f359fbfcf7b48f70f/numpy-2.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e823b8b6edc81e747526f70f71a9c0a07ac4e7ad13020aa736bb7c9d67196115", size = 14694532, upload-time = "2026-03-29T13:19:25.581Z" }, - { url = "https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af", size = 5199661, upload-time = "2026-03-29T13:19:28.31Z" }, - { url = "https://files.pythonhosted.org/packages/cd/da/464d551604320d1491bc345efed99b4b7034143a85787aab78d5691d5a0e/numpy-2.4.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d2a8490669bfe99a233298348acc2d824d496dee0e66e31b66a6022c2ad74a5c", size = 6547539, upload-time = "2026-03-29T13:19:30.97Z" }, - { url = "https://files.pythonhosted.org/packages/7d/90/8d23e3b0dafd024bf31bdec225b3bb5c2dbfa6912f8a53b8659f21216cbf/numpy-2.4.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45dbed2ab436a9e826e302fcdcbe9133f9b0006e5af7168afb8963a6520da103", size = 15668806, upload-time = "2026-03-29T13:19:33.887Z" }, - { url = "https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83", size = 16632682, upload-time = "2026-03-29T13:19:37.336Z" }, - { url = "https://files.pythonhosted.org/packages/34/fb/14570d65c3bde4e202a031210475ae9cde9b7686a2e7dc97ee67d2833b35/numpy-2.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:99d838547ace2c4aace6c4f76e879ddfe02bb58a80c1549928477862b7a6d6ed", size = 17019810, upload-time = "2026-03-29T13:19:40.963Z" }, - { url = "https://files.pythonhosted.org/packages/8a/77/2ba9d87081fd41f6d640c83f26fb7351e536b7ce6dd9061b6af5904e8e46/numpy-2.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0aec54fd785890ecca25a6003fd9a5aed47ad607bbac5cd64f836ad8666f4959", size = 18357394, upload-time = "2026-03-29T13:19:44.859Z" }, - { url = "https://files.pythonhosted.org/packages/a2/23/52666c9a41708b0853fa3b1a12c90da38c507a3074883823126d4e9d5b30/numpy-2.4.4-cp313-cp313-win32.whl", hash = "sha256:07077278157d02f65c43b1b26a3886bce886f95d20aabd11f87932750dfb14ed", size = 5959556, upload-time = "2026-03-29T13:19:47.661Z" }, - { url = "https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf", size = 12317311, upload-time = "2026-03-29T13:19:50.67Z" }, - { url = "https://files.pythonhosted.org/packages/ba/d8/11490cddd564eb4de97b4579ef6bfe6a736cc07e94c1598590ae25415e01/numpy-2.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:ef4059d6e5152fa1a39f888e344c73fdc926e1b2dd58c771d67b0acfbf2aa67d", size = 10222060, upload-time = "2026-03-29T13:19:54.229Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/dab4339177a905aad3e2221c915b35202f1ec30d750dd2e5e9d9a72b804b/numpy-2.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4bbc7f303d125971f60ec0aaad5e12c62d0d2c925f0ab1273debd0e4ba37aba5", size = 14822302, upload-time = "2026-03-29T13:19:57.585Z" }, - { url = "https://files.pythonhosted.org/packages/eb/e4/0564a65e7d3d97562ed6f9b0fd0fb0a6f559ee444092f105938b50043876/numpy-2.4.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:4d6d57903571f86180eb98f8f0c839fa9ebbfb031356d87f1361be91e433f5b7", size = 5327407, upload-time = "2026-03-29T13:20:00.601Z" }, - { url = "https://files.pythonhosted.org/packages/29/8d/35a3a6ce5ad371afa58b4700f1c820f8f279948cca32524e0a695b0ded83/numpy-2.4.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:4636de7fd195197b7535f231b5de9e4b36d2c440b6e566d2e4e4746e6af0ca93", size = 6647631, upload-time = "2026-03-29T13:20:02.855Z" }, - { url = "https://files.pythonhosted.org/packages/f4/da/477731acbd5a58a946c736edfdabb2ac5b34c3d08d1ba1a7b437fa0884df/numpy-2.4.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad2e2ef14e0b04e544ea2fa0a36463f847f113d314aa02e5b402fdf910ef309e", size = 15727691, upload-time = "2026-03-29T13:20:06.004Z" }, - { url = "https://files.pythonhosted.org/packages/e6/db/338535d9b152beabeb511579598418ba0212ce77cf9718edd70262cc4370/numpy-2.4.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a285b3b96f951841799528cd1f4f01cd70e7e0204b4abebac9463eecfcf2a40", size = 16681241, upload-time = "2026-03-29T13:20:09.417Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a9/ad248e8f58beb7a0219b413c9c7d8151c5d285f7f946c3e26695bdbbe2df/numpy-2.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f8474c4241bc18b750be2abea9d7a9ec84f46ef861dbacf86a4f6e043401f79e", size = 17085767, upload-time = "2026-03-29T13:20:13.126Z" }, - { url = "https://files.pythonhosted.org/packages/b5/1a/3b88ccd3694681356f70da841630e4725a7264d6a885c8d442a697e1146b/numpy-2.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4e874c976154687c1f71715b034739b45c7711bec81db01914770373d125e392", size = 18403169, upload-time = "2026-03-29T13:20:17.096Z" }, - { url = "https://files.pythonhosted.org/packages/c2/c9/fcfd5d0639222c6eac7f304829b04892ef51c96a75d479214d77e3ce6e33/numpy-2.4.4-cp313-cp313t-win32.whl", hash = "sha256:9c585a1790d5436a5374bac930dad6ed244c046ed91b2b2a3634eb2971d21008", size = 6083477, upload-time = "2026-03-29T13:20:20.195Z" }, - { url = "https://files.pythonhosted.org/packages/d5/e3/3938a61d1c538aaec8ed6fd6323f57b0c2d2d2219512434c5c878db76553/numpy-2.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:93e15038125dc1e5345d9b5b68aa7f996ec33b98118d18c6ca0d0b7d6198b7e8", size = 12457487, upload-time = "2026-03-29T13:20:22.946Z" }, - { url = "https://files.pythonhosted.org/packages/97/6a/7e345032cc60501721ef94e0e30b60f6b0bd601f9174ebd36389a2b86d40/numpy-2.4.4-cp313-cp313t-win_arm64.whl", hash = "sha256:0dfd3f9d3adbe2920b68b5cd3d51444e13a10792ec7154cd0a2f6e74d4ab3233", size = 10292002, upload-time = "2026-03-29T13:20:25.909Z" }, - { url = "https://files.pythonhosted.org/packages/6e/06/c54062f85f673dd5c04cbe2f14c3acb8c8b95e3384869bb8cc9bff8cb9df/numpy-2.4.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f169b9a863d34f5d11b8698ead99febeaa17a13ca044961aa8e2662a6c7766a0", size = 16684353, upload-time = "2026-03-29T13:20:29.504Z" }, - { url = "https://files.pythonhosted.org/packages/4c/39/8a320264a84404c74cc7e79715de85d6130fa07a0898f67fb5cd5bd79908/numpy-2.4.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2483e4584a1cb3092da4470b38866634bafb223cbcd551ee047633fd2584599a", size = 14704914, upload-time = "2026-03-29T13:20:33.547Z" }, - { url = "https://files.pythonhosted.org/packages/91/fb/287076b2614e1d1044235f50f03748f31fa287e3dbe6abeb35cdfa351eca/numpy-2.4.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:2d19e6e2095506d1736b7d80595e0f252d76b89f5e715c35e06e937679ea7d7a", size = 5210005, upload-time = "2026-03-29T13:20:36.45Z" }, - { url = "https://files.pythonhosted.org/packages/63/eb/fcc338595309910de6ecabfcef2419a9ce24399680bfb149421fa2df1280/numpy-2.4.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6a246d5914aa1c820c9443ddcee9c02bec3e203b0c080349533fae17727dfd1b", size = 6544974, upload-time = "2026-03-29T13:20:39.014Z" }, - { url = "https://files.pythonhosted.org/packages/44/5d/e7e9044032a716cdfaa3fba27a8e874bf1c5f1912a1ddd4ed071bf8a14a6/numpy-2.4.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989824e9faf85f96ec9c7761cd8d29c531ad857bfa1daa930cba85baaecf1a9a", size = 15684591, upload-time = "2026-03-29T13:20:42.146Z" }, - { url = "https://files.pythonhosted.org/packages/98/7c/21252050676612625449b4807d6b695b9ce8a7c9e1c197ee6216c8a65c7c/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27a8d92cd10f1382a67d7cf4db7ce18341b66438bdd9f691d7b0e48d104c2a9d", size = 16637700, upload-time = "2026-03-29T13:20:46.204Z" }, - { url = "https://files.pythonhosted.org/packages/b1/29/56d2bbef9465db24ef25393383d761a1af4f446a1df9b8cded4fe3a5a5d7/numpy-2.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e44319a2953c738205bf3354537979eaa3998ed673395b964c1176083dd46252", size = 17035781, upload-time = "2026-03-29T13:20:50.242Z" }, - { url = "https://files.pythonhosted.org/packages/e3/2b/a35a6d7589d21f44cea7d0a98de5ddcbb3d421b2622a5c96b1edf18707c3/numpy-2.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e892aff75639bbef0d2a2cfd55535510df26ff92f63c92cd84ef8d4ba5a5557f", size = 18362959, upload-time = "2026-03-29T13:20:54.019Z" }, - { url = "https://files.pythonhosted.org/packages/64/c9/d52ec581f2390e0f5f85cbfd80fb83d965fc15e9f0e1aec2195faa142cde/numpy-2.4.4-cp314-cp314-win32.whl", hash = "sha256:1378871da56ca8943c2ba674530924bb8ca40cd228358a3b5f302ad60cf875fc", size = 6008768, upload-time = "2026-03-29T13:20:56.912Z" }, - { url = "https://files.pythonhosted.org/packages/fa/22/4cc31a62a6c7b74a8730e31a4274c5dc80e005751e277a2ce38e675e4923/numpy-2.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:715d1c092715954784bc79e1174fc2a90093dc4dc84ea15eb14dad8abdcdeb74", size = 12449181, upload-time = "2026-03-29T13:20:59.548Z" }, - { url = "https://files.pythonhosted.org/packages/70/2e/14cda6f4d8e396c612d1bf97f22958e92148801d7e4f110cabebdc0eef4b/numpy-2.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:2c194dd721e54ecad9ad387c1d35e63dce5c4450c6dc7dd5611283dda239aabb", size = 10496035, upload-time = "2026-03-29T13:21:02.524Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e8/8fed8c8d848d7ecea092dc3469643f9d10bc3a134a815a3b033da1d2039b/numpy-2.4.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2aa0613a5177c264ff5921051a5719d20095ea586ca88cc802c5c218d1c67d3e", size = 14824958, upload-time = "2026-03-29T13:21:05.671Z" }, - { url = "https://files.pythonhosted.org/packages/05/1a/d8007a5138c179c2bf33ef44503e83d70434d2642877ee8fbb230e7c0548/numpy-2.4.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:42c16925aa5a02362f986765f9ebabf20de75cdefdca827d14315c568dcab113", size = 5330020, upload-time = "2026-03-29T13:21:08.635Z" }, - { url = "https://files.pythonhosted.org/packages/99/64/ffb99ac6ae93faf117bcbd5c7ba48a7f45364a33e8e458545d3633615dda/numpy-2.4.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:874f200b2a981c647340f841730fc3a2b54c9d940566a3c4149099591e2c4c3d", size = 6650758, upload-time = "2026-03-29T13:21:10.949Z" }, - { url = "https://files.pythonhosted.org/packages/6e/6e/795cc078b78a384052e73b2f6281ff7a700e9bf53bcce2ee579d4f6dd879/numpy-2.4.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b39d38a9bd2ae1becd7eac1303d031c5c110ad31f2b319c6e7d98b135c934d", size = 15729948, upload-time = "2026-03-29T13:21:14.047Z" }, - { url = "https://files.pythonhosted.org/packages/5f/86/2acbda8cc2af5f3d7bfc791192863b9e3e19674da7b5e533fded124d1299/numpy-2.4.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b268594bccac7d7cf5844c7732e3f20c50921d94e36d7ec9b79e9857694b1b2f", size = 16679325, upload-time = "2026-03-29T13:21:17.561Z" }, - { url = "https://files.pythonhosted.org/packages/bc/59/cafd83018f4aa55e0ac6fa92aa066c0a1877b77a615ceff1711c260ffae8/numpy-2.4.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac6b31e35612a26483e20750126d30d0941f949426974cace8e6b5c58a3657b0", size = 17084883, upload-time = "2026-03-29T13:21:21.106Z" }, - { url = "https://files.pythonhosted.org/packages/f0/85/a42548db84e65ece46ab2caea3d3f78b416a47af387fcbb47ec28e660dc2/numpy-2.4.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8e3ed142f2728df44263aaf5fb1f5b0b99f4070c553a0d7f033be65338329150", size = 18403474, upload-time = "2026-03-29T13:21:24.828Z" }, - { url = "https://files.pythonhosted.org/packages/ed/ad/483d9e262f4b831000062e5d8a45e342166ec8aaa1195264982bca267e62/numpy-2.4.4-cp314-cp314t-win32.whl", hash = "sha256:dddbbd259598d7240b18c9d87c56a9d2fb3b02fe266f49a7c101532e78c1d871", size = 6155500, upload-time = "2026-03-29T13:21:28.205Z" }, - { url = "https://files.pythonhosted.org/packages/c7/03/2fc4e14c7bd4ff2964b74ba90ecb8552540b6315f201df70f137faa5c589/numpy-2.4.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a7164afb23be6e37ad90b2f10426149fd75aee07ca55653d2aa41e66c4ef697e", size = 12637755, upload-time = "2026-03-29T13:21:31.107Z" }, - { url = "https://files.pythonhosted.org/packages/58/78/548fb8e07b1a341746bfbecb32f2c268470f45fa028aacdbd10d9bc73aab/numpy-2.4.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ba203255017337d39f89bdd58417f03c4426f12beed0440cfd933cb15f8669c7", size = 10566643, upload-time = "2026-03-29T13:21:34.339Z" }, - { url = "https://files.pythonhosted.org/packages/6b/33/8fae8f964a4f63ed528264ddf25d2b683d0b663e3cba26961eb838a7c1bd/numpy-2.4.4-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:58c8b5929fcb8287cbd6f0a3fae19c6e03a5c48402ae792962ac465224a629a4", size = 16854491, upload-time = "2026-03-29T13:21:38.03Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d0/1aabee441380b981cf8cdda3ae7a46aa827d1b5a8cce84d14598bc94d6d9/numpy-2.4.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:eea7ac5d2dce4189771cedb559c738a71512768210dc4e4753b107a2048b3d0e", size = 14895830, upload-time = "2026-03-29T13:21:41.509Z" }, - { url = "https://files.pythonhosted.org/packages/a5/b8/aafb0d1065416894fccf4df6b49ef22b8db045187949545bced89c034b8e/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:51fc224f7ca4d92656d5a5eb315f12eb5fe2c97a66249aa7b5f562528a3be38c", size = 5400927, upload-time = "2026-03-29T13:21:44.747Z" }, - { url = "https://files.pythonhosted.org/packages/d6/77/063baa20b08b431038c7f9ff5435540c7b7265c78cf56012a483019ca72d/numpy-2.4.4-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:28a650663f7314afc3e6ec620f44f333c386aad9f6fc472030865dc0ebb26ee3", size = 6715557, upload-time = "2026-03-29T13:21:47.406Z" }, - { url = "https://files.pythonhosted.org/packages/c7/a8/379542d45a14f149444c5c4c4e7714707239ce9cc1de8c2803958889da14/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19710a9ca9992d7174e9c52f643d4272dcd1558c5f7af7f6f8190f633bd651a7", size = 15804253, upload-time = "2026-03-29T13:21:50.753Z" }, - { url = "https://files.pythonhosted.org/packages/a2/c8/f0a45426d6d21e7ea3310a15cf90c43a14d9232c31a837702dba437f3373/numpy-2.4.4-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b2aec6af35c113b05695ebb5749a787acd63cafc83086a05771d1e1cd1e555f", size = 16753552, upload-time = "2026-03-29T13:21:54.344Z" }, - { url = "https://files.pythonhosted.org/packages/04/74/f4c001f4714c3ad9ce037e18cf2b9c64871a84951eaa0baf683a9ca9301c/numpy-2.4.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f2cf083b324a467e1ab358c105f6cad5ea950f50524668a80c486ff1db24e119", size = 12509075, upload-time = "2026-03-29T13:21:57.644Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/22/fd/89965aa4ac08c74998539fcbf24fa3540f3e15237fbeb6bcf9c908f4aade/numpy-2.5.1.tar.gz", hash = "sha256:a48a113e6afea91f5608793bafa7ef2ad481fefbda87ec5069f483de61cb9fa3", size = 20755553, upload-time = "2026-07-04T17:08:00.933Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/7b/14687aa674250e5e546f616f486b0d56d3631cd5b2415739141ce40bdcea/numpy-2.5.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2c889b56fe48b1018f764b0eec8df59ab654e9148aa91faa12596043500de277", size = 16801574, upload-time = "2026-07-04T17:06:12.423Z" }, + { url = "https://files.pythonhosted.org/packages/e1/19/cc5bb2a3f2913d27d6dbb2c78d25921fabaedc6741d4a5a615a11f3c5bf3/numpy-2.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ab451b59c5643c570974c43aef780703ef1d3b4965d2be07afd530615a9358d1", size = 11772250, upload-time = "2026-07-04T17:06:15.726Z" }, + { url = "https://files.pythonhosted.org/packages/42/77/fdf34a71dd30f54979b18603bee915e0aaf825b07afe79acd60b04b691e2/numpy-2.5.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:78798bd5b9ad744056af8efa90e3b9ddaa53272a0848a483084a1cc0a13b2dc0", size = 5331516, upload-time = "2026-07-04T17:06:17.913Z" }, + { url = "https://files.pythonhosted.org/packages/ce/e2/eb7efa015b4cce41e2517bf182a7fce0d7d5b9d9ed76a29bfa0f4fe4505c/numpy-2.5.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:2ae0ca40bcb22d6ba59c1dfd5446f49940b0f2d821fde133f10dda11f816b84e", size = 6664863, upload-time = "2026-07-04T17:06:20.02Z" }, + { url = "https://files.pythonhosted.org/packages/a9/4b/a2b32dd94ee9ffbeecb28152240042a3949db33b1c834d44090b80e1b3b8/numpy-2.5.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:61ac47e772e6b8ea489e1d2f441a34c5c3ac17327e7ce294cbdf535795ad4e75", size = 15167977, upload-time = "2026-07-04T17:06:21.621Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a9/6e73d68500f80773f65f0654ea932019d6694329a0eb0ed0533de38df376/numpy-2.5.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:59fda5e192b570217ec2580c96f00e9a7e12ef6866a900eb089b62c1a32545ca", size = 16672469, upload-time = "2026-07-04T17:06:24.064Z" }, + { url = "https://files.pythonhosted.org/packages/24/7d/ad3e59015135f5261c95fd4cafeff159c955febd83a99a1d9250c4233815/numpy-2.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f7119ebff1a9829e9f431a4f9d28e703023bb6b9fe7c8f724467dbfc27c94ab3", size = 16527531, upload-time = "2026-07-04T17:06:26.69Z" }, + { url = "https://files.pythonhosted.org/packages/83/d0/a39b2fbcde9cb17a1dac678f254b33a6336298af9df338824c685425d5e8/numpy-2.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e824c2acf8862052246be5a44c15da1777940c60d010dd2aab897824d9c430f9", size = 18431940, upload-time = "2026-07-04T17:06:29.521Z" }, + { url = "https://files.pythonhosted.org/packages/04/12/cff070947791c1ed425ff76413189adbdc2fbe215eba7ce7fa454a03c7f8/numpy-2.5.1-cp312-cp312-win32.whl", hash = "sha256:08d60c810432eb83360958dea0999ac4cfb94531ea8efcbf0b7f277c2068aeb2", size = 6066764, upload-time = "2026-07-04T17:06:32.571Z" }, + { url = "https://files.pythonhosted.org/packages/65/66/53f31807a48a750f9d748da273bc3fcedd12b27ff1f3e373bfec55ef2dc0/numpy-2.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:f7d60026c0bdb1380e83bfa7a0419c4577ee4b9a08880afcb6dadeb74c649fa2", size = 12430966, upload-time = "2026-07-04T17:06:34.926Z" }, + { url = "https://files.pythonhosted.org/packages/2b/2a/d1a88066b1c14186f5d3c0d18c94f17b064511982bab0578d49ee9d43c29/numpy-2.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:17a25e09640602e10bc8de0e6fa2b3fd68eedd84ba6d7842dc8f32f9ab87bd0b", size = 10350488, upload-time = "2026-07-04T17:06:37.785Z" }, + { url = "https://files.pythonhosted.org/packages/eb/07/ec2a3f0c91761581d4b7104a740791800025983f9a4dc4e73f91a99aeac4/numpy-2.5.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0bfebd8695f9863592fe744be833a258120b14a9f39da255e8aa8fade2c0ddd1", size = 16796419, upload-time = "2026-07-04T17:06:40.37Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ab/ddb499fc4f8780354395face5b65c7fd107bcd6e1d667a5f07d046956f6f/numpy-2.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:30b44a6b53a7ae63c54c089a8726e5563ed302716c5b7ccc85afade40b0e7ff6", size = 11765832, upload-time = "2026-07-04T17:06:42.768Z" }, + { url = "https://files.pythonhosted.org/packages/88/b3/3c28c558a09fc72100c646dac6d2fce8e834c471b0edca01a29996706117/numpy-2.5.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:6165343f81b56ef8f514f396989e529b61d9dc709b99421b07e9f3e698e2287d", size = 5325143, upload-time = "2026-07-04T17:06:45.466Z" }, + { url = "https://files.pythonhosted.org/packages/5e/0e/ce19b985bb15c596f4f05954e76cccc77c845083b3b8f938a6c68e523128/numpy-2.5.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4939237038ada79308dda3204ac6462df056b5672b2e25db1149cf873668b3e1", size = 6659749, upload-time = "2026-07-04T17:06:47.288Z" }, + { url = "https://files.pythonhosted.org/packages/2e/20/1ee6614d64332a1bba6411f38e68cb79eec1b2459e20a623777c5c5492a2/numpy-2.5.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c6759f538fb912fc46de0a6b1758ccf7b57bc7c7ebebc23974fdac3de8db0cd", size = 15164716, upload-time = "2026-07-04T17:06:49.494Z" }, + { url = "https://files.pythonhosted.org/packages/ed/a7/2bcd3fdbb87804755c35b729bf8709d62025c5f4cfd7d5b2415997097515/numpy-2.5.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9726558e8db4a5bf7929a70ae50f63abda4daf0efe810e3bfbab95976f75fc1a", size = 16661440, upload-time = "2026-07-04T17:06:52.061Z" }, + { url = "https://files.pythonhosted.org/packages/fc/d7/a41e3310c886fe457d36e670bbf24fae411aca8a7b6ad92a32afd924077c/numpy-2.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3935f3b419b244a02732676fa5317a9193cc596a4c0646db07e5b421229ac9f7", size = 16526305, upload-time = "2026-07-04T17:06:54.605Z" }, + { url = "https://files.pythonhosted.org/packages/53/75/4333a9a707c1edd3a4e1a0c58eca52c0f31e55089fa80db02b5565b24df7/numpy-2.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc932a65ded7ce9013d120845a2514dcccb1a67bfc8deb8d37633762951904a6", size = 18423008, upload-time = "2026-07-04T17:06:57.54Z" }, + { url = "https://files.pythonhosted.org/packages/ee/90/e314a32b1c11a2ffe818ddad3a57b50b4b6e1b6c487192eb50cdef0415d0/numpy-2.5.1-cp313-cp313-win32.whl", hash = "sha256:4b4ff1608417eb7a59da7b967bbb798cacfe071d2caf526a24281cd562072ed9", size = 6063885, upload-time = "2026-07-04T17:07:00.14Z" }, + { url = "https://files.pythonhosted.org/packages/10/70/800b3fca480af32df9e8ea9f3d4a0c8feb4b32d7f195d174eabbda4829ad/numpy-2.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:6c3fe51bc6a16453d452997053454f309e8e0ed7b42d6b361ce4ac8c32913d74", size = 12425674, upload-time = "2026-07-04T17:07:02.387Z" }, + { url = "https://files.pythonhosted.org/packages/8b/0b/196350c122f50f6ca56846f2d71efd5e0d24b7b2e07355e019b2e2c7a11e/numpy-2.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:f7feb014281029e628ba2d5a007407443b06e418b6fe451d1e2adcbc8eba0107", size = 10350256, upload-time = "2026-07-04T17:07:04.878Z" }, + { url = "https://files.pythonhosted.org/packages/db/f4/731b6085a83faf6ca843394cbd5e217280c214399f7e8b21b9f552af0ae2/numpy-2.5.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:7c786fe9a5bbe360022e584c5a34cf6b54265c71bd7ec8ac3d8fec38968071f8", size = 16795063, upload-time = "2026-07-04T17:07:07.374Z" }, + { url = "https://files.pythonhosted.org/packages/bf/64/0e215f2048dd11a55bb989ed41b3585ef57452404e638d703a211a3e4157/numpy-2.5.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32985c896d897419ef8da6917872d80b78ad0ea26d85b23245c7366ffde76d75", size = 11776652, upload-time = "2026-07-04T17:07:09.907Z" }, + { url = "https://files.pythonhosted.org/packages/b5/59/2b844c7a6e9deff69b404a66221e1542937734f65d5e6e39411876053862/numpy-2.5.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:efd736408cc97c79b9e6917338dfc8f06013b2274f992e96b1d9a81a71e2a2c2", size = 5335944, upload-time = "2026-07-04T17:07:12.227Z" }, + { url = "https://files.pythonhosted.org/packages/86/51/9bf7cb2cabcebc9e017e4ec7e6322b378317a542c08b4cb68479c1efc716/numpy-2.5.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:ab84dc6b074fa881cae55bea94cc4f68e285181ba7f32497bf7dee6b1496165b", size = 6656266, upload-time = "2026-07-04T17:07:14.368Z" }, + { url = "https://files.pythonhosted.org/packages/83/3e/fb7615b211b82a32f44d5180a6d421b61f84d4fadd578b48ba4ac34e189f/numpy-2.5.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caf3e317d33d60c37986b452613f4ab51246d0691350c03d0cb4a898627f4a95", size = 15179720, upload-time = "2026-07-04T17:07:16.272Z" }, + { url = "https://files.pythonhosted.org/packages/41/5f/0f992cb24560673496c5d68de61913b57166ce530ffda07c1f280e0cc464/numpy-2.5.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:54ad769f17bc2d833b620851989f62054fb9ab93c969d9e1dc3c8e3d56beea21", size = 16664835, upload-time = "2026-07-04T17:07:19.021Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2f/97d6475ee91afe2587797d09446f9d3e475ad4cb681662d824809327b75a/numpy-2.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c12afb53450fa976d4c681c50a7423729a4c51c0465ed9f32b8a9cabbc472373", size = 16539135, upload-time = "2026-07-04T17:07:22.015Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/4db81e4ba0be7e2776b1de68c82aa862c7f8ec27e1b4927d4ae075e20678/numpy-2.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e8c11c405efc5ff6816d5983c96cdfa215bab3428961243af3ff59b228490438", size = 18426684, upload-time = "2026-07-04T17:07:24.941Z" }, + { url = "https://files.pythonhosted.org/packages/1f/64/c0ba2d90724d450279a7df8f32057241070250a26a7e2b5337d77347f481/numpy-2.5.1-cp314-cp314-win32.whl", hash = "sha256:f2479a47f8d5932d1718168a681ad6e536a9df484c83cfcf9de365e164537ace", size = 6116103, upload-time = "2026-07-04T17:07:27.622Z" }, + { url = "https://files.pythonhosted.org/packages/c1/1a/837f9ed7405adcd7a40538792eb169eddd8fa5630c16a1ef49dae71a30f4/numpy-2.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:24d0eb82c0541d3415a33425db64ae439dffccd7b4dbcb30e7c35120205c506a", size = 12562177, upload-time = "2026-07-04T17:07:29.887Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/49707938b6dd0a78a9178dd93227dc89e4c11af47f5c798d70366e8d0483/numpy-2.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:5a4c988b38d261deeeaad9954e3deb091ad905c94e8bb6708654ef1d97f286b0", size = 10627739, upload-time = "2026-07-04T17:07:32.568Z" }, + { url = "https://files.pythonhosted.org/packages/a6/c7/bb4b882cfe7f299cbc8b66e42e7dd78cf9d14e40f9469fc5e3db7e15b3bd/numpy-2.5.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a33276be12fa045805f477f22482088b66bb758ffbe89a9d21457de863a32e22", size = 11894709, upload-time = "2026-07-04T17:07:34.941Z" }, + { url = "https://files.pythonhosted.org/packages/40/3f/5af7f4a7f6224aef48017aa82bb6174c7a659d724be0c75017b7e64a55b4/numpy-2.5.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:f089d7b00756190aacf1f5d34bdf38c3c430ac82b4f868f8cede73380460fce7", size = 5453810, upload-time = "2026-07-04T17:07:37.495Z" }, + { url = "https://files.pythonhosted.org/packages/20/c9/3474309bc94d634d3f9c3eddf03250ecb8c22cd948ef16fef69a77cc5d7b/numpy-2.5.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:09e9bfd8d2cf479c7d174804fb3811c53a8e9f20a37444008606b57d6b7a826d", size = 6761189, upload-time = "2026-07-04T17:07:39.563Z" }, + { url = "https://files.pythonhosted.org/packages/90/8a/558ae39fdd55d7e7f7fef9a84a6e964ac6b23edbd2a07e52bb084500507d/numpy-2.5.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e68d8dd1e7eba712948f2053a29ec86917bc70ba1358df869d9f06649ef9cf09", size = 15225039, upload-time = "2026-07-04T17:07:41.682Z" }, + { url = "https://files.pythonhosted.org/packages/63/27/ca7392b2d030277bdf0273e7d23255b3ee57d57a7c170a6f4fb3981e1e5d/numpy-2.5.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99d5095fa265a0c4152e7bb12759e14381ef5496152f1ce58f44bdf55c44beb4", size = 16701306, upload-time = "2026-07-04T17:07:44.611Z" }, + { url = "https://files.pythonhosted.org/packages/02/42/03d53ae7996c44d4374a8262e9dc41671fd56cbb98f7d47ef85cf5da4c6b/numpy-2.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ab87a91b3cc3382b8956095bd8f95e00cf679bb81554339be1a2ba404a1473c1", size = 16589955, upload-time = "2026-07-04T17:07:47.694Z" }, + { url = "https://files.pythonhosted.org/packages/7b/15/6c1784ae469640e65db111e9a34b3d0f14d91e8a38b9ce34810ced370dbb/numpy-2.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:224ca51130ef7da85bea2191625181cb4f337f9cb64b471f10c1a12aa8b60077", size = 18464252, upload-time = "2026-07-04T17:07:50.684Z" }, + { url = "https://files.pythonhosted.org/packages/94/a8/f98e50356cf167df656c526c2dfeec2d7dde182f2a3da4b458a5938e2776/numpy-2.5.1-cp314-cp314t-win32.whl", hash = "sha256:6eab239876581b2b3c5a242281b6007bbdbcd1c7085d7709bb57c5929b11e6bf", size = 6263298, upload-time = "2026-07-04T17:07:53.445Z" }, + { url = "https://files.pythonhosted.org/packages/72/ac/96ae880cdecad0b3275d9359fcec72667b49a4863c9f12942e43679dda02/numpy-2.5.1-cp314-cp314t-win_amd64.whl", hash = "sha256:83ce9c80d5b521b0d77ddcbe5447c218d247929b6cc056ca5351342accfff0af", size = 12748623, upload-time = "2026-07-04T17:07:55.384Z" }, + { url = "https://files.pythonhosted.org/packages/a1/5a/4d2b1601df3602dba7a14f3348ba9bfe94a18adb428e693df6154c293831/numpy-2.5.1-cp314-cp314t-win_arm64.whl", hash = "sha256:5a6db61f9aaa57e369905c67d852045d3c4f7126405b29d09b19dec118e9c9cb", size = 10697674, upload-time = "2026-07-04T17:07:58.506Z" }, ] [[package]] @@ -1905,7 +2073,8 @@ version = "2.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "python-dateutil" }, { name = "pytz" }, { name = "tzdata" }, @@ -2006,7 +2175,8 @@ version = "0.40.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, + { name = "numpy", version = "2.5.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, { name = "pandas" }, { name = "pephubclient" }, { name = "pyyaml" }, @@ -2020,100 +2190,96 @@ wheels = [ [[package]] name = "pillow" -version = "12.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/aa/d0b28e1c811cd4d5f5c2bfe2e022292bd255ae5744a3b9ac7d6c8f72dd75/pillow-12.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a4e8f36e677d3336f35089648c8955c51c6d386a13cf6ee9c189c5f5bd713a9f", size = 5354355, upload-time = "2026-04-01T14:42:15.402Z" }, - { url = "https://files.pythonhosted.org/packages/27/8e/1d5b39b8ae2bd7650d0c7b6abb9602d16043ead9ebbfef4bc4047454da2a/pillow-12.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e589959f10d9824d39b350472b92f0ce3b443c0a3442ebf41c40cb8361c5b97", size = 4695871, upload-time = "2026-04-01T14:42:18.234Z" }, - { url = "https://files.pythonhosted.org/packages/f0/c5/dcb7a6ca6b7d3be41a76958e90018d56c8462166b3ef223150360850c8da/pillow-12.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a52edc8bfff4429aaabdf4d9ee0daadbbf8562364f940937b941f87a4290f5ff", size = 6269734, upload-time = "2026-04-01T14:42:20.608Z" }, - { url = "https://files.pythonhosted.org/packages/ea/f1/aa1bb13b2f4eba914e9637893c73f2af8e48d7d4023b9d3750d4c5eb2d0c/pillow-12.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:975385f4776fafde056abb318f612ef6285b10a1f12b8570f3647ad0d74b48ec", size = 8076080, upload-time = "2026-04-01T14:42:23.095Z" }, - { url = "https://files.pythonhosted.org/packages/a1/2a/8c79d6a53169937784604a8ae8d77e45888c41537f7f6f65ed1f407fe66d/pillow-12.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd9c0c7a0c681a347b3194c500cb1e6ca9cab053ea4d82a5cf45b6b754560136", size = 6382236, upload-time = "2026-04-01T14:42:25.82Z" }, - { url = "https://files.pythonhosted.org/packages/b5/42/bbcb6051030e1e421d103ce7a8ecadf837aa2f39b8f82ef1a8d37c3d4ebc/pillow-12.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88d387ff40b3ff7c274947ed3125dedf5262ec6919d83946753b5f3d7c67ea4c", size = 7070220, upload-time = "2026-04-01T14:42:28.68Z" }, - { url = "https://files.pythonhosted.org/packages/3f/e1/c2a7d6dd8cfa6b231227da096fd2d58754bab3603b9d73bf609d3c18b64f/pillow-12.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c4167c34b0d8ba05b547a3bb23578d0ba17b80a5593f93bd8ecb123dd336a3", size = 6493124, upload-time = "2026-04-01T14:42:31.579Z" }, - { url = "https://files.pythonhosted.org/packages/5f/41/7c8617da5d32e1d2f026e509484fdb6f3ad7efaef1749a0c1928adbb099e/pillow-12.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:34c0d99ecccea270c04882cb3b86e7b57296079c9a4aff88cb3b33563d95afaa", size = 7194324, upload-time = "2026-04-01T14:42:34.615Z" }, - { url = "https://files.pythonhosted.org/packages/2d/de/a777627e19fd6d62f84070ee1521adde5eeda4855b5cf60fe0b149118bca/pillow-12.2.0-cp310-cp310-win32.whl", hash = "sha256:b85f66ae9eb53e860a873b858b789217ba505e5e405a24b85c0464822fe88032", size = 6376363, upload-time = "2026-04-01T14:42:37.19Z" }, - { url = "https://files.pythonhosted.org/packages/e7/34/fc4cb5204896465842767b96d250c08410f01f2f28afc43b257de842eed5/pillow-12.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:673aa32138f3e7531ccdbca7b3901dba9b70940a19ccecc6a37c77d5fdeb05b5", size = 7083523, upload-time = "2026-04-01T14:42:39.62Z" }, - { url = "https://files.pythonhosted.org/packages/2d/a0/32852d36bc7709f14dc3f64f929a275e958ad8c19a6deba9610d458e28b3/pillow-12.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:3e080565d8d7c671db5802eedfb438e5565ffa40115216eabb8cd52d0ecce024", size = 2463318, upload-time = "2026-04-01T14:42:42.063Z" }, - { url = "https://files.pythonhosted.org/packages/68/e1/748f5663efe6edcfc4e74b2b93edfb9b8b99b67f21a854c3ae416500a2d9/pillow-12.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:8be29e59487a79f173507c30ddf57e733a357f67881430449bb32614075a40ab", size = 5354347, upload-time = "2026-04-01T14:42:44.255Z" }, - { url = "https://files.pythonhosted.org/packages/47/a1/d5ff69e747374c33a3b53b9f98cca7889fce1fd03d79cdc4e1bccc6c5a87/pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65", size = 4695873, upload-time = "2026-04-01T14:42:46.452Z" }, - { url = "https://files.pythonhosted.org/packages/df/21/e3fbdf54408a973c7f7f89a23b2cb97a7ef30c61ab4142af31eee6aebc88/pillow-12.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f490f9368b6fc026f021db16d7ec2fbf7d89e2edb42e8ec09d2c60505f5729c7", size = 6280168, upload-time = "2026-04-01T14:42:49.228Z" }, - { url = "https://files.pythonhosted.org/packages/d3/f1/00b7278c7dd52b17ad4329153748f87b6756ec195ff786c2bdf12518337d/pillow-12.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8bd7903a5f2a4545f6fd5935c90058b89d30045568985a71c79f5fd6edf9b91e", size = 8088188, upload-time = "2026-04-01T14:42:51.735Z" }, - { url = "https://files.pythonhosted.org/packages/ad/cf/220a5994ef1b10e70e85748b75649d77d506499352be135a4989c957b701/pillow-12.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3997232e10d2920a68d25191392e3a4487d8183039e1c74c2297f00ed1c50705", size = 6394401, upload-time = "2026-04-01T14:42:54.343Z" }, - { url = "https://files.pythonhosted.org/packages/e9/bd/e51a61b1054f09437acfbc2ff9106c30d1eb76bc1453d428399946781253/pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176", size = 7079655, upload-time = "2026-04-01T14:42:56.954Z" }, - { url = "https://files.pythonhosted.org/packages/6b/3d/45132c57d5fb4b5744567c3817026480ac7fc3ce5d4c47902bc0e7f6f853/pillow-12.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:56a3f9c60a13133a98ecff6197af34d7824de9b7b38c3654861a725c970c197b", size = 6503105, upload-time = "2026-04-01T14:42:59.847Z" }, - { url = "https://files.pythonhosted.org/packages/7d/2e/9df2fc1e82097b1df3dce58dc43286aa01068e918c07574711fcc53e6fb4/pillow-12.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90e6f81de50ad6b534cab6e5aef77ff6e37722b2f5d908686f4a5c9eba17a909", size = 7203402, upload-time = "2026-04-01T14:43:02.664Z" }, - { url = "https://files.pythonhosted.org/packages/bd/2e/2941e42858ebb67e50ae741473de81c2984e6eff7b397017623c676e2e8d/pillow-12.2.0-cp311-cp311-win32.whl", hash = "sha256:8c984051042858021a54926eb597d6ee3012393ce9c181814115df4c60b9a808", size = 6378149, upload-time = "2026-04-01T14:43:05.274Z" }, - { url = "https://files.pythonhosted.org/packages/69/42/836b6f3cd7f3e5fa10a1f1a5420447c17966044c8fbf589cc0452d5502db/pillow-12.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60", size = 7082626, upload-time = "2026-04-01T14:43:08.557Z" }, - { url = "https://files.pythonhosted.org/packages/c2/88/549194b5d6f1f494b485e493edc6693c0a16f4ada488e5bd974ed1f42fad/pillow-12.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:9a8a34cc89c67a65ea7437ce257cea81a9dad65b29805f3ecee8c8fe8ff25ffe", size = 2463531, upload-time = "2026-04-01T14:43:10.743Z" }, - { url = "https://files.pythonhosted.org/packages/58/be/7482c8a5ebebbc6470b3eb791812fff7d5e0216c2be3827b30b8bb6603ed/pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5", size = 5308279, upload-time = "2026-04-01T14:43:13.246Z" }, - { url = "https://files.pythonhosted.org/packages/d8/95/0a351b9289c2b5cbde0bacd4a83ebc44023e835490a727b2a3bd60ddc0f4/pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421", size = 4695490, upload-time = "2026-04-01T14:43:15.584Z" }, - { url = "https://files.pythonhosted.org/packages/de/af/4e8e6869cbed569d43c416fad3dc4ecb944cb5d9492defaed89ddd6fe871/pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987", size = 6284462, upload-time = "2026-04-01T14:43:18.268Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9e/c05e19657fd57841e476be1ab46c4d501bffbadbafdc31a6d665f8b737b6/pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76", size = 8094744, upload-time = "2026-04-01T14:43:20.716Z" }, - { url = "https://files.pythonhosted.org/packages/2b/54/1789c455ed10176066b6e7e6da1b01e50e36f94ba584dc68d9eebfe9156d/pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005", size = 6398371, upload-time = "2026-04-01T14:43:23.443Z" }, - { url = "https://files.pythonhosted.org/packages/43/e3/fdc657359e919462369869f1c9f0e973f353f9a9ee295a39b1fea8ee1a77/pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780", size = 7087215, upload-time = "2026-04-01T14:43:26.758Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f8/2f6825e441d5b1959d2ca5adec984210f1ec086435b0ed5f52c19b3b8a6e/pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5", size = 6509783, upload-time = "2026-04-01T14:43:29.56Z" }, - { url = "https://files.pythonhosted.org/packages/67/f9/029a27095ad20f854f9dba026b3ea6428548316e057e6fc3545409e86651/pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5", size = 7212112, upload-time = "2026-04-01T14:43:32.091Z" }, - { url = "https://files.pythonhosted.org/packages/be/42/025cfe05d1be22dbfdb4f264fe9de1ccda83f66e4fc3aac94748e784af04/pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940", size = 6378489, upload-time = "2026-04-01T14:43:34.601Z" }, - { url = "https://files.pythonhosted.org/packages/5d/7b/25a221d2c761c6a8ae21bfa3874988ff2583e19cf8a27bf2fee358df7942/pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5", size = 7084129, upload-time = "2026-04-01T14:43:37.213Z" }, - { url = "https://files.pythonhosted.org/packages/10/e1/542a474affab20fd4a0f1836cb234e8493519da6b76899e30bcc5d990b8b/pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414", size = 2463612, upload-time = "2026-04-01T14:43:39.421Z" }, - { url = "https://files.pythonhosted.org/packages/4a/01/53d10cf0dbad820a8db274d259a37ba50b88b24768ddccec07355382d5ad/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c", size = 4100837, upload-time = "2026-04-01T14:43:41.506Z" }, - { url = "https://files.pythonhosted.org/packages/0f/98/f3a6657ecb698c937f6c76ee564882945f29b79bad496abcba0e84659ec5/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2", size = 4176528, upload-time = "2026-04-01T14:43:43.773Z" }, - { url = "https://files.pythonhosted.org/packages/69/bc/8986948f05e3ea490b8442ea1c1d4d990b24a7e43d8a51b2c7d8b1dced36/pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c", size = 3640401, upload-time = "2026-04-01T14:43:45.87Z" }, - { url = "https://files.pythonhosted.org/packages/34/46/6c717baadcd62bc8ed51d238d521ab651eaa74838291bda1f86fe1f864c9/pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795", size = 5308094, upload-time = "2026-04-01T14:43:48.438Z" }, - { url = "https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f", size = 4695402, upload-time = "2026-04-01T14:43:51.292Z" }, - { url = "https://files.pythonhosted.org/packages/73/dd/42107efcb777b16fa0393317eac58f5b5cf30e8392e266e76e51cff28c3d/pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed", size = 6280005, upload-time = "2026-04-01T14:43:54.242Z" }, - { url = "https://files.pythonhosted.org/packages/a8/68/b93e09e5e8549019e61acf49f65b1a8530765a7f812c77a7461bca7e4494/pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9", size = 8090669, upload-time = "2026-04-01T14:43:57.335Z" }, - { url = "https://files.pythonhosted.org/packages/4b/6e/3ccb54ce8ec4ddd1accd2d89004308b7b0b21c4ac3d20fa70af4760a4330/pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed", size = 6395194, upload-time = "2026-04-01T14:43:59.864Z" }, - { url = "https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3", size = 7082423, upload-time = "2026-04-01T14:44:02.74Z" }, - { url = "https://files.pythonhosted.org/packages/78/5f/e9f86ab0146464e8c133fe85df987ed9e77e08b29d8d35f9f9f4d6f917ba/pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9", size = 6505667, upload-time = "2026-04-01T14:44:05.381Z" }, - { url = "https://files.pythonhosted.org/packages/ed/1e/409007f56a2fdce61584fd3acbc2bbc259857d555196cedcadc68c015c82/pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795", size = 7208580, upload-time = "2026-04-01T14:44:08.39Z" }, - { url = "https://files.pythonhosted.org/packages/23/c4/7349421080b12fb35414607b8871e9534546c128a11965fd4a7002ccfbee/pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e", size = 6375896, upload-time = "2026-04-01T14:44:11.197Z" }, - { url = "https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b", size = 7081266, upload-time = "2026-04-01T14:44:13.947Z" }, - { url = "https://files.pythonhosted.org/packages/c3/25/f968f618a062574294592f668218f8af564830ccebdd1fa6200f598e65c5/pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06", size = 2463508, upload-time = "2026-04-01T14:44:16.312Z" }, - { url = "https://files.pythonhosted.org/packages/4d/a4/b342930964e3cb4dce5038ae34b0eab4653334995336cd486c5a8c25a00c/pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b", size = 5309927, upload-time = "2026-04-01T14:44:18.89Z" }, - { url = "https://files.pythonhosted.org/packages/9f/de/23198e0a65a9cf06123f5435a5d95cea62a635697f8f03d134d3f3a96151/pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f", size = 4698624, upload-time = "2026-04-01T14:44:21.115Z" }, - { url = "https://files.pythonhosted.org/packages/01/a6/1265e977f17d93ea37aa28aa81bad4fa597933879fac2520d24e021c8da3/pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612", size = 6321252, upload-time = "2026-04-01T14:44:23.663Z" }, - { url = "https://files.pythonhosted.org/packages/3c/83/5982eb4a285967baa70340320be9f88e57665a387e3a53a7f0db8231a0cd/pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c", size = 8126550, upload-time = "2026-04-01T14:44:26.772Z" }, - { url = "https://files.pythonhosted.org/packages/4e/48/6ffc514adce69f6050d0753b1a18fd920fce8cac87620d5a31231b04bfc5/pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea", size = 6433114, upload-time = "2026-04-01T14:44:29.615Z" }, - { url = "https://files.pythonhosted.org/packages/36/a3/f9a77144231fb8d40ee27107b4463e205fa4677e2ca2548e14da5cf18dce/pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4", size = 7115667, upload-time = "2026-04-01T14:44:32.773Z" }, - { url = "https://files.pythonhosted.org/packages/c1/fc/ac4ee3041e7d5a565e1c4fd72a113f03b6394cc72ab7089d27608f8aaccb/pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4", size = 6538966, upload-time = "2026-04-01T14:44:35.252Z" }, - { url = "https://files.pythonhosted.org/packages/c0/a8/27fb307055087f3668f6d0a8ccb636e7431d56ed0750e07a60547b1e083e/pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea", size = 7238241, upload-time = "2026-04-01T14:44:37.875Z" }, - { url = "https://files.pythonhosted.org/packages/ad/4b/926ab182c07fccae9fcb120043464e1ff1564775ec8864f21a0ebce6ac25/pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24", size = 6379592, upload-time = "2026-04-01T14:44:40.336Z" }, - { url = "https://files.pythonhosted.org/packages/c2/c4/f9e476451a098181b30050cc4c9a3556b64c02cf6497ea421ac047e89e4b/pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98", size = 7085542, upload-time = "2026-04-01T14:44:43.251Z" }, - { url = "https://files.pythonhosted.org/packages/00/a4/285f12aeacbe2d6dc36c407dfbbe9e96d4a80b0fb710a337f6d2ad978c75/pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453", size = 2465765, upload-time = "2026-04-01T14:44:45.996Z" }, - { url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8", size = 4100848, upload-time = "2026-04-01T14:44:48.48Z" }, - { url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b", size = 4176515, upload-time = "2026-04-01T14:44:51.353Z" }, - { url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295", size = 3640159, upload-time = "2026-04-01T14:44:53.588Z" }, - { url = "https://files.pythonhosted.org/packages/71/e0/fb22f797187d0be2270f83500aab851536101b254bfa1eae10795709d283/pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed", size = 5312185, upload-time = "2026-04-01T14:44:56.039Z" }, - { url = "https://files.pythonhosted.org/packages/ba/8c/1a9e46228571de18f8e28f16fabdfc20212a5d019f3e3303452b3f0a580d/pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae", size = 4695386, upload-time = "2026-04-01T14:44:58.663Z" }, - { url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601", size = 6280384, upload-time = "2026-04-01T14:45:01.5Z" }, - { url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be", size = 8091599, upload-time = "2026-04-01T14:45:04.5Z" }, - { url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f", size = 6396021, upload-time = "2026-04-01T14:45:07.117Z" }, - { url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286", size = 7083360, upload-time = "2026-04-01T14:45:09.763Z" }, - { url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50", size = 6507628, upload-time = "2026-04-01T14:45:12.378Z" }, - { url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104", size = 7209321, upload-time = "2026-04-01T14:45:15.122Z" }, - { url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7", size = 6479723, upload-time = "2026-04-01T14:45:17.797Z" }, - { url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150", size = 7217400, upload-time = "2026-04-01T14:45:20.529Z" }, - { url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1", size = 2554835, upload-time = "2026-04-01T14:45:23.162Z" }, - { url = "https://files.pythonhosted.org/packages/b6/ab/1b426a3974cb0e7da5c29ccff4807871d48110933a57207b5a676cccc155/pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463", size = 5314225, upload-time = "2026-04-01T14:45:25.637Z" }, - { url = "https://files.pythonhosted.org/packages/19/1e/dce46f371be2438eecfee2a1960ee2a243bbe5e961890146d2dee1ff0f12/pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3", size = 4698541, upload-time = "2026-04-01T14:45:28.355Z" }, - { url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166", size = 6322251, upload-time = "2026-04-01T14:45:30.924Z" }, - { url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe", size = 8127807, upload-time = "2026-04-01T14:45:33.908Z" }, - { url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd", size = 6433935, upload-time = "2026-04-01T14:45:36.623Z" }, - { url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e", size = 7116720, upload-time = "2026-04-01T14:45:39.258Z" }, - { url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06", size = 6540498, upload-time = "2026-04-01T14:45:41.879Z" }, - { url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43", size = 7239413, upload-time = "2026-04-01T14:45:44.705Z" }, - { url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354", size = 6482084, upload-time = "2026-04-01T14:45:47.568Z" }, - { url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1", size = 7225152, upload-time = "2026-04-01T14:45:50.032Z" }, - { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579, upload-time = "2026-04-01T14:45:52.529Z" }, - { url = "https://files.pythonhosted.org/packages/4e/b7/2437044fb910f499610356d1352e3423753c98e34f915252aafecc64889f/pillow-12.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538bd5e05efec03ae613fd89c4ce0368ecd2ba239cc25b9f9be7ed426b0af1f", size = 5273969, upload-time = "2026-04-01T14:45:55.538Z" }, - { url = "https://files.pythonhosted.org/packages/f6/f4/8316e31de11b780f4ac08ef3654a75555e624a98db1056ecb2122d008d5a/pillow-12.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:394167b21da716608eac917c60aa9b969421b5dcbbe02ae7f013e7b85811c69d", size = 4659674, upload-time = "2026-04-01T14:45:58.093Z" }, - { url = "https://files.pythonhosted.org/packages/d4/37/664fca7201f8bb2aa1d20e2c3d5564a62e6ae5111741966c8319ca802361/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5d04bfa02cc2d23b497d1e90a0f927070043f6cbf303e738300532379a4b4e0f", size = 5288479, upload-time = "2026-04-01T14:46:01.141Z" }, - { url = "https://files.pythonhosted.org/packages/49/62/5b0ed78fce87346be7a5cfcfaaad91f6a1f98c26f86bdbafa2066c647ef6/pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0c838a5125cee37e68edec915651521191cef1e6aa336b855f495766e77a366e", size = 7032230, upload-time = "2026-04-01T14:46:03.874Z" }, - { url = "https://files.pythonhosted.org/packages/c3/28/ec0fc38107fc32536908034e990c47914c57cd7c5a3ece4d8d8f7ffd7e27/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a6c9fa44005fa37a91ebfc95d081e8079757d2e904b27103f4f5fa6f0bf78c0", size = 5355404, upload-time = "2026-04-01T14:46:06.33Z" }, - { url = "https://files.pythonhosted.org/packages/5e/8b/51b0eddcfa2180d60e41f06bd6d0a62202b20b59c68f5a132e615b75aecf/pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25373b66e0dd5905ed63fa3cae13c82fbddf3079f2c8bf15c6fb6a35586324c1", size = 6002215, upload-time = "2026-04-01T14:46:08.83Z" }, - { url = "https://files.pythonhosted.org/packages/bc/60/5382c03e1970de634027cee8e1b7d39776b778b81812aaf45b694dfe9e28/pillow-12.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:bfa9c230d2fe991bed5318a5f119bd6780cda2915cca595393649fc118ab895e", size = 7080946, upload-time = "2026-04-01T14:46:11.734Z" }, +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/c2/669d88644cddb1485bd9534e63e8cf476c8e51cb3c3a1297677023505c0e/pillow-12.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6c0016e7b354317c4e9e525b937ac8596c38d2d232b419529b9cd7a1cd46e39a", size = 5392418, upload-time = "2026-07-01T11:53:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ba/3762f376a2948e3036488d773a146e0ae6ecc2ca03ac20e2615bd0b2ba02/pillow-12.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bcc33feacfaefce60c12fd500a277533bdc02b10a19f7f6d348763d8140bbba7", size = 4785287, upload-time = "2026-07-01T11:53:29.761Z" }, + { url = "https://files.pythonhosted.org/packages/07/50/b5d688cc9c52d4482f3d5bcab6ce20bc2a74a85d2343841c907444a3be2c/pillow-12.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5594fc43d548a7ed94949d139aa1341b270f1863f11cfd37f5a6c8b778a6b67f", size = 6253754, upload-time = "2026-07-01T11:53:32.298Z" }, + { url = "https://files.pythonhosted.org/packages/4e/89/36f4cd76cf4baf05c50ababb976249153f18c959171c7f6ba09a6f217260/pillow-12.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0606c8bf2cdefea14a43530f7657cbbb7ecf1c4222512492ef4a4434a9501ec", size = 6925605, upload-time = "2026-07-01T11:53:34.487Z" }, + { url = "https://files.pythonhosted.org/packages/eb/c0/4de58cf6633b9e3a6061ef4be6fb91fc3c90b812ece886f531e3c523d777/pillow-12.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:85f998ea1848bc6757289e739cfbdda3a04adfd58b02fc018ce54d754a5ce468", size = 6327788, upload-time = "2026-07-01T11:53:36.433Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/14d53682a19550dbbaf3b598f807d5457646c510805a44c7d7891cd1cd1a/pillow-12.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:25b9b82bb22e6e2b3cd07b39c68b7b862001226cb3dff7130d1cb914121b39ed", size = 7036288, upload-time = "2026-07-01T11:53:38.712Z" }, + { url = "https://files.pythonhosted.org/packages/38/1d/36279e3c77efe034e4cc2b0393ee74ffdb5a62391dacbf9b916154f5f0b8/pillow-12.3.0-cp310-cp310-win32.whl", hash = "sha256:37dc8f7bbb66efe481bb60defacef820c950c24713fb44962ed6aa2a50966de1", size = 6472396, upload-time = "2026-07-01T11:53:40.781Z" }, + { url = "https://files.pythonhosted.org/packages/48/7c/8fa0039574c476d7c6fa57dd7c32a130436877c6ec1e5ce1cc8ec44878c1/pillow-12.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:300557495eb45ebb8aec96c2da9c4be642fbf7cd937278b4013ba894ea8eb0eb", size = 7226887, upload-time = "2026-07-01T11:53:42.764Z" }, + { url = "https://files.pythonhosted.org/packages/fa/17/e324be141d173c1c919428066c3259f21c1b8982e564e01a4a81e96dbdcf/pillow-12.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:514435a37670e3e5e08f3945b68718b6ed329bb84367777e16f9f4dfe1e61a0f", size = 2568039, upload-time = "2026-07-01T11:53:45.372Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" }, + { url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, + { url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, + { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" }, + { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, + { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/85/e2/73c77d218410b14f5f2d565e8a998d5317b7b9c75368d29985139f7a46f0/pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8", size = 5350344, upload-time = "2026-07-01T11:54:57.657Z" }, + { url = "https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0", size = 4780131, upload-time = "2026-07-01T11:54:59.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/77f3f793fed8efc7d243f21b33c5a3f0d1c97ee70346d3db855587e155ff/pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a", size = 6467209, upload-time = "2026-07-01T11:55:10.408Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e0/492879f69d94f91f60fc8cd05ba03650e9520afebb2fb7aa12777d7c7f38/pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d", size = 7237707, upload-time = "2026-07-01T11:55:12.745Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ac/6b11f2875f1c2ac040d84e1bbf9cf22a88038f901ca1037898b280b38365/pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838", size = 2565995, upload-time = "2026-07-01T11:55:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/52/69/c2208e56af9bfc1913afb24020297a691eb1d4ef688474c8a04913f65e04/pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e", size = 5352503, upload-time = "2026-07-01T11:55:17.076Z" }, + { url = "https://files.pythonhosted.org/packages/07/70/e5686d753e898a45d778ff1718dba8516ead6ab6b95d85fc8c4b70650cf2/pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17", size = 4782956, upload-time = "2026-07-01T11:55:19.448Z" }, + { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, + { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, + { url = "https://files.pythonhosted.org/packages/23/26/fcb2f6e37175b04f53570b59937867e2b80ee1685e744023153028fc14f9/pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7", size = 6474125, upload-time = "2026-07-01T11:55:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/de/3634abee5f1c9e13c56787b7d5517b0ba8d6de51700b95578cf338349c9f/pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c", size = 7242939, upload-time = "2026-07-01T11:55:34.044Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2a/fd13f8eb24de5714a6eb444a3d67e2842c6c576e159a43793adf23051351/pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45", size = 2567506, upload-time = "2026-07-01T11:55:35.988Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, + { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, + { url = "https://files.pythonhosted.org/packages/12/40/d306fc2c8e4d45d7f175c77edca7063be7b86fe7fe6e68f4353bf71d808c/pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f", size = 5350370, upload-time = "2026-07-01T11:55:44.028Z" }, + { url = "https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701", size = 4780147, upload-time = "2026-07-01T11:55:46.073Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, + { url = "https://files.pythonhosted.org/packages/54/76/a09cc3ccc8d773a7283d34c38bec1708f9e3cc932093cbc4c5e71ac4060b/pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827", size = 6467375, upload-time = "2026-07-01T11:55:57.769Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/1846c49ba3b1d5550392a4bbd06d6fb4578e1cd91a803198b5c90f5f7d53/pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5", size = 7237048, upload-time = "2026-07-01T11:55:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bb/89f35dcc79610423f9f195504d7def7f0d1416a711541b42867e25fe3412/pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658", size = 2566006, upload-time = "2026-07-01T11:56:02.143Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/707027ba09942dfa2c28759b5c222d769290a41c6d20ea60ec250801941f/pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf", size = 5352509, upload-time = "2026-07-01T11:56:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6d/00352fa25332c2569cd387851f568cc5a4b75a9adbfb37ac4fbce4c02eec/pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64", size = 4783167, upload-time = "2026-07-01T11:56:06.631Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, + { url = "https://files.pythonhosted.org/packages/18/f0/a5595c1e8c3ae44b9828cb2f0fa8155e5095ef04d6327b8f61cf44a3df85/pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8", size = 6474384, upload-time = "2026-07-01T11:56:18.855Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/62bcd9f844984c5938d3b05264a61d797a29d3e0812341a8204af70bbdee/pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418", size = 7243537, upload-time = "2026-07-01T11:56:21.214Z" }, + { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, + { url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" }, ] [[package]] @@ -2152,11 +2318,11 @@ wheels = [ [[package]] name = "platformdirs" -version = "4.9.6" +version = "4.10.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" } +sdist = { url = "https://files.pythonhosted.org/packages/52/cd/4f25b2f95b23f5d2c9c1fe43e49841bff5800562149b2666afc09309aa8f/platformdirs-4.10.1.tar.gz", hash = "sha256:ceab4084426fe6319ce18e86deada8ab1b7487c7aee7040c55e277c9ae793695", size = 31678, upload-time = "2026-07-18T03:53:43.808Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" }, + { url = "https://files.pythonhosted.org/packages/ec/73/6fd0bb9ce84138c3857f12e9de63bc901852975a092d545f18087a204aa2/platformdirs-4.10.1-py3-none-any.whl", hash = "sha256:0e4eff26be2d75293977f7cddc153fd9b8eaa7fb0c7b64ffe4076cb443117443", size = 22906, upload-time = "2026-07-18T03:53:42.576Z" }, ] [[package]] @@ -2179,26 +2345,26 @@ wheels = [ [[package]] name = "prek" -version = "0.3.11" +version = "0.4.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/60/5b980c70525ca5f0d17942d8eae13b399051aa384413366fe5df229712ea/prek-0.3.11.tar.gz", hash = "sha256:c4cf77848009503c58d80ff216e32af45b63ea49652bb5546748c1ebfd4d9847", size = 433440, upload-time = "2026-04-27T04:22:59.923Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/54/edc21e275f9fa3540d4d98cf349c2de11621d6729cc401bb7aedf563609e/prek-0.4.10.tar.gz", hash = "sha256:db3122f4e780eb4587635e6a83df881caf2dbb1eb7799d1cca51158216d6f33b", size = 502565, upload-time = "2026-07-16T10:13:00.788Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/2a/3392fa7d1fd1ce538915baa7597e7203bbe888367a8b15bfd51ca74d4714/prek-0.3.11-py3-none-linux_armv6l.whl", hash = "sha256:787e605716cfdc86ec01e7c5cf62799f39c28d49de5e37d75595c8e6248cb0f3", size = 5423112, upload-time = "2026-04-27T04:22:52.659Z" }, - { url = "https://files.pythonhosted.org/packages/a9/b0/3fc653b30b70d6c2714fc56bcfe1c2439437fc38f60b72bc300603ace4cd/prek-0.3.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ef1f37187ca52d75ba9c46b53007476c4eab2c3f11bd23defd57a81c62d90442", size = 5801382, upload-time = "2026-04-27T04:23:04.464Z" }, - { url = "https://files.pythonhosted.org/packages/2e/46/39aedc7843c3703f1f43b686622e4f8cd123e03b87a163e5c8f2fbd56cda/prek-0.3.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e0d0828a1b50447502ea1be3f5a84da474fdca558cd5d76a1a5205169bb808c7", size = 5370817, upload-time = "2026-04-27T04:22:49.277Z" }, - { url = "https://files.pythonhosted.org/packages/15/83/df5f3aeacbdea96a88c4f06c98d3932469711fed4e3bf5b703dd6507abe7/prek-0.3.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:bf49464b526ee36d2130baf60ab9580560bfaa60efd2997328e6d6671e209014", size = 5621405, upload-time = "2026-04-27T04:23:10.58Z" }, - { url = "https://files.pythonhosted.org/packages/8f/f2/e32c9720747a327669863a4f92d05b9e6fadb851e903b0d7310a97c956a4/prek-0.3.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac344529f0d34757c7c95f65e66b9f6440a691f826eaf43f503247bd22023558", size = 5339780, upload-time = "2026-04-27T04:22:47.614Z" }, - { url = "https://files.pythonhosted.org/packages/29/2e/0e2f71b63bc2e5372575d5c1574b0666d2f90d30da51ed706a32cbf465a0/prek-0.3.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83672d963f249e2f246d3bec97f8fd2e8032e70da0a7d9acb2fa38af76dd82d2", size = 5735277, upload-time = "2026-04-27T04:23:12.437Z" }, - { url = "https://files.pythonhosted.org/packages/09/46/88abf51ac88eeff1ad2fe7d1797ca1fea43eb1ac1ddb8331463ac5b27ed2/prek-0.3.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef70957195d2896a30dd849e64f88344df7bb51af9c950cf16bd11519e7424b0", size = 6622420, upload-time = "2026-04-27T04:23:05.982Z" }, - { url = "https://files.pythonhosted.org/packages/5d/b6/592028a45b084a68b76c7edef909c789d1c96b26761388f63659beef7166/prek-0.3.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f0cc07d2cdb5fe2882015d5fdafc9af98b4c560d4caa1ae948caeab4341b79", size = 6020038, upload-time = "2026-04-27T04:22:54.367Z" }, - { url = "https://files.pythonhosted.org/packages/ca/f7/e97f55a1645a2e9becffeee28892ad8bb66cd144dabfa4392ea8e2674bbe/prek-0.3.11-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:d7554b436dae2ec97f4351a46817e3561657244307d1c0915f355b859f4fab71", size = 5622539, upload-time = "2026-04-27T04:23:01.314Z" }, - { url = "https://files.pythonhosted.org/packages/41/e2/f3119eef6b621782ad216a86d449609858ea34c57cf4a40fc6dc80556d7e/prek-0.3.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:caba5d635a5b64b7ac64d903f29b043ca5b0d9d9693543a0ef331ade89e6ad3f", size = 5440681, upload-time = "2026-04-27T04:23:07.422Z" }, - { url = "https://files.pythonhosted.org/packages/04/62/22dd4f59a47654faeebe74651182ecc48d436542646cc92723052dfd9a45/prek-0.3.11-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:c95a63f19dde48e84b70bd63a235670834af15fa4df8b85d8b7894dd5bc419a9", size = 5314773, upload-time = "2026-04-27T04:22:57.912Z" }, - { url = "https://files.pythonhosted.org/packages/bb/94/a8361462acb8d8f5b8505255b95ffbfc2ee0872a79b4e066eb330692f7be/prek-0.3.11-py3-none-musllinux_1_1_i686.whl", hash = "sha256:7353b45f44a386c676fe96ba72a5ee326b676f789339f405cf6f1d69a1707194", size = 5596208, upload-time = "2026-04-27T04:23:09.08Z" }, - { url = "https://files.pythonhosted.org/packages/04/0c/5f065b86bbeb9977074a055d8a05e90c7201f6c4c7032dada61739b5f8cb/prek-0.3.11-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:39f4e86176ccbb70c098df6abbc8e36c1d86cb81281abe92fb79dcd572418214", size = 6132833, upload-time = "2026-04-27T04:22:56.054Z" }, - { url = "https://files.pythonhosted.org/packages/19/0c/8ab0ae140201dcee505f58b60abbe56bd05ac96b821a6866f6f90c4d971f/prek-0.3.11-py3-none-win32.whl", hash = "sha256:35d2361049653a3dcf27227b7f1b340c5c42a12c0e0361c4b785921bfd125839", size = 5120856, upload-time = "2026-04-27T04:23:02.752Z" }, - { url = "https://files.pythonhosted.org/packages/57/05/9844c1125d3714f6f6c7b475884128a4b0c6c3ee0cd208ead44ca8174687/prek-0.3.11-py3-none-win_amd64.whl", hash = "sha256:a387689cd2e182f92dbb681151ee5a04f494fe97e95d6d783875da90b950e6d5", size = 5510916, upload-time = "2026-04-27T04:22:45.704Z" }, - { url = "https://files.pythonhosted.org/packages/ff/13/24b0288c553dc8d61f44c4d0746fe9bb1e1bd29d1e70571658536e4c0f72/prek-0.3.11-py3-none-win_arm64.whl", hash = "sha256:e4a8f900378a6657c7eb2fc4b12fa5c934edf209d0a24544539842479ec16e0b", size = 5345988, upload-time = "2026-04-27T04:22:50.918Z" }, + { url = "https://files.pythonhosted.org/packages/db/e7/5a63528ba7b95b64f38db3e253aed49ee8e5e8ba16589889d2b7f809edb7/prek-0.4.10-py3-none-linux_armv6l.whl", hash = "sha256:023f302741d79301346c3088ba43a9592aff0ecdbe5ddc3019fa9b1183319c5e", size = 5694609, upload-time = "2026-07-16T10:12:26.352Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ef/ee9e6bf9a5ce242e9e4e66ac4e2e9042a0f6fd9f367cee18ad404456e93d/prek-0.4.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:72adc707e16f97564bbae08d22b222ac3bb2491f8fbfb5a0754f80d472c28a71", size = 6044037, upload-time = "2026-07-16T10:12:28.539Z" }, + { url = "https://files.pythonhosted.org/packages/68/7e/da08cc39e5348ccb9234e63a21ee56861f72e8497d6a78f0db1ccae6515d/prek-0.4.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:04c9321957e1b32e1fc7cf60bb4f90bba3761f8659d5551ed04f96e25596de49", size = 5535983, upload-time = "2026-07-16T10:12:30.691Z" }, + { url = "https://files.pythonhosted.org/packages/30/c6/0486a35bb687a9beac7a5810bd1104c6da56d469b30b1eeaeefd03c99da2/prek-0.4.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:e66ccf6c5e4ebadd05cd98cb338d7f553e4d27aa243cf91279c5a569b3cdccc7", size = 5862085, upload-time = "2026-07-16T10:12:33.042Z" }, + { url = "https://files.pythonhosted.org/packages/52/39/277fe17ae1f121e532e3942456f5a6d01ddacfbc550e481dcb359be7a1b0/prek-0.4.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63f9061d75a50ef0ca92c4b596ad352937a845df80758244950e513b27e9e18f", size = 5605697, upload-time = "2026-07-16T10:12:35.498Z" }, + { url = "https://files.pythonhosted.org/packages/ad/a1/08354af3e000f2656fad086690d834eab6c04631ff41313a219ea6232199/prek-0.4.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c2ff7110e4bfaafbbab13c2893a337081aca61ed797f14b6b224d2ea9741eef", size = 6034111, upload-time = "2026-07-16T10:12:37.545Z" }, + { url = "https://files.pythonhosted.org/packages/e4/74/4702396c8d486132e5ce009ab56a0b37f50cb6866830d371f2617b7bdfdc/prek-0.4.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b696a05542e79aa27bcce68d1792e77f4fe6f9c6b012b34d74d62f964f3c72d", size = 6787203, upload-time = "2026-07-16T10:12:40.031Z" }, + { url = "https://files.pythonhosted.org/packages/90/29/b5d5d6fb87ebd64b37471e3e79761de9983f85e14d69c522efe7af6620ce/prek-0.4.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:431b44d6054e72815b4b05e1173596dfd02a7f7461211d40a2e3117e414642ad", size = 6261333, upload-time = "2026-07-16T10:12:42.216Z" }, + { url = "https://files.pythonhosted.org/packages/94/d6/54ba696d19f7efdc184093353cce713a850aef9c3556e23faeecafa22e94/prek-0.4.10-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:ccbd2b4fd1df790087ba18b4506f680471922a5f13714f19801568434a040dee", size = 5867761, upload-time = "2026-07-16T10:12:44.329Z" }, + { url = "https://files.pythonhosted.org/packages/be/7d/3975098aa2baaabfc10f99f9fcf78045c4f10851beed8e9812b6a2688eab/prek-0.4.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:479e7480b447191aa5c6ed67e80f081d0f5ee4e878b140f4d2cee44165395f1c", size = 5714412, upload-time = "2026-07-16T10:12:46.297Z" }, + { url = "https://files.pythonhosted.org/packages/97/c0/3e0aac190fe95fdef98526343559b61d4d9fd54444c8c9137ba02412afe1/prek-0.4.10-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:0bb7451025cbd2b68e480a13cf665d7a5c87c8b87bf18549a78985c17df817ed", size = 5578145, upload-time = "2026-07-16T10:12:48.261Z" }, + { url = "https://files.pythonhosted.org/packages/d7/44/7b26035534204b8b8a9d5e625479201e616413d287262f557cb32e1f8d77/prek-0.4.10-py3-none-musllinux_1_1_i686.whl", hash = "sha256:4fb047e5776676805794574b2d7b178cb3ab536793aadf172419fcda56b34a57", size = 5889245, upload-time = "2026-07-16T10:12:50.818Z" }, + { url = "https://files.pythonhosted.org/packages/7e/6c/178a9d768876b4211a1bf63907fe308ae02d173639bcf41cea3c5eed35c1/prek-0.4.10-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:08318818d19caf79643babb89f872c92fda134a622b4731df1d6ed61e29d2d26", size = 6372849, upload-time = "2026-07-16T10:12:52.952Z" }, + { url = "https://files.pythonhosted.org/packages/4d/84/d5f5ac8193602883f9dd1d675d9d4084e34fbe3ed2ef50a0c336d8a53d8f/prek-0.4.10-py3-none-win32.whl", hash = "sha256:092872714dcde480a662bbdd98b980b248c2d3e10543d4d53a3a58cc9e5b35b0", size = 5413005, upload-time = "2026-07-16T10:12:55.113Z" }, + { url = "https://files.pythonhosted.org/packages/41/63/9e648fda10bc02c9b6ba305f93b6a6e4fd37d23d13a269a9d2d6bb44eaa1/prek-0.4.10-py3-none-win_amd64.whl", hash = "sha256:3d323a18d0f8c50e474a8fa29fb93bd2db680116d8afb19b76e72ad4667f58e6", size = 5799075, upload-time = "2026-07-16T10:12:56.963Z" }, + { url = "https://files.pythonhosted.org/packages/22/74/b34d8c80cec8dccc7b922c75b9dca62b18b603b5ed2eea93c9d7c2928d2d/prek-0.4.10-py3-none-win_arm64.whl", hash = "sha256:5e93865ef96756c4a26f37ece04ad514abbc19ae6a23ed1a507b6314e6a0d2fb", size = 5563955, upload-time = "2026-07-16T10:12:59.07Z" }, ] [[package]] @@ -2215,116 +2381,130 @@ wheels = [ [[package]] name = "propcache" -version = "0.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/0e/934b541323035566a9af292dba85a195f7b78179114f2c6ebb24551118a9/propcache-0.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db", size = 79534, upload-time = "2025-10-08T19:46:02.083Z" }, - { url = "https://files.pythonhosted.org/packages/a1/6b/db0d03d96726d995dc7171286c6ba9d8d14251f37433890f88368951a44e/propcache-0.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8", size = 45526, upload-time = "2025-10-08T19:46:03.884Z" }, - { url = "https://files.pythonhosted.org/packages/e4/c3/82728404aea669e1600f304f2609cde9e665c18df5a11cdd57ed73c1dceb/propcache-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925", size = 47263, upload-time = "2025-10-08T19:46:05.405Z" }, - { url = "https://files.pythonhosted.org/packages/df/1b/39313ddad2bf9187a1432654c38249bab4562ef535ef07f5eb6eb04d0b1b/propcache-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21", size = 201012, upload-time = "2025-10-08T19:46:07.165Z" }, - { url = "https://files.pythonhosted.org/packages/5b/01/f1d0b57d136f294a142acf97f4ed58c8e5b974c21e543000968357115011/propcache-0.4.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5", size = 209491, upload-time = "2025-10-08T19:46:08.909Z" }, - { url = "https://files.pythonhosted.org/packages/a1/c8/038d909c61c5bb039070b3fb02ad5cccdb1dde0d714792e251cdb17c9c05/propcache-0.4.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db", size = 215319, upload-time = "2025-10-08T19:46:10.7Z" }, - { url = "https://files.pythonhosted.org/packages/08/57/8c87e93142b2c1fa2408e45695205a7ba05fb5db458c0bf5c06ba0e09ea6/propcache-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7", size = 196856, upload-time = "2025-10-08T19:46:12.003Z" }, - { url = "https://files.pythonhosted.org/packages/42/df/5615fec76aa561987a534759b3686008a288e73107faa49a8ae5795a9f7a/propcache-0.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4", size = 193241, upload-time = "2025-10-08T19:46:13.495Z" }, - { url = "https://files.pythonhosted.org/packages/d5/21/62949eb3a7a54afe8327011c90aca7e03547787a88fb8bd9726806482fea/propcache-0.4.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60", size = 190552, upload-time = "2025-10-08T19:46:14.938Z" }, - { url = "https://files.pythonhosted.org/packages/30/ee/ab4d727dd70806e5b4de96a798ae7ac6e4d42516f030ee60522474b6b332/propcache-0.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f", size = 200113, upload-time = "2025-10-08T19:46:16.695Z" }, - { url = "https://files.pythonhosted.org/packages/8a/0b/38b46208e6711b016aa8966a3ac793eee0d05c7159d8342aa27fc0bc365e/propcache-0.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900", size = 200778, upload-time = "2025-10-08T19:46:18.023Z" }, - { url = "https://files.pythonhosted.org/packages/cf/81/5abec54355ed344476bee711e9f04815d4b00a311ab0535599204eecc257/propcache-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c", size = 193047, upload-time = "2025-10-08T19:46:19.449Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b6/1f237c04e32063cb034acd5f6ef34ef3a394f75502e72703545631ab1ef6/propcache-0.4.1-cp310-cp310-win32.whl", hash = "sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb", size = 38093, upload-time = "2025-10-08T19:46:20.643Z" }, - { url = "https://files.pythonhosted.org/packages/a6/67/354aac4e0603a15f76439caf0427781bcd6797f370377f75a642133bc954/propcache-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37", size = 41638, upload-time = "2025-10-08T19:46:21.935Z" }, - { url = "https://files.pythonhosted.org/packages/e0/e1/74e55b9fd1a4c209ff1a9a824bf6c8b3d1fc5a1ac3eabe23462637466785/propcache-0.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581", size = 38229, upload-time = "2025-10-08T19:46:23.368Z" }, - { url = "https://files.pythonhosted.org/packages/8c/d4/4e2c9aaf7ac2242b9358f98dccd8f90f2605402f5afeff6c578682c2c491/propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf", size = 80208, upload-time = "2025-10-08T19:46:24.597Z" }, - { url = "https://files.pythonhosted.org/packages/c2/21/d7b68e911f9c8e18e4ae43bdbc1e1e9bbd971f8866eb81608947b6f585ff/propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5", size = 45777, upload-time = "2025-10-08T19:46:25.733Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1d/11605e99ac8ea9435651ee71ab4cb4bf03f0949586246476a25aadfec54a/propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e", size = 47647, upload-time = "2025-10-08T19:46:27.304Z" }, - { url = "https://files.pythonhosted.org/packages/58/1a/3c62c127a8466c9c843bccb503d40a273e5cc69838805f322e2826509e0d/propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566", size = 214929, upload-time = "2025-10-08T19:46:28.62Z" }, - { url = "https://files.pythonhosted.org/packages/56/b9/8fa98f850960b367c4b8fe0592e7fc341daa7a9462e925228f10a60cf74f/propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165", size = 221778, upload-time = "2025-10-08T19:46:30.358Z" }, - { url = "https://files.pythonhosted.org/packages/46/a6/0ab4f660eb59649d14b3d3d65c439421cf2f87fe5dd68591cbe3c1e78a89/propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc", size = 228144, upload-time = "2025-10-08T19:46:32.607Z" }, - { url = "https://files.pythonhosted.org/packages/52/6a/57f43e054fb3d3a56ac9fc532bc684fc6169a26c75c353e65425b3e56eef/propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48", size = 210030, upload-time = "2025-10-08T19:46:33.969Z" }, - { url = "https://files.pythonhosted.org/packages/40/e2/27e6feebb5f6b8408fa29f5efbb765cd54c153ac77314d27e457a3e993b7/propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570", size = 208252, upload-time = "2025-10-08T19:46:35.309Z" }, - { url = "https://files.pythonhosted.org/packages/9e/f8/91c27b22ccda1dbc7967f921c42825564fa5336a01ecd72eb78a9f4f53c2/propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85", size = 202064, upload-time = "2025-10-08T19:46:36.993Z" }, - { url = "https://files.pythonhosted.org/packages/f2/26/7f00bd6bd1adba5aafe5f4a66390f243acab58eab24ff1a08bebb2ef9d40/propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e", size = 212429, upload-time = "2025-10-08T19:46:38.398Z" }, - { url = "https://files.pythonhosted.org/packages/84/89/fd108ba7815c1117ddca79c228f3f8a15fc82a73bca8b142eb5de13b2785/propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757", size = 216727, upload-time = "2025-10-08T19:46:39.732Z" }, - { url = "https://files.pythonhosted.org/packages/79/37/3ec3f7e3173e73f1d600495d8b545b53802cbf35506e5732dd8578db3724/propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f", size = 205097, upload-time = "2025-10-08T19:46:41.025Z" }, - { url = "https://files.pythonhosted.org/packages/61/b0/b2631c19793f869d35f47d5a3a56fb19e9160d3c119f15ac7344fc3ccae7/propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1", size = 38084, upload-time = "2025-10-08T19:46:42.693Z" }, - { url = "https://files.pythonhosted.org/packages/f4/78/6cce448e2098e9f3bfc91bb877f06aa24b6ccace872e39c53b2f707c4648/propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6", size = 41637, upload-time = "2025-10-08T19:46:43.778Z" }, - { url = "https://files.pythonhosted.org/packages/9c/e9/754f180cccd7f51a39913782c74717c581b9cc8177ad0e949f4d51812383/propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239", size = 38064, upload-time = "2025-10-08T19:46:44.872Z" }, - { url = "https://files.pythonhosted.org/packages/a2/0f/f17b1b2b221d5ca28b4b876e8bb046ac40466513960646bda8e1853cdfa2/propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2", size = 80061, upload-time = "2025-10-08T19:46:46.075Z" }, - { url = "https://files.pythonhosted.org/packages/76/47/8ccf75935f51448ba9a16a71b783eb7ef6b9ee60f5d14c7f8a8a79fbeed7/propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403", size = 46037, upload-time = "2025-10-08T19:46:47.23Z" }, - { url = "https://files.pythonhosted.org/packages/0a/b6/5c9a0e42df4d00bfb4a3cbbe5cf9f54260300c88a0e9af1f47ca5ce17ac0/propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207", size = 47324, upload-time = "2025-10-08T19:46:48.384Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d3/6c7ee328b39a81ee877c962469f1e795f9db87f925251efeb0545e0020d0/propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72", size = 225505, upload-time = "2025-10-08T19:46:50.055Z" }, - { url = "https://files.pythonhosted.org/packages/01/5d/1c53f4563490b1d06a684742cc6076ef944bc6457df6051b7d1a877c057b/propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367", size = 230242, upload-time = "2025-10-08T19:46:51.815Z" }, - { url = "https://files.pythonhosted.org/packages/20/e1/ce4620633b0e2422207c3cb774a0ee61cac13abc6217763a7b9e2e3f4a12/propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4", size = 238474, upload-time = "2025-10-08T19:46:53.208Z" }, - { url = "https://files.pythonhosted.org/packages/46/4b/3aae6835b8e5f44ea6a68348ad90f78134047b503765087be2f9912140ea/propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf", size = 221575, upload-time = "2025-10-08T19:46:54.511Z" }, - { url = "https://files.pythonhosted.org/packages/6e/a5/8a5e8678bcc9d3a1a15b9a29165640d64762d424a16af543f00629c87338/propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3", size = 216736, upload-time = "2025-10-08T19:46:56.212Z" }, - { url = "https://files.pythonhosted.org/packages/f1/63/b7b215eddeac83ca1c6b934f89d09a625aa9ee4ba158338854c87210cc36/propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778", size = 213019, upload-time = "2025-10-08T19:46:57.595Z" }, - { url = "https://files.pythonhosted.org/packages/57/74/f580099a58c8af587cac7ba19ee7cb418506342fbbe2d4a4401661cca886/propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6", size = 220376, upload-time = "2025-10-08T19:46:59.067Z" }, - { url = "https://files.pythonhosted.org/packages/c4/ee/542f1313aff7eaf19c2bb758c5d0560d2683dac001a1c96d0774af799843/propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9", size = 226988, upload-time = "2025-10-08T19:47:00.544Z" }, - { url = "https://files.pythonhosted.org/packages/8f/18/9c6b015dd9c6930f6ce2229e1f02fb35298b847f2087ea2b436a5bfa7287/propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75", size = 215615, upload-time = "2025-10-08T19:47:01.968Z" }, - { url = "https://files.pythonhosted.org/packages/80/9e/e7b85720b98c45a45e1fca6a177024934dc9bc5f4d5dd04207f216fc33ed/propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8", size = 38066, upload-time = "2025-10-08T19:47:03.503Z" }, - { url = "https://files.pythonhosted.org/packages/54/09/d19cff2a5aaac632ec8fc03737b223597b1e347416934c1b3a7df079784c/propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db", size = 41655, upload-time = "2025-10-08T19:47:04.973Z" }, - { url = "https://files.pythonhosted.org/packages/68/ab/6b5c191bb5de08036a8c697b265d4ca76148efb10fa162f14af14fb5f076/propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1", size = 37789, upload-time = "2025-10-08T19:47:06.077Z" }, - { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, - { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, - { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, - { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, - { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, - { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, - { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, - { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, - { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, - { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, - { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, - { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, - { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, - { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, - { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, - { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, - { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, - { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, - { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, - { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, - { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, - { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, - { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, - { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, - { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, - { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, - { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, - { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, - { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, - { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, - { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, - { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, - { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, - { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, - { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, - { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, - { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, - { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, - { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, - { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, - { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, - { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, - { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, - { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, - { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, - { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, - { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, - { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, - { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, - { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, - { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, - { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, - { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, - { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/44/c87281c333769159c50594f22610f77398a47ccbfbbf23074e744e86f87c/propcache-0.5.2.tar.gz", hash = "sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427", size = 50208, upload-time = "2026-05-08T21:02:12.199Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/56/030b7b4719d53085722893e0009dffb9236aa10bca1b12121bdc5626ef16/propcache-0.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b", size = 93417, upload-time = "2026-05-08T20:59:15.597Z" }, + { url = "https://files.pythonhosted.org/packages/1a/55/1140a8e067b8ec093a18a4ae7bb0045d9db65da38a08618ddc5e2f1994aa/propcache-0.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c", size = 53847, upload-time = "2026-05-08T20:59:17.096Z" }, + { url = "https://files.pythonhosted.org/packages/20/42/0e7443c90310498561addf346e7d57fe3c6ba1914e1ba938b5464c7bbfd2/propcache-0.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb", size = 53512, upload-time = "2026-05-08T20:59:18.64Z" }, + { url = "https://files.pythonhosted.org/packages/b7/db/cf51a71bab2009517d1a7f0ee07657e3bd446c4d69f67e6966cf17bcf956/propcache-0.5.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e", size = 58068, upload-time = "2026-05-08T20:59:20.683Z" }, + { url = "https://files.pythonhosted.org/packages/b7/43/39b6bdee9699fa1e1641c519feeb64a67e2a9f93bb465c70776b37a7333f/propcache-0.5.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e", size = 61020, upload-time = "2026-05-08T20:59:22.112Z" }, + { url = "https://files.pythonhosted.org/packages/26/0b/843726fbb0a29a8c5684fdb25971823638399f31e52e9d1f06a02dc9aa6b/propcache-0.5.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b", size = 62732, upload-time = "2026-05-08T20:59:23.805Z" }, + { url = "https://files.pythonhosted.org/packages/39/6e/899fed76dc1942b8a64193a4f059d7f1a2c7ef65085e8a9366ed8ec0d199/propcache-0.5.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d", size = 60140, upload-time = "2026-05-08T20:59:25.389Z" }, + { url = "https://files.pythonhosted.org/packages/ab/09/3da4be9b5b879219ad234aa535b3dd4a080ed1ad48d3a73ca07a9e798f22/propcache-0.5.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d", size = 60400, upload-time = "2026-05-08T20:59:27.238Z" }, + { url = "https://files.pythonhosted.org/packages/60/2f/09b72b874a9aa0044faf52a69807a6ed618e267ceaa9ec4a63195fa5b504/propcache-0.5.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0", size = 58155, upload-time = "2026-05-08T20:59:28.48Z" }, + { url = "https://files.pythonhosted.org/packages/8a/37/97489848c54c95578045473954f10956d619ce6a09e7ac137b71cdcb698b/propcache-0.5.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b", size = 57037, upload-time = "2026-05-08T20:59:30.146Z" }, + { url = "https://files.pythonhosted.org/packages/22/db/6c695285ccfc49012743ee9c98212b8c5dd0aed7b63cfd816d4a0f7a1601/propcache-0.5.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf", size = 61103, upload-time = "2026-05-08T20:59:31.626Z" }, + { url = "https://files.pythonhosted.org/packages/98/a9/1e500401ca593b0bdb6bf75a70bc2d723835fd53360edff6af70692c7546/propcache-0.5.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf", size = 60394, upload-time = "2026-05-08T20:59:32.829Z" }, + { url = "https://files.pythonhosted.org/packages/1f/87/f638b6e375eae0f30a1a2325d8b34fd85fdc785bb9960cf805f3bf1ec69a/propcache-0.5.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e", size = 63084, upload-time = "2026-05-08T20:59:35.964Z" }, + { url = "https://files.pythonhosted.org/packages/f6/18/884573f5d97b6d9eba68de759a82c901b7e39d7904d30f7b8d58d42d2a12/propcache-0.5.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274", size = 60999, upload-time = "2026-05-08T20:59:38.481Z" }, + { url = "https://files.pythonhosted.org/packages/8f/1a/c3915eb059ceec9e758a56e4cfd955292bc0f201be2176a46b76d94b303a/propcache-0.5.2-cp310-cp310-win32.whl", hash = "sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe", size = 39036, upload-time = "2026-05-08T20:59:40.323Z" }, + { url = "https://files.pythonhosted.org/packages/5b/02/1dfd5607501a602d19c1c449d2d193b7d1c611f9246b4059026a1189a80e/propcache-0.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d", size = 42190, upload-time = "2026-05-08T20:59:42.232Z" }, + { url = "https://files.pythonhosted.org/packages/57/93/f71588ad08b3e6f4b555b5ef215808a3c02b042d0151ad82fa6f15be677a/propcache-0.5.2-cp310-cp310-win_arm64.whl", hash = "sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5", size = 38545, upload-time = "2026-05-08T20:59:44.087Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f1/8a8cc1c2c7e7934ab77e0163414f736fadbc0f5e8dd9673b952355ac175b/propcache-0.5.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78", size = 90744, upload-time = "2026-05-08T20:59:45.799Z" }, + { url = "https://files.pythonhosted.org/packages/c2/f4/651b1225e976bd1a2ba5cfba0c29d096581c2636b437e3a9a7ab6276270a/propcache-0.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959", size = 52033, upload-time = "2026-05-08T20:59:47.408Z" }, + { url = "https://files.pythonhosted.org/packages/15/a8/8ede85d6aa1f79fc7dc2f8fd2c8d65920b8272c3892903c8a1affde48cfb/propcache-0.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7", size = 52754, upload-time = "2026-05-08T20:59:49.202Z" }, + { url = "https://files.pythonhosted.org/packages/7d/fe/b3551b41bbc2f5b5bb088fc6920567cd43101253e68fbaa261339eb96fe1/propcache-0.5.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511", size = 57573, upload-time = "2026-05-08T20:59:50.778Z" }, + { url = "https://files.pythonhosted.org/packages/83/27/ab851ebd1b7172e3e161f5f8d39e315d54a91bea246f01f4d872d3376aef/propcache-0.5.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660", size = 60645, upload-time = "2026-05-08T20:59:52.227Z" }, + { url = "https://files.pythonhosted.org/packages/95/7d/466b3d18022e9897cbda9c735c493c5bd747d7a4c6f5ea1480b4cec434b6/propcache-0.5.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66", size = 61563, upload-time = "2026-05-08T20:59:53.866Z" }, + { url = "https://files.pythonhosted.org/packages/27/1b/16ab7f2cf2041da2f60d156ba64c2484eadf9168075b4ff43c3ef60045af/propcache-0.5.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b", size = 58888, upload-time = "2026-05-08T20:59:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/0a/67/bb777ffd907633563bf35fd859c4ce97b0512c32f4633cf5d1eb7c33512b/propcache-0.5.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67", size = 59253, upload-time = "2026-05-08T20:59:57.075Z" }, + { url = "https://files.pythonhosted.org/packages/b9/42/64f8d90b73fd9cdc1499b48057ff6d9cd2a98a25734c9bb62ecf07e87061/propcache-0.5.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f", size = 57558, upload-time = "2026-05-08T20:59:58.602Z" }, + { url = "https://files.pythonhosted.org/packages/eb/02/dba5bc03c9041f2092ea55a449caf5dfe68352c6654511b29ba0654ddb69/propcache-0.5.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c", size = 55007, upload-time = "2026-05-08T20:59:59.837Z" }, + { url = "https://files.pythonhosted.org/packages/14/c0/43f649c7aa2a77a3b100d84e9dea3a483120ecb608bfe36ce49eaff517fe/propcache-0.5.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0", size = 60355, upload-time = "2026-05-08T21:00:01.144Z" }, + { url = "https://files.pythonhosted.org/packages/83/c0/435dafd27f1cb4a495381dae60e25883ccfe4020bb72818e8184c1678092/propcache-0.5.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6", size = 59057, upload-time = "2026-05-08T21:00:02.401Z" }, + { url = "https://files.pythonhosted.org/packages/53/ae/6e292df9135d659944e96cb3389258e4a663e5b2b5f6c217ef0ddc8d2f73/propcache-0.5.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27", size = 61938, upload-time = "2026-05-08T21:00:03.638Z" }, + { url = "https://files.pythonhosted.org/packages/0b/42/314ebc50d8159055411fd6b0bda322ff510e4b1f7d2e4927940ad0f6af20/propcache-0.5.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f", size = 59731, upload-time = "2026-05-08T21:00:04.881Z" }, + { url = "https://files.pythonhosted.org/packages/b8/9b/2da6dee38871c3c8772fabc2758325a5c9077d6d18c597737dc04dd884cd/propcache-0.5.2-cp311-cp311-win32.whl", hash = "sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0", size = 38966, upload-time = "2026-05-08T21:00:06.511Z" }, + { url = "https://files.pythonhosted.org/packages/42/4e/f17363fb58c0afe05b067361cb6d86ed2d29de6506779a27547c4d183075/propcache-0.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82", size = 42135, upload-time = "2026-05-08T21:00:08.088Z" }, + { url = "https://files.pythonhosted.org/packages/c6/eb/6af6685077d22e8b33358d3c548e3282706a0b3cd85044ffba4e5dd08e3b/propcache-0.5.2-cp311-cp311-win_arm64.whl", hash = "sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab", size = 38381, upload-time = "2026-05-08T21:00:09.692Z" }, + { url = "https://files.pythonhosted.org/packages/4a/cb/e27bc2b2737a0bb49962b275efa051e8f1c35a936df7d5139b6b658b7dc9/propcache-0.5.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba", size = 95887, upload-time = "2026-05-08T21:00:11.277Z" }, + { url = "https://files.pythonhosted.org/packages/e6/13/b8ae04c59392f8d11c6cd9fb4011d1dc7c86b81225c770280300e259ffe1/propcache-0.5.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a", size = 54654, upload-time = "2026-05-08T21:00:12.604Z" }, + { url = "https://files.pythonhosted.org/packages/2c/7d/49777a3e20b55863d4794384a38acd460c04157b0a00f8602b0d508b8431/propcache-0.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf", size = 55190, upload-time = "2026-05-08T21:00:13.935Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/085d0cd63062e84044e3f05797749c3f8e3938ff3aeb0eb2f69d43fafc91/propcache-0.5.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144", size = 59995, upload-time = "2026-05-08T21:00:15.526Z" }, + { url = "https://files.pythonhosted.org/packages/9c/42/32cf8e3009e92b2645cf1e944f701e8ea4e924dffde1ee26db860bcbf7e4/propcache-0.5.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9", size = 63422, upload-time = "2026-05-08T21:00:16.824Z" }, + { url = "https://files.pythonhosted.org/packages/9e/1b/f112433f99fc979431b87a39ef169e3f8df070d99a72792c56d6937ac48b/propcache-0.5.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42", size = 64342, upload-time = "2026-05-08T21:00:18.362Z" }, + { url = "https://files.pythonhosted.org/packages/14/15/5574111ae50dd6e879456888c0eadd4c5a869959775854e18e18a6b345f3/propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476", size = 61639, upload-time = "2026-05-08T21:00:19.692Z" }, + { url = "https://files.pythonhosted.org/packages/cc/da/4d775080b1490c0ae604acda868bd71aabe3a89ed16f2aa4339eb8a283e7/propcache-0.5.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba", size = 61588, upload-time = "2026-05-08T21:00:21.155Z" }, + { url = "https://files.pythonhosted.org/packages/04/ac/f076982cbe2195ee9cf32de5a1e46951d9fb399fc207f390562dd0fd8fb2/propcache-0.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a", size = 60029, upload-time = "2026-05-08T21:00:22.713Z" }, + { url = "https://files.pythonhosted.org/packages/70/60/189be62e0dd898dce3b331e1b8c7a543cd3a405ac0c81fe8ee8a9d5d77e1/propcache-0.5.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64", size = 56774, upload-time = "2026-05-08T21:00:24.001Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9e/93377b9c7939c1ffae98f878dee955efadfd638078bc86dbc21f9d52f651/propcache-0.5.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913", size = 63532, upload-time = "2026-05-08T21:00:25.545Z" }, + { url = "https://files.pythonhosted.org/packages/14/f9/590ef6cfb9b8028d516d287812ece32bb0bc5f11fbb9c8bf6b2e6313fec8/propcache-0.5.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1", size = 61592, upload-time = "2026-05-08T21:00:27.186Z" }, + { url = "https://files.pythonhosted.org/packages/b4/5e/70958b3034c297a630bba2f17ca7abc2d5f39a803ad7e370ab79d1ecd022/propcache-0.5.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33", size = 64788, upload-time = "2026-05-08T21:00:28.8Z" }, + { url = "https://files.pythonhosted.org/packages/12/fd/77fe5936d8c3086ca9048f7f415f122ed82e53884a9ec193646b42deef06/propcache-0.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a", size = 62514, upload-time = "2026-05-08T21:00:30.098Z" }, + { url = "https://files.pythonhosted.org/packages/cf/74/66bd798b5b3be70aa1b391f5cc9d6a0a5532d7fd3b19ec0b213e72e6ad9d/propcache-0.5.2-cp312-cp312-win32.whl", hash = "sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031", size = 39018, upload-time = "2026-05-08T21:00:31.622Z" }, + { url = "https://files.pythonhosted.org/packages/61/7c/5c0d34aa3024694d6dcb9271cdbdd08c4e47c1c0ad95ec7e7bc74cdea145/propcache-0.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42", size = 42322, upload-time = "2026-05-08T21:00:32.918Z" }, + { url = "https://files.pythonhosted.org/packages/4d/91/875812f1a3feb20ceba818ef39fbe4d92f1081e04ac815c822496d0d038b/propcache-0.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84", size = 38172, upload-time = "2026-05-08T21:00:35.124Z" }, + { url = "https://files.pythonhosted.org/packages/c5/09/f049e45385503fe67db75a6b6186a7b9f0c3930366dc960522c312a825b1/propcache-0.5.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a", size = 94457, upload-time = "2026-05-08T21:00:36.355Z" }, + { url = "https://files.pythonhosted.org/packages/6b/65/83d1d05655baf63113731bd5a1008435e14f8d1e5a06cbe4ec5b23ad7a31/propcache-0.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117", size = 53835, upload-time = "2026-05-08T21:00:38.072Z" }, + { url = "https://files.pythonhosted.org/packages/a9/12/a6ba6482bb5ea3260c000c9b20881c95fa11c6b30173715668259f844ed7/propcache-0.5.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098", size = 54545, upload-time = "2026-05-08T21:00:39.319Z" }, + { url = "https://files.pythonhosted.org/packages/a9/19/7fa086f5764c59ec8a8e157cd93aa8497acc00aba9dcdec56bfffb32602d/propcache-0.5.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4", size = 59886, upload-time = "2026-05-08T21:00:40.621Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e4/5d7663dc8235956c8f5281698a3af1d351d8820341ddd890f59d9a9127f2/propcache-0.5.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e", size = 63261, upload-time = "2026-05-08T21:00:41.775Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4a/15a03adee24d6350da4292caeac44c34c033d2afe5e87eb370f38854560f/propcache-0.5.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7", size = 64184, upload-time = "2026-05-08T21:00:43.018Z" }, + { url = "https://files.pythonhosted.org/packages/8b/c6/979176efdaa3d239e36d503d5af63a0a773b36662ed8f52e5b6a6d9fd40e/propcache-0.5.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d", size = 61534, upload-time = "2026-05-08T21:00:44.507Z" }, + { url = "https://files.pythonhosted.org/packages/c8/22/63e8cd1bae4c2d2be6493b6b7d10566ddafad88137cfbc99964a1119853c/propcache-0.5.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a", size = 61500, upload-time = "2026-05-08T21:00:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/60/5a/28e5d9acbac1cc9ccb67045e8c1b943aa8d79fdf39c93bd73cacd68008ea/propcache-0.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2", size = 59994, upload-time = "2026-05-08T21:00:47.093Z" }, + { url = "https://files.pythonhosted.org/packages/f3/40/db650677f554a95b9c01a7c9d93d629e93a15562f5deb4573c9ee136fed2/propcache-0.5.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa", size = 56884, upload-time = "2026-05-08T21:00:48.376Z" }, + { url = "https://files.pythonhosted.org/packages/80/45/70b39b89516ff8b96bf732fa6fded8cef20f293cb1508690101c3c07ec51/propcache-0.5.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853", size = 63464, upload-time = "2026-05-08T21:00:49.954Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e2/fa59d3a89eac5534293124af4f1d0d0ada091ce4a0ab4610ce03fd2bdd8d/propcache-0.5.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a", size = 61588, upload-time = "2026-05-08T21:00:51.281Z" }, + { url = "https://files.pythonhosted.org/packages/0b/97/efb547a55c4bc7381cfb202d6a2239ac621045277bc1ea5dfd3a7f0516c0/propcache-0.5.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704", size = 64667, upload-time = "2026-05-08T21:00:52.602Z" }, + { url = "https://files.pythonhosted.org/packages/92/56/f5c7d9b4b7595d5127da38974d791b2153f3d1eae6c674af3583ace92ad3/propcache-0.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4", size = 62463, upload-time = "2026-05-08T21:00:54.303Z" }, + { url = "https://files.pythonhosted.org/packages/bd/3b/484a3a65fc9f9f60c41dcd17b428bace5389544e2c680994534a20755066/propcache-0.5.2-cp313-cp313-win32.whl", hash = "sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d", size = 38621, upload-time = "2026-05-08T21:00:55.808Z" }, + { url = "https://files.pythonhosted.org/packages/1c/fd/3f0f10dba4dabad3bf53102be007abf55481067952bde0fdddff439e7c61/propcache-0.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757", size = 41649, upload-time = "2026-05-08T21:00:57.061Z" }, + { url = "https://files.pythonhosted.org/packages/90/ec/6ce619cc32bb500a482f811f9cd509368b4e58e638d13f2c68f370d6b475/propcache-0.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f", size = 37636, upload-time = "2026-05-08T21:00:58.646Z" }, + { url = "https://files.pythonhosted.org/packages/1b/82/c1d268bbbf2ef981c5bf0fbbe746db617c66e3bcefe431a1aa8943fbe23a/propcache-0.5.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d", size = 98872, upload-time = "2026-05-08T21:00:59.889Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d4/52c871e73e864e6b34c0e2d58ac1ec5ccd149497ddc7ad2137ae98323a35/propcache-0.5.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa", size = 56257, upload-time = "2026-05-08T21:01:01.195Z" }, + { url = "https://files.pythonhosted.org/packages/67/f0/9b90ca2a210b3d09bcfcd96ecd0f55545c091535abce2a45de2775cfd357/propcache-0.5.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94", size = 56696, upload-time = "2026-05-08T21:01:02.941Z" }, + { url = "https://files.pythonhosted.org/packages/9d/0e/6e9d4ba07c8e56e21ddec1e75f12148142b21ca83a51871babce095334f4/propcache-0.5.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164", size = 62378, upload-time = "2026-05-08T21:01:04.475Z" }, + { url = "https://files.pythonhosted.org/packages/65/19/c10badaa463dde8a27ce884f8ee2ec37e6035b7c9f5ff0c8f74f06f08dac/propcache-0.5.2-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f", size = 65283, upload-time = "2026-05-08T21:01:05.959Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b6/93bea99ca80e19cef6512a8580e5b7857bbe09422d9daa7fd4ef5723306c/propcache-0.5.2-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c", size = 66616, upload-time = "2026-05-08T21:01:07.228Z" }, + { url = "https://files.pythonhosted.org/packages/83/e4/5c7462e50625f051f37fb38b8224f7639f667184bbd34424ec83819bb1b7/propcache-0.5.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc", size = 63773, upload-time = "2026-05-08T21:01:08.514Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b6/99238894047b13c823be25027e736626cd414a52a5e30d2c3347c2733529/propcache-0.5.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f", size = 63664, upload-time = "2026-05-08T21:01:09.874Z" }, + { url = "https://files.pythonhosted.org/packages/85/1e/a3a1a63116a2b8edb415a8bb9a6f0c34bd03830b1e18e8ce2904e1dc1cf4/propcache-0.5.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb", size = 62643, upload-time = "2026-05-08T21:01:11.132Z" }, + { url = "https://files.pythonhosted.org/packages/e4/03/893cf147de2fc6543c5eaa07ad833170e7e2a2385725bbebe8c0503723bb/propcache-0.5.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751", size = 59595, upload-time = "2026-05-08T21:01:12.387Z" }, + { url = "https://files.pythonhosted.org/packages/86/3b/04c1a2e12c57766568ba75ba72b3bf2042818d4c1425fab6fc07155c7cff/propcache-0.5.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836", size = 65711, upload-time = "2026-05-08T21:01:13.676Z" }, + { url = "https://files.pythonhosted.org/packages/1c/34/80f8d0099f8d6bacc4de1624c85672681c8cd1149ca2da0e38fd120b817f/propcache-0.5.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f", size = 64247, upload-time = "2026-05-08T21:01:14.936Z" }, + { url = "https://files.pythonhosted.org/packages/f3/1a/8b08f3a5f1037e9e370c55883ceeeee0f6dd0416fb2d2d67b8bfc91f2a79/propcache-0.5.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55", size = 67102, upload-time = "2026-05-08T21:01:16.281Z" }, + { url = "https://files.pythonhosted.org/packages/34/68/8bdb7bb7756d76e005490649d10e4a8369e610c74d619f71e1aedf889e9c/propcache-0.5.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568", size = 64964, upload-time = "2026-05-08T21:01:17.57Z" }, + { url = "https://files.pythonhosted.org/packages/0a/aa/50fb0b5d3968b61a510926ff8b8465f1d6e976b3ab74496d7a4b9fc42515/propcache-0.5.2-cp313-cp313t-win32.whl", hash = "sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191", size = 42546, upload-time = "2026-05-08T21:01:18.946Z" }, + { url = "https://files.pythonhosted.org/packages/ae/4c/0ddbae64321bd4a95bcbfc19307238016b5b1fee645c84626c8d539e5b74/propcache-0.5.2-cp313-cp313t-win_amd64.whl", hash = "sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7", size = 46330, upload-time = "2026-05-08T21:01:20.162Z" }, + { url = "https://files.pythonhosted.org/packages/00/d9/9cddc8efb78d8af264c5ec9f6d10b62f57c515feda8d321595f56010fb23/propcache-0.5.2-cp313-cp313t-win_arm64.whl", hash = "sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96", size = 40521, upload-time = "2026-05-08T21:01:21.399Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ea/23ee535d90ce8bcc465a3028eb3cc0ce3bd1005f4bb27710b30587de798d/propcache-0.5.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999", size = 94662, upload-time = "2026-05-08T21:01:22.683Z" }, + { url = "https://files.pythonhosted.org/packages/b5/06/c5a52f419b5d8972f8d46a7577476090d8e3263ff589ce40b5ca4968d5be/propcache-0.5.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e", size = 53928, upload-time = "2026-05-08T21:01:23.986Z" }, + { url = "https://files.pythonhosted.org/packages/63/b1/4260d67d6bd85e58a66b72d54ce15d5de789b6f3870cc6bedf8ff9667401/propcache-0.5.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539", size = 54650, upload-time = "2026-05-08T21:01:25.305Z" }, + { url = "https://files.pythonhosted.org/packages/70/06/2f46c318e3307cd7a6a7481def374ce838c0fe20084b39dd54b0879d0e99/propcache-0.5.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e", size = 59912, upload-time = "2026-05-08T21:01:26.545Z" }, + { url = "https://files.pythonhosted.org/packages/4c/29/fe1aebec2ce57ab985a9c382bded1124431f85078113aa222c5d278430d4/propcache-0.5.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979", size = 63300, upload-time = "2026-05-08T21:01:27.937Z" }, + { url = "https://files.pythonhosted.org/packages/b4/18/2334b26768b6c82be8c69e83671b767d5ef426aa09b0cba6c2ea47816774/propcache-0.5.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80", size = 64208, upload-time = "2026-05-08T21:01:29.484Z" }, + { url = "https://files.pythonhosted.org/packages/2b/76/7f1bfd6afff4c5e38e36a3c6d68eb5f4b7311ea80baf693db78d95b603c4/propcache-0.5.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825", size = 61633, upload-time = "2026-05-08T21:01:31.068Z" }, + { url = "https://files.pythonhosted.org/packages/c4/46/b3ff8aba2b4953a3e50de2cf72f1b5748b8eca93b15f3dc2c84339084c09/propcache-0.5.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39", size = 61724, upload-time = "2026-05-08T21:01:32.374Z" }, + { url = "https://files.pythonhosted.org/packages/c5/01/814cfcafbcff954f94c01cf30e097ddc88a076b5440fbcf4570753437d40/propcache-0.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4", size = 60069, upload-time = "2026-05-08T21:01:33.67Z" }, + { url = "https://files.pythonhosted.org/packages/da/68/5c6f7622d510cc666a300687e06fd060c1a43361c0c9b20d284f06d8096a/propcache-0.5.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5", size = 57099, upload-time = "2026-05-08T21:01:34.915Z" }, + { url = "https://files.pythonhosted.org/packages/55/27/9cb0b4c679124085327957d42521c99dba04c88c90c3e55a6f0b633ebccc/propcache-0.5.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702", size = 63391, upload-time = "2026-05-08T21:01:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/f0/9d/7258aaa5bdf60fc6f27591eef6fe52768cb0beda7140be477c8b12c9794a/propcache-0.5.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3", size = 61626, upload-time = "2026-05-08T21:01:37.545Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0d/41c602003e8a9b16fe1e7eadf62c7bfba9d5474370b24200bf48b315f45f/propcache-0.5.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5", size = 64781, upload-time = "2026-05-08T21:01:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f3/38e66b1856e9bd079deea015bc4a55f7767c0e4db2f7dcf69e7e680ba4ce/propcache-0.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4", size = 62570, upload-time = "2026-05-08T21:01:40.415Z" }, + { url = "https://files.pythonhosted.org/packages/95/ca/bbfe9b910ce57dde8bb4876b4520fc02a4e89497c10de26be936758a3aaa/propcache-0.5.2-cp314-cp314-win32.whl", hash = "sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0", size = 39436, upload-time = "2026-05-08T21:01:41.654Z" }, + { url = "https://files.pythonhosted.org/packages/61/d2/45c9defbaa1ea297035d9d4cce9e8f80daafbf19319c6007f157c6256ea9/propcache-0.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c", size = 42373, upload-time = "2026-05-08T21:01:43.041Z" }, + { url = "https://files.pythonhosted.org/packages/44/68/9ea5103f41d5217d7d6ec24db90018e23aebec070c3f9a6e54d12b841fd8/propcache-0.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0", size = 38554, upload-time = "2026-05-08T21:01:44.336Z" }, + { url = "https://files.pythonhosted.org/packages/8a/81/fadf555f42d3b762eea8a53950b0489fdc0aa9da5f8ed9e10ce0a4e01b48/propcache-0.5.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb", size = 99395, upload-time = "2026-05-08T21:01:45.883Z" }, + { url = "https://files.pythonhosted.org/packages/f5/c9/c61e134a686949cf7971af3a390148b1156f7be81c73bc0cd12c873e2d48/propcache-0.5.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078", size = 56653, upload-time = "2026-05-08T21:01:47.307Z" }, + { url = "https://files.pythonhosted.org/packages/cb/73/daf935ea7048ddd7ec8eec5345b4a40b619d2d178b3c0a0900796bc3c794/propcache-0.5.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa", size = 56914, upload-time = "2026-05-08T21:01:48.573Z" }, + { url = "https://files.pythonhosted.org/packages/79/9f/aba959b435ea18617edd7cf0a7ad0b9c574b8fc7e3d2cd55fb59cb255d33/propcache-0.5.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917", size = 62567, upload-time = "2026-05-08T21:01:49.903Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a1/859942de9a791ff42f6141736f5b37749b8f53e65edfa49638c67dd67e6a/propcache-0.5.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe", size = 65542, upload-time = "2026-05-08T21:01:51.204Z" }, + { url = "https://files.pythonhosted.org/packages/b5/61/315bc0fd6c0fc7f80a528b8afd209e5fc4a875ea79571b91b8f50f442907/propcache-0.5.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03", size = 66845, upload-time = "2026-05-08T21:01:52.539Z" }, + { url = "https://files.pythonhosted.org/packages/47/f7/9f8122e3132e8e354ac41975ef8f1099be7d5a16bc7ae562734e993665c0/propcache-0.5.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335", size = 63985, upload-time = "2026-05-08T21:01:53.847Z" }, + { url = "https://files.pythonhosted.org/packages/c8/54/c317819ec157cbf6f35df9df9657a6f82daf34d5faf15948b2f639c2192e/propcache-0.5.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285", size = 63999, upload-time = "2026-05-08T21:01:55.179Z" }, + { url = "https://files.pythonhosted.org/packages/5a/56/387e3f7dfce0a9233df41fb888aa1c30222cb4bbbf09537c02dd9bd85fe2/propcache-0.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837", size = 62779, upload-time = "2026-05-08T21:01:57.489Z" }, + { url = "https://files.pythonhosted.org/packages/a1/9c/596784cb5824ed61ee960d3f8655a3f0993e107c6e98ab6c818b7fb92ccb/propcache-0.5.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8", size = 59796, upload-time = "2026-05-08T21:01:58.736Z" }, + { url = "https://files.pythonhosted.org/packages/c2/3d/1a6cfa1726a48542c1e8784a0761421476a5b68e09b7f36bf95eb954aaba/propcache-0.5.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366", size = 66023, upload-time = "2026-05-08T21:02:00.228Z" }, + { url = "https://files.pythonhosted.org/packages/e4/0e/05fd6990369477076e4e280bcb970de760fddf0161a46e988bc95f7940ec/propcache-0.5.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56", size = 64448, upload-time = "2026-05-08T21:02:01.888Z" }, + { url = "https://files.pythonhosted.org/packages/cd/86/5f8da315a4309c62c10c0b2516b17492d5d3bbe1bb862b96604db67e2a37/propcache-0.5.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d", size = 67329, upload-time = "2026-05-08T21:02:03.484Z" }, + { url = "https://files.pythonhosted.org/packages/da/d3/3368efe79ab21f0cdf86ef49895811c9cc933131d4cde1f28a624e22e712/propcache-0.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2", size = 65172, upload-time = "2026-05-08T21:02:04.745Z" }, + { url = "https://files.pythonhosted.org/packages/d5/07/127e8b0bacfb325396196f9d976a22453049b89b9b2b08477cc3145faa44/propcache-0.5.2-cp314-cp314t-win32.whl", hash = "sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821", size = 43813, upload-time = "2026-05-08T21:02:06.025Z" }, + { url = "https://files.pythonhosted.org/packages/88/fb/46dad6c0ae49ed230ab1b16c890c2b6314e2403e6c412976f4a72d64a527/propcache-0.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370", size = 47764, upload-time = "2026-05-08T21:02:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c4/a47d0a63aa309d10d59ede6e9d4cff03a344a79d1f0f4cd0cd74997b53e0/propcache-0.5.2-cp314-cp314t-win_arm64.whl", hash = "sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6", size = 41140, upload-time = "2026-05-08T21:02:09.065Z" }, + { url = "https://files.pythonhosted.org/packages/3a/ed/1cdcab6ba3d6ab7feca11fc14f0eeea80755bb53ef4e892079f31b10a25f/propcache-0.5.2-py3-none-any.whl", hash = "sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe", size = 14036, upload-time = "2026-05-08T21:02:10.673Z" }, ] [[package]] @@ -2366,7 +2546,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.13.3" +version = "2.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -2374,125 +2554,125 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d9/e4/40d09941a2cebcb20609b86a559817d5b9291c49dd6f8c87e5feffbe703a/pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d", size = 844068, upload-time = "2026-04-20T14:46:43.632Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/0a/fd7d723f8f8153418fb40cf9c940e82004fce7e987026b08a68a36dd3fe7/pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927", size = 471981, upload-time = "2026-04-20T14:46:41.402Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, ] [[package]] name = "pydantic-core" -version = "2.46.3" +version = "2.46.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2a/ef/f7abb56c49382a246fd2ce9c799691e3c3e7175ec74b14d99e798bcddb1a/pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c", size = 471412, upload-time = "2026-04-20T14:40:56.672Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/98/b50eb9a411e87483b5c65dba4fa430a06bac4234d3403a40e5a9905ebcd0/pydantic_core-2.46.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1", size = 2108971, upload-time = "2026-04-20T14:43:51.945Z" }, - { url = "https://files.pythonhosted.org/packages/08/4b/f364b9d161718ff2217160a4b5d41ce38de60aed91c3689ebffa1c939d23/pydantic_core-2.46.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f", size = 1949588, upload-time = "2026-04-20T14:44:10.386Z" }, - { url = "https://files.pythonhosted.org/packages/8f/8b/30bd03ee83b2f5e29f5ba8e647ab3c456bf56f2ec72fdbcc0215484a0854/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3", size = 1975986, upload-time = "2026-04-20T14:43:57.106Z" }, - { url = "https://files.pythonhosted.org/packages/3c/54/13ccf954d84ec275d5d023d5786e4aa48840bc9f161f2838dc98e1153518/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a", size = 2055830, upload-time = "2026-04-20T14:44:15.499Z" }, - { url = "https://files.pythonhosted.org/packages/be/0e/65f38125e660fdbd72aa858e7dfae893645cfa0e7b13d333e174a367cd23/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807", size = 2222340, upload-time = "2026-04-20T14:41:51.353Z" }, - { url = "https://files.pythonhosted.org/packages/d1/88/f3ab7739efe0e7e80777dbb84c59eb98518e3f57ea433206194c2e425272/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda", size = 2280727, upload-time = "2026-04-20T14:41:30.461Z" }, - { url = "https://files.pythonhosted.org/packages/2a/6d/c228219080817bec4982f9531cadb18da6aaa770fdeb114f49c237ac2c9f/pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57", size = 2092158, upload-time = "2026-04-20T14:44:07.305Z" }, - { url = "https://files.pythonhosted.org/packages/0f/b1/525a16711e7c6d61635fac3b0bd54600b5c5d9f60c6fc5aaab26b64a2297/pydantic_core-2.46.3-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045", size = 2116626, upload-time = "2026-04-20T14:42:34.118Z" }, - { url = "https://files.pythonhosted.org/packages/ef/7c/17d30673351439a6951bf54f564cf2443ab00ae264ec9df00e2efd710eb5/pydantic_core-2.46.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943", size = 2160691, upload-time = "2026-04-20T14:41:14.023Z" }, - { url = "https://files.pythonhosted.org/packages/86/66/af8adbcbc0886ead7f1a116606a534d75a307e71e6e08226000d51b880d2/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f", size = 2182543, upload-time = "2026-04-20T14:40:48.886Z" }, - { url = "https://files.pythonhosted.org/packages/b0/37/6de71e0f54c54a4190010f57deb749e1ddf75c568ada3b1320b70067f121/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4", size = 2324513, upload-time = "2026-04-20T14:42:36.121Z" }, - { url = "https://files.pythonhosted.org/packages/51/b1/9fc74ce94f603d5ef59ff258ca9c2c8fb902fb548d340a96f77f4d1c3b7f/pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a", size = 2361853, upload-time = "2026-04-20T14:43:24.886Z" }, - { url = "https://files.pythonhosted.org/packages/40/d0/4c652fc592db35f100279ee751d5a145aca1b9a7984b9684ba7c1b5b0535/pydantic_core-2.46.3-cp310-cp310-win32.whl", hash = "sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7", size = 1980465, upload-time = "2026-04-20T14:44:46.239Z" }, - { url = "https://files.pythonhosted.org/packages/27/b8/a920453c38afbe1f355e1ea0b0d94a0a3e0b0879d32d793108755fa171d5/pydantic_core-2.46.3-cp310-cp310-win_amd64.whl", hash = "sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6", size = 2073884, upload-time = "2026-04-20T14:43:01.201Z" }, - { url = "https://files.pythonhosted.org/packages/22/a2/1ba90a83e85a3f94c796b184f3efde9c72f2830dcda493eea8d59ba78e6d/pydantic_core-2.46.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5", size = 2106740, upload-time = "2026-04-20T14:41:20.932Z" }, - { url = "https://files.pythonhosted.org/packages/b6/f6/99ae893c89a0b9d3daec9f95487aa676709aa83f67643b3f0abaf4ab628a/pydantic_core-2.46.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c", size = 1948293, upload-time = "2026-04-20T14:43:42.115Z" }, - { url = "https://files.pythonhosted.org/packages/3e/b8/2e8e636dc9e3f16c2e16bf0849e24be82c5ee82c603c65fc0326666328fc/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e", size = 1973222, upload-time = "2026-04-20T14:41:57.841Z" }, - { url = "https://files.pythonhosted.org/packages/34/36/0e730beec4d83c5306f417afbd82ff237d9a21e83c5edf675f31ed84c1fe/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287", size = 2053852, upload-time = "2026-04-20T14:40:43.077Z" }, - { url = "https://files.pythonhosted.org/packages/4b/f0/3071131f47e39136a17814576e0fada9168569f7f8c0e6ac4d1ede6a4958/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe", size = 2221134, upload-time = "2026-04-20T14:43:03.349Z" }, - { url = "https://files.pythonhosted.org/packages/2f/a9/a2dc023eec5aa4b02a467874bad32e2446957d2adcab14e107eab502e978/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050", size = 2279785, upload-time = "2026-04-20T14:41:19.285Z" }, - { url = "https://files.pythonhosted.org/packages/0a/44/93f489d16fb63fbd41c670441536541f6e8cfa1e5a69f40bc9c5d30d8c90/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2", size = 2089404, upload-time = "2026-04-20T14:43:10.108Z" }, - { url = "https://files.pythonhosted.org/packages/2a/78/8692e3aa72b2d004f7a5d937f1dfdc8552ba26caf0bec75f342c40f00dec/pydantic_core-2.46.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa", size = 2114898, upload-time = "2026-04-20T14:44:51.475Z" }, - { url = "https://files.pythonhosted.org/packages/6a/62/e83133f2e7832532060175cebf1f13748f4c7e7e7165cdd1f611f174494b/pydantic_core-2.46.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c", size = 2157856, upload-time = "2026-04-20T14:43:46.64Z" }, - { url = "https://files.pythonhosted.org/packages/6d/ec/6a500e3ad7718ee50583fae79c8651f5d37e3abce1fa9ae177ae65842c53/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf", size = 2180168, upload-time = "2026-04-20T14:42:00.302Z" }, - { url = "https://files.pythonhosted.org/packages/d8/53/8267811054b1aa7fc1dc7ded93812372ef79a839f5e23558136a6afbfde1/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b", size = 2322885, upload-time = "2026-04-20T14:41:05.253Z" }, - { url = "https://files.pythonhosted.org/packages/c8/c1/1c0acdb3aa0856ddc4ecc55214578f896f2de16f400cf51627eb3c26c1c4/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e", size = 2360328, upload-time = "2026-04-20T14:41:43.991Z" }, - { url = "https://files.pythonhosted.org/packages/f0/d0/ef39cd0f4a926814f360e71c1adeab48ad214d9727e4deb48eedfb5bce1a/pydantic_core-2.46.3-cp311-cp311-win32.whl", hash = "sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb", size = 1979464, upload-time = "2026-04-20T14:43:12.215Z" }, - { url = "https://files.pythonhosted.org/packages/18/9c/f41951b0d858e343f1cf09398b2a7b3014013799744f2c4a8ad6a3eec4f2/pydantic_core-2.46.3-cp311-cp311-win_amd64.whl", hash = "sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346", size = 2070837, upload-time = "2026-04-20T14:41:47.707Z" }, - { url = "https://files.pythonhosted.org/packages/9f/1e/264a17cd582f6ed50950d4d03dd5fefd84e570e238afe1cb3e25cf238769/pydantic_core-2.46.3-cp311-cp311-win_arm64.whl", hash = "sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6", size = 2053647, upload-time = "2026-04-20T14:42:27.535Z" }, - { url = "https://files.pythonhosted.org/packages/4b/cb/5b47425556ecc1f3fe18ed2a0083188aa46e1dd812b06e406475b3a5d536/pydantic_core-2.46.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67", size = 2101946, upload-time = "2026-04-20T14:40:52.581Z" }, - { url = "https://files.pythonhosted.org/packages/a1/4f/2fb62c2267cae99b815bbf4a7b9283812c88ca3153ef29f7707200f1d4e5/pydantic_core-2.46.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089", size = 1951612, upload-time = "2026-04-20T14:42:42.996Z" }, - { url = "https://files.pythonhosted.org/packages/50/6e/b7348fd30d6556d132cddd5bd79f37f96f2601fe0608afac4f5fb01ec0b3/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0", size = 1977027, upload-time = "2026-04-20T14:42:02.001Z" }, - { url = "https://files.pythonhosted.org/packages/82/11/31d60ee2b45540d3fb0b29302a393dbc01cd771c473f5b5147bcd353e593/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789", size = 2063008, upload-time = "2026-04-20T14:44:17.952Z" }, - { url = "https://files.pythonhosted.org/packages/8a/db/3a9d1957181b59258f44a2300ab0f0be9d1e12d662a4f57bb31250455c52/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d", size = 2233082, upload-time = "2026-04-20T14:40:57.934Z" }, - { url = "https://files.pythonhosted.org/packages/9c/e1/3277c38792aeb5cfb18c2f0c5785a221d9ff4e149abbe1184d53d5f72273/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c", size = 2304615, upload-time = "2026-04-20T14:42:12.584Z" }, - { url = "https://files.pythonhosted.org/packages/5e/d5/e3d9717c9eba10855325650afd2a9cba8e607321697f18953af9d562da2f/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395", size = 2094380, upload-time = "2026-04-20T14:43:05.522Z" }, - { url = "https://files.pythonhosted.org/packages/a1/20/abac35dedcbfd66c6f0b03e4e3564511771d6c9b7ede10a362d03e110d9b/pydantic_core-2.46.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396", size = 2135429, upload-time = "2026-04-20T14:41:55.549Z" }, - { url = "https://files.pythonhosted.org/packages/6c/a5/41bfd1df69afad71b5cf0535055bccc73022715ad362edbc124bc1e021d7/pydantic_core-2.46.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d", size = 2174582, upload-time = "2026-04-20T14:41:45.96Z" }, - { url = "https://files.pythonhosted.org/packages/79/65/38d86ea056b29b2b10734eb23329b7a7672ca604df4f2b6e9c02d4ee22fe/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca", size = 2187533, upload-time = "2026-04-20T14:40:55.367Z" }, - { url = "https://files.pythonhosted.org/packages/b6/55/a1129141678a2026badc539ad1dee0a71d06f54c2f06a4bd68c030ac781b/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976", size = 2332985, upload-time = "2026-04-20T14:44:13.05Z" }, - { url = "https://files.pythonhosted.org/packages/d7/60/cb26f4077719f709e54819f4e8e1d43f4091f94e285eb6bd21e1190a7b7c/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b", size = 2373670, upload-time = "2026-04-20T14:41:53.421Z" }, - { url = "https://files.pythonhosted.org/packages/6b/7e/c3f21882bdf1d8d086876f81b5e296206c69c6082551d776895de7801fa0/pydantic_core-2.46.3-cp312-cp312-win32.whl", hash = "sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4", size = 1966722, upload-time = "2026-04-20T14:44:30.588Z" }, - { url = "https://files.pythonhosted.org/packages/57/be/6b5e757b859013ebfbd7adba02f23b428f37c86dcbf78b5bb0b4ffd36e99/pydantic_core-2.46.3-cp312-cp312-win_amd64.whl", hash = "sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1", size = 2072970, upload-time = "2026-04-20T14:42:54.248Z" }, - { url = "https://files.pythonhosted.org/packages/bf/f8/a989b21cc75e9a32d24192ef700eea606521221a89faa40c919ce884f2b1/pydantic_core-2.46.3-cp312-cp312-win_arm64.whl", hash = "sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72", size = 2035963, upload-time = "2026-04-20T14:44:20.4Z" }, - { url = "https://files.pythonhosted.org/packages/9b/3c/9b5e8eb9821936d065439c3b0fb1490ffa64163bfe7e1595985a47896073/pydantic_core-2.46.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37", size = 2102109, upload-time = "2026-04-20T14:41:24.219Z" }, - { url = "https://files.pythonhosted.org/packages/91/97/1c41d1f5a19f241d8069f1e249853bcce378cdb76eec8ab636d7bc426280/pydantic_core-2.46.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f", size = 1951820, upload-time = "2026-04-20T14:42:14.236Z" }, - { url = "https://files.pythonhosted.org/packages/30/b4/d03a7ae14571bc2b6b3c7b122441154720619afe9a336fa3a95434df5e2f/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8", size = 1977785, upload-time = "2026-04-20T14:42:31.648Z" }, - { url = "https://files.pythonhosted.org/packages/ae/0c/4086f808834b59e3c8f1aa26df8f4b6d998cdcf354a143d18ef41529d1fe/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad", size = 2062761, upload-time = "2026-04-20T14:40:37.093Z" }, - { url = "https://files.pythonhosted.org/packages/fa/71/a649be5a5064c2df0db06e0a512c2281134ed2fcc981f52a657936a7527c/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c", size = 2232989, upload-time = "2026-04-20T14:42:59.254Z" }, - { url = "https://files.pythonhosted.org/packages/a2/84/7756e75763e810b3a710f4724441d1ecc5883b94aacb07ca71c5fb5cfb69/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f", size = 2303975, upload-time = "2026-04-20T14:41:32.287Z" }, - { url = "https://files.pythonhosted.org/packages/6c/35/68a762e0c1e31f35fa0dac733cbd9f5b118042853698de9509c8e5bf128b/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35", size = 2095325, upload-time = "2026-04-20T14:42:47.685Z" }, - { url = "https://files.pythonhosted.org/packages/77/bf/1bf8c9a8e91836c926eae5e3e51dce009bf495a60ca56060689d3df3f340/pydantic_core-2.46.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687", size = 2133368, upload-time = "2026-04-20T14:41:22.766Z" }, - { url = "https://files.pythonhosted.org/packages/e5/50/87d818d6bab915984995157ceb2380f5aac4e563dddbed6b56f0ed057aba/pydantic_core-2.46.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3", size = 2173908, upload-time = "2026-04-20T14:42:52.044Z" }, - { url = "https://files.pythonhosted.org/packages/91/88/a311fb306d0bd6185db41fa14ae888fb81d0baf648a761ae760d30819d33/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022", size = 2186422, upload-time = "2026-04-20T14:43:29.55Z" }, - { url = "https://files.pythonhosted.org/packages/8f/79/28fd0d81508525ab2054fef7c77a638c8b5b0afcbbaeee493cf7c3fef7e1/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23", size = 2332709, upload-time = "2026-04-20T14:42:16.134Z" }, - { url = "https://files.pythonhosted.org/packages/b3/21/795bf5fe5c0f379308b8ef19c50dedab2e7711dbc8d0c2acf08f1c7daa05/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7", size = 2372428, upload-time = "2026-04-20T14:41:10.974Z" }, - { url = "https://files.pythonhosted.org/packages/45/b3/ed14c659cbe7605e3ef063077680a64680aec81eb1a04763a05190d49b7f/pydantic_core-2.46.3-cp313-cp313-win32.whl", hash = "sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13", size = 1965601, upload-time = "2026-04-20T14:41:42.128Z" }, - { url = "https://files.pythonhosted.org/packages/ef/bb/adb70d9a762ddd002d723fbf1bd492244d37da41e3af7b74ad212609027e/pydantic_core-2.46.3-cp313-cp313-win_amd64.whl", hash = "sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0", size = 2071517, upload-time = "2026-04-20T14:43:36.096Z" }, - { url = "https://files.pythonhosted.org/packages/52/eb/66faefabebfe68bd7788339c9c9127231e680b11906368c67ce112fdb47f/pydantic_core-2.46.3-cp313-cp313-win_arm64.whl", hash = "sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec", size = 2035802, upload-time = "2026-04-20T14:43:38.507Z" }, - { url = "https://files.pythonhosted.org/packages/7f/db/a7bcb4940183fda36022cd18ba8dd12f2dff40740ec7b58ce7457befa416/pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b", size = 2097614, upload-time = "2026-04-20T14:44:38.374Z" }, - { url = "https://files.pythonhosted.org/packages/24/35/e4066358a22e3e99519db370494c7528f5a2aa1367370e80e27e20283543/pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018", size = 1951896, upload-time = "2026-04-20T14:40:53.996Z" }, - { url = "https://files.pythonhosted.org/packages/87/92/37cf4049d1636996e4b888c05a501f40a43ff218983a551d57f9d5e14f0d/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34", size = 1979314, upload-time = "2026-04-20T14:41:49.446Z" }, - { url = "https://files.pythonhosted.org/packages/d8/36/9ff4d676dfbdfb2d591cf43f3d90ded01e15b1404fd101180ed2d62a2fd3/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7", size = 2056133, upload-time = "2026-04-20T14:42:23.574Z" }, - { url = "https://files.pythonhosted.org/packages/bc/f0/405b442a4d7ba855b06eec8b2bf9c617d43b8432d099dfdc7bf999293495/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2", size = 2228726, upload-time = "2026-04-20T14:44:22.816Z" }, - { url = "https://files.pythonhosted.org/packages/e7/f8/65cd92dd5a0bd89ba277a98ecbfaf6fc36bbd3300973c7a4b826d6ab1391/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba", size = 2301214, upload-time = "2026-04-20T14:44:48.792Z" }, - { url = "https://files.pythonhosted.org/packages/fd/86/ef96a4c6e79e7a2d0410826a68fbc0eccc0fd44aa733be199d5fcac3bb87/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f", size = 2099927, upload-time = "2026-04-20T14:41:40.196Z" }, - { url = "https://files.pythonhosted.org/packages/6d/53/269caf30e0096e0a8a8f929d1982a27b3879872cca2d917d17c2f9fdf4fe/pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22", size = 2128789, upload-time = "2026-04-20T14:41:15.868Z" }, - { url = "https://files.pythonhosted.org/packages/00/b0/1a6d9b6a587e118482910c244a1c5acf4d192604174132efd12bf0ac486f/pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f", size = 2173815, upload-time = "2026-04-20T14:44:25.152Z" }, - { url = "https://files.pythonhosted.org/packages/87/56/e7e00d4041a7e62b5a40815590114db3b535bf3ca0bf4dca9f16cef25246/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127", size = 2181608, upload-time = "2026-04-20T14:41:28.933Z" }, - { url = "https://files.pythonhosted.org/packages/e8/22/4bd23c3d41f7c185d60808a1de83c76cf5aeabf792f6c636a55c3b1ec7f9/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c", size = 2326968, upload-time = "2026-04-20T14:42:03.962Z" }, - { url = "https://files.pythonhosted.org/packages/24/ac/66cd45129e3915e5ade3b292cb3bc7fd537f58f8f8dbdaba6170f7cabb74/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1", size = 2369842, upload-time = "2026-04-20T14:41:35.52Z" }, - { url = "https://files.pythonhosted.org/packages/a2/51/dd4248abb84113615473aa20d5545b7c4cd73c8644003b5259686f93996c/pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505", size = 1959661, upload-time = "2026-04-20T14:41:00.042Z" }, - { url = "https://files.pythonhosted.org/packages/20/eb/59980e5f1ae54a3b86372bd9f0fa373ea2d402e8cdcd3459334430f91e91/pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e", size = 2071686, upload-time = "2026-04-20T14:43:16.471Z" }, - { url = "https://files.pythonhosted.org/packages/8c/db/1cf77e5247047dfee34bc01fa9bca134854f528c8eb053e144298893d370/pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df", size = 2026907, upload-time = "2026-04-20T14:43:31.732Z" }, - { url = "https://files.pythonhosted.org/packages/57/c0/b3df9f6a543276eadba0a48487b082ca1f201745329d97dbfa287034a230/pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf", size = 2095047, upload-time = "2026-04-20T14:42:37.982Z" }, - { url = "https://files.pythonhosted.org/packages/66/57/886a938073b97556c168fd99e1a7305bb363cd30a6d2c76086bf0587b32a/pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee", size = 1934329, upload-time = "2026-04-20T14:43:49.655Z" }, - { url = "https://files.pythonhosted.org/packages/0b/7c/b42eaa5c34b13b07ecb51da21761297a9b8eb43044c864a035999998f328/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a", size = 1974847, upload-time = "2026-04-20T14:42:10.737Z" }, - { url = "https://files.pythonhosted.org/packages/e6/9b/92b42db6543e7de4f99ae977101a2967b63122d4b6cf7773812da2d7d5b5/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c", size = 2041742, upload-time = "2026-04-20T14:40:44.262Z" }, - { url = "https://files.pythonhosted.org/packages/0f/19/46fbe1efabb5aa2834b43b9454e70f9a83ad9c338c1291e48bdc4fecf167/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1", size = 2236235, upload-time = "2026-04-20T14:41:27.307Z" }, - { url = "https://files.pythonhosted.org/packages/77/da/b3f95bc009ad60ec53120f5d16c6faa8cabdbe8a20d83849a1f2b8728148/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64", size = 2282633, upload-time = "2026-04-20T14:44:33.271Z" }, - { url = "https://files.pythonhosted.org/packages/cc/6e/401336117722e28f32fb8220df676769d28ebdf08f2f4469646d404c43a3/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb", size = 2109679, upload-time = "2026-04-20T14:44:41.065Z" }, - { url = "https://files.pythonhosted.org/packages/fc/53/b289f9bc8756a32fe718c46f55afaeaf8d489ee18d1a1e7be1db73f42cc4/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6", size = 2108342, upload-time = "2026-04-20T14:42:50.144Z" }, - { url = "https://files.pythonhosted.org/packages/10/5b/8292fc7c1f9111f1b2b7c1b0dcf1179edcd014fc3ea4517499f50b829d71/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c", size = 2157208, upload-time = "2026-04-20T14:42:08.133Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9e/f80044e9ec07580f057a89fc131f78dda7a58751ddf52bbe05eaf31db50f/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47", size = 2167237, upload-time = "2026-04-20T14:42:25.412Z" }, - { url = "https://files.pythonhosted.org/packages/f8/84/6781a1b037f3b96be9227edbd1101f6d3946746056231bf4ac48cdff1a8d/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab", size = 2312540, upload-time = "2026-04-20T14:40:40.313Z" }, - { url = "https://files.pythonhosted.org/packages/3e/db/19c0839feeb728e7df03255581f198dfdf1c2aeb1e174a8420b63c5252e5/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba", size = 2369556, upload-time = "2026-04-20T14:41:09.427Z" }, - { url = "https://files.pythonhosted.org/packages/e0/15/3228774cb7cd45f5f721ddf1b2242747f4eb834d0c491f0c02d606f09fed/pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56", size = 1949756, upload-time = "2026-04-20T14:41:25.717Z" }, - { url = "https://files.pythonhosted.org/packages/b8/2a/c79cf53fd91e5a87e30d481809f52f9a60dd221e39de66455cf04deaad37/pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8", size = 2051305, upload-time = "2026-04-20T14:43:18.627Z" }, - { url = "https://files.pythonhosted.org/packages/0b/db/d8182a7f1d9343a032265aae186eb063fe26ca4c40f256b21e8da4498e89/pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374", size = 2026310, upload-time = "2026-04-20T14:41:01.778Z" }, - { url = "https://files.pythonhosted.org/packages/66/7f/03dbad45cd3aa9083fbc93c210ae8b005af67e4136a14186950a747c6874/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46", size = 2105683, upload-time = "2026-04-20T14:42:19.779Z" }, - { url = "https://files.pythonhosted.org/packages/26/22/4dc186ac8ea6b257e9855031f51b62a9637beac4d68ac06bee02f046f836/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874", size = 1940052, upload-time = "2026-04-20T14:43:59.274Z" }, - { url = "https://files.pythonhosted.org/packages/0d/ca/d376391a5aff1f2e8188960d7873543608130a870961c2b6b5236627c116/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76", size = 1988172, upload-time = "2026-04-20T14:41:17.469Z" }, - { url = "https://files.pythonhosted.org/packages/0e/6b/523b9f85c23788755d6ab949329de692a2e3a584bc6beb67fef5e035aa9d/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531", size = 2128596, upload-time = "2026-04-20T14:40:41.707Z" }, - { url = "https://files.pythonhosted.org/packages/34/42/f426db557e8ab2791bc7562052299944a118655496fbff99914e564c0a94/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803", size = 2091877, upload-time = "2026-04-20T14:43:27.091Z" }, - { url = "https://files.pythonhosted.org/packages/5c/4f/86a832a9d14df58e663bfdf4627dc00d3317c2bd583c4fb23390b0f04b8e/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3", size = 1932428, upload-time = "2026-04-20T14:40:45.781Z" }, - { url = "https://files.pythonhosted.org/packages/11/1a/fe857968954d93fb78e0d4b6df5c988c74c4aaa67181c60be7cfe327c0ca/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5", size = 1997550, upload-time = "2026-04-20T14:44:02.425Z" }, - { url = "https://files.pythonhosted.org/packages/17/eb/9d89ad2d9b0ba8cd65393d434471621b98912abb10fbe1df08e480ba57b5/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4", size = 2137657, upload-time = "2026-04-20T14:42:45.149Z" }, - { url = "https://files.pythonhosted.org/packages/1f/da/99d40830684f81dec901cac521b5b91c095394cc1084b9433393cde1c2df/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25", size = 2107973, upload-time = "2026-04-20T14:42:06.175Z" }, - { url = "https://files.pythonhosted.org/packages/99/a5/87024121818d75bbb2a98ddbaf638e40e7a18b5e0f5492c9ca4b1b316107/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3", size = 1947191, upload-time = "2026-04-20T14:43:14.319Z" }, - { url = "https://files.pythonhosted.org/packages/60/62/0c1acfe10945b83a6a59d19fbaa92f48825381509e5701b855c08f13db76/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536", size = 2123791, upload-time = "2026-04-20T14:43:22.766Z" }, - { url = "https://files.pythonhosted.org/packages/75/3e/3b2393b4c8f44285561dc30b00cf307a56a2eff7c483a824db3b8221ca51/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1", size = 2153197, upload-time = "2026-04-20T14:44:27.932Z" }, - { url = "https://files.pythonhosted.org/packages/ba/75/5af02fb35505051eee727c061f2881c555ab4f8ddb2d42da715a42c9731b/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c", size = 2181073, upload-time = "2026-04-20T14:43:20.729Z" }, - { url = "https://files.pythonhosted.org/packages/10/92/7e0e1bd9ca3c68305db037560ca2876f89b2647deb2f8b6319005de37505/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85", size = 2315886, upload-time = "2026-04-20T14:44:04.826Z" }, - { url = "https://files.pythonhosted.org/packages/b8/d8/101655f27eaf3e44558ead736b2795d12500598beed4683f279396fa186e/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8", size = 2360528, upload-time = "2026-04-20T14:40:47.431Z" }, - { url = "https://files.pythonhosted.org/packages/07/0f/1c34a74c8d07136f0d729ffe5e1fdab04fbdaa7684f61a92f92511a84a15/pydantic_core-2.46.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff", size = 2184144, upload-time = "2026-04-20T14:42:57Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/08/f1ba952f1c8ae5581c70fa9c6da89f247b83e3dd8c09c035d5d7931fc23d/pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4", size = 2113146, upload-time = "2026-05-06T13:37:36.537Z" }, + { url = "https://files.pythonhosted.org/packages/56/c6/65f646c7ff09bd257f660434adb45c4dfcbbcebcc030562fecf6f5bf887d/pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5", size = 1949769, upload-time = "2026-05-06T13:37:46.365Z" }, + { url = "https://files.pythonhosted.org/packages/64/ba/bfb1d928fd5b49e1258935ff104ae356e9fd89384a55bf9f847e9193ad40/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba", size = 1974958, upload-time = "2026-05-06T13:37:28.611Z" }, + { url = "https://files.pythonhosted.org/packages/4e/74/76223bfb117b64af743c9b6670d1364516f5c0604f96b48f3272f6af6cc6/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b", size = 2042118, upload-time = "2026-05-06T13:36:55.216Z" }, + { url = "https://files.pythonhosted.org/packages/cb/7b/848732968bc8f48f3187542f08358b9d842db564147b256669426ebb1652/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c", size = 2222876, upload-time = "2026-05-06T13:38:25.455Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2f/e90b63ee2e14bd8d3db8f705a6d75d64e6ee1b7c2c8833747ce706e1e0ce/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50", size = 2286703, upload-time = "2026-05-06T13:37:53.304Z" }, + { url = "https://files.pythonhosted.org/packages/ba/1e/acc4d70f88a0a277e4a1fa77ebb985ceabaf900430f875bf9338e11c9420/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd", size = 2092042, upload-time = "2026-05-06T13:38:46.981Z" }, + { url = "https://files.pythonhosted.org/packages/a9/da/0a422b57bf8504102bf3c4ccea9c41bab5a5cee6a54650acf8faf67f5a24/pydantic_core-2.46.4-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01", size = 2117231, upload-time = "2026-05-06T13:39:23.146Z" }, + { url = "https://files.pythonhosted.org/packages/bd/2a/2ac13c3af305843e23c5078c53d135656b3f05a2fd78cb7bbbb12e97b473/pydantic_core-2.46.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d", size = 2168388, upload-time = "2026-05-06T13:40:08.06Z" }, + { url = "https://files.pythonhosted.org/packages/72/04/2beacf7e1607e93eefe4aed1b4709f079b905fb77530179d4f7c71745f22/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4", size = 2184769, upload-time = "2026-05-06T13:38:13.901Z" }, + { url = "https://files.pythonhosted.org/packages/9e/29/d2b9fd9f539133548eaf622c06a4ce176cb46ac59f32d0359c4abc0de047/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f", size = 2319312, upload-time = "2026-05-06T13:39:08.24Z" }, + { url = "https://files.pythonhosted.org/packages/7c/af/0f7a5b85fec6075bea96e3ef9187de38fccced0de92c1e7feda8d5cc7bb9/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39", size = 2361817, upload-time = "2026-05-06T13:38:43.2Z" }, + { url = "https://files.pythonhosted.org/packages/25/a4/73363fec545fd3ec025490bdda2743c56d0dd5b6266b1a53bbe9e4265375/pydantic_core-2.46.4-cp310-cp310-win32.whl", hash = "sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d", size = 1987085, upload-time = "2026-05-06T13:39:25.497Z" }, + { url = "https://files.pythonhosted.org/packages/01/aa/62f082da2c91fac1c234bc9ee0066257ce83f0604abd72e4c9d5991f2d84/pydantic_core-2.46.4-cp310-cp310-win_amd64.whl", hash = "sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf", size = 2074311, upload-time = "2026-05-06T13:39:59.922Z" }, + { url = "https://files.pythonhosted.org/packages/5c/fa/6d7708d2cfc1a832acb6aeb0cd16e801902df8a0f583bb3b4b527fde022e/pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594", size = 2111872, upload-time = "2026-05-06T13:40:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6f/aa064a3e74b5745afbdf250594f38e7ead05e2d651bcb35994b9417a0d4d/pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c", size = 1948255, upload-time = "2026-05-06T13:39:12.574Z" }, + { url = "https://files.pythonhosted.org/packages/43/3a/41114a9f7569b84b4d84e7a018c57c56347dac30c0d4a872946ec4e36c46/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826", size = 1972827, upload-time = "2026-05-06T13:38:19.841Z" }, + { url = "https://files.pythonhosted.org/packages/ef/25/1ab42e8048fe551934d9884e8d64daa7e990ad386f310a15981aeb6a5b08/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04", size = 2041051, upload-time = "2026-05-06T13:38:10.447Z" }, + { url = "https://files.pythonhosted.org/packages/94/c2/1a934597ddf08da410385b3b7aae91956a5a76c635effef456074fad7e88/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e", size = 2221314, upload-time = "2026-05-06T13:40:13.089Z" }, + { url = "https://files.pythonhosted.org/packages/02/6d/9e8ad178c9c4df27ad3c8f25d1fe2a7ab0d2ba0559fad4aee5d3d1f16771/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3", size = 2285146, upload-time = "2026-05-06T13:38:59.224Z" }, + { url = "https://files.pythonhosted.org/packages/80/50/540cd3aeefc041beb111125c4bff779831a2111fc6b15a9138cda277d32c/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4", size = 2089685, upload-time = "2026-05-06T13:38:17.762Z" }, + { url = "https://files.pythonhosted.org/packages/6b/a4/b440ad35f05f6a38f89fa0f149accb3f0e02be94ca5e15f3c449a61b4bc9/pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398", size = 2115420, upload-time = "2026-05-06T13:37:58.195Z" }, + { url = "https://files.pythonhosted.org/packages/99/61/de4f55db8dfd57bfdfa9a12ec90fe1b57c4f41062f7ca86f08586b3e0ac0/pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3", size = 2165122, upload-time = "2026-05-06T13:37:01.167Z" }, + { url = "https://files.pythonhosted.org/packages/f7/52/7c529d7bdb2d1068bd52f51fe32572c8301f9a4febf1948f10639f1436f5/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848", size = 2182573, upload-time = "2026-05-06T13:38:45.04Z" }, + { url = "https://files.pythonhosted.org/packages/37/b3/7c40325848ba78247f2812dcf9c7274e38cd801820ca6dd9fe63bcfb0eb4/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3", size = 2317139, upload-time = "2026-05-06T13:37:15.539Z" }, + { url = "https://files.pythonhosted.org/packages/d9/37/f913f81a657c865b75da6c0dbed79876073c2a43b5bd9edbe8da785e4d49/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109", size = 2360433, upload-time = "2026-05-06T13:37:30.099Z" }, + { url = "https://files.pythonhosted.org/packages/c4/67/6acaa1be2567f9256b056d8477158cac7240813956ce86e49deae8e173b4/pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda", size = 1985513, upload-time = "2026-05-06T13:38:15.669Z" }, + { url = "https://files.pythonhosted.org/packages/aa/e6/c505f83dfeda9a2e5c995cfd872949e4d05e12f7feb3dca72f633daefa94/pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33", size = 2071114, upload-time = "2026-05-06T13:40:35.416Z" }, + { url = "https://files.pythonhosted.org/packages/0f/da/7a263a96d965d9d0df5e8de8a475f33495451117035b09acb110288c381f/pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d", size = 2044298, upload-time = "2026-05-06T13:38:29.754Z" }, + { url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" }, + { url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" }, + { url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" }, + { url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" }, + { url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" }, + { url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" }, + { url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" }, + { url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" }, + { url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" }, + { url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" }, + { url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" }, + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, + { url = "https://files.pythonhosted.org/packages/ee/a4/73995fd4ebbb46ba0ee51e6fa049b8f02c40daebb762208feda8a6b7894d/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c", size = 2111589, upload-time = "2026-05-06T13:37:10.817Z" }, + { url = "https://files.pythonhosted.org/packages/fb/7f/f37d3a5e8bfcc2e403f5c57a730f2d815693fb42119e8ea48b3789335af1/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b", size = 1944552, upload-time = "2026-05-06T13:36:56.717Z" }, + { url = "https://files.pythonhosted.org/packages/15/3c/d7eb777b3ff43e8433a4efb39a17aa8fd98a4ee8561a24a67ef5db07b2d6/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b", size = 1982984, upload-time = "2026-05-06T13:39:06.207Z" }, + { url = "https://files.pythonhosted.org/packages/63/87/70b9f40170a81afd55ca26c9b2acb25c20d64bcfbf888fafecb3ba077d4c/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea", size = 2138417, upload-time = "2026-05-06T13:39:45.476Z" }, + { url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" }, + { url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" }, + { url = "https://files.pythonhosted.org/packages/11/cb/428de0385b6c8d44b716feba566abfacfbd23ee3c4439faa789a1456242f/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0", size = 2112782, upload-time = "2026-05-06T13:37:04.016Z" }, + { url = "https://files.pythonhosted.org/packages/0b/b5/6a17bdadd0fc1f170adfd05a20d37c832f52b117b4d9131da1f41bb097ce/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7", size = 1952146, upload-time = "2026-05-06T13:39:43.092Z" }, + { url = "https://files.pythonhosted.org/packages/2a/dc/03734d80e362cd43ef65428e9de77c730ce7f2f11c60d2b1e1b39f0fbf99/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2", size = 2134492, upload-time = "2026-05-06T13:36:58.124Z" }, + { url = "https://files.pythonhosted.org/packages/de/df/5e5ffc085ed07cc22d298134d3d911c63e91f6a0eb91fe646750a3209910/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9", size = 2156604, upload-time = "2026-05-06T13:37:49.88Z" }, + { url = "https://files.pythonhosted.org/packages/81/44/6e112a4253e56f5705467cbab7ab5e91ee7398ba3d56d358635958893d3e/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf", size = 2183828, upload-time = "2026-05-06T13:37:43.053Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ad/5565071e937d8e752842ac241463944c9eb14c87e2d269f2658a5bd05e98/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30", size = 2310000, upload-time = "2026-05-06T13:37:56.694Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c3/66883a5cec183e7fba4d024b4cbbe61851a63750ef606b0afecc46d1f2bf/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc", size = 2361286, upload-time = "2026-05-06T13:40:05.667Z" }, + { url = "https://files.pythonhosted.org/packages/4b/2d/69abac8f838090bbecd5df894befb2c2619e7996a98ddb949db9f3b93225/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983", size = 2193071, upload-time = "2026-05-06T13:38:08.682Z" }, ] [[package]] @@ -2534,14 +2714,14 @@ wheels = [ [[package]] name = "pyjwt" -version = "2.12.1" +version = "2.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/27/a3b6e5bf6ff856d2509292e95c8f57f0df7017cf5394921fc4e4ef40308a/pyjwt-2.12.1.tar.gz", hash = "sha256:c74a7a2adf861c04d002db713dd85f84beb242228e671280bf709d765b03672b", size = 102564, upload-time = "2026-03-13T19:27:37.25Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/81/58d0ac84e1ef3a3843791d6954d94c0b33d526c75eeb1efbce9d0a4c4077/pyjwt-2.13.0.tar.gz", hash = "sha256:41571c89ca91598c79e8ef18a2d07367d4810fbbd6f637794879baf1b7703423", size = 107515, upload-time = "2026-05-21T19:54:36.618Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/7a/8dd906bd22e79e47397a61742927f6747fe93242ef86645ee9092e610244/pyjwt-2.12.1-py3-none-any.whl", hash = "sha256:28ca37c070cad8ba8cd9790cd940535d40274d22f80ab87f3ac6a713e6e8454c", size = 29726, upload-time = "2026-03-13T19:27:35.677Z" }, + { url = "https://files.pythonhosted.org/packages/a3/5e/ecf12fdb62546d64385c158514e9b2b671f7832108ef2ecd2020ce0af2d1/pyjwt-2.13.0-py3-none-any.whl", hash = "sha256:66adcc2aff09b3f1bbd95fc1e1577df8ac8723c978552fd43304c8a290ac5728", size = 31274, upload-time = "2026-05-21T19:54:35.362Z" }, ] [package.optional-dependencies] @@ -2586,11 +2766,11 @@ wheels = [ [[package]] name = "pyreadline3" -version = "3.5.4" +version = "3.5.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/49/4cea918a08f02817aabae639e3d0ac046fef9f9180518a3ad394e22da148/pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7", size = 99839, upload-time = "2024-09-19T02:40:10.062Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/6d/f94028646d7bbe6d9d873c47ee7c246f2d29129d253f0d96cb6fcab70733/pyreadline3-3.5.6.tar.gz", hash = "sha256:61e53218b99656091ddb077df9e71f25850e72e030b6183b39c9b7e6e4f4a9bf", size = 100368, upload-time = "2026-05-14T17:55:04.471Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/dc/491b7661614ab97483abf2056be1deee4dc2490ecbf7bff9ab5cdbac86e1/pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6", size = 83178, upload-time = "2024-09-19T02:40:08.598Z" }, + { url = "https://files.pythonhosted.org/packages/f7/5e/35c856e186b74678c24927847ad9895a51f1bc02a0c6126477a6c6040064/pyreadline3-3.5.6-py3-none-any.whl", hash = "sha256:8449b734232e42a5dcd74048e39b60db2839a4c38cf3ae2bf7707d58b5389c0d", size = 85243, upload-time = "2026-05-14T17:55:03.262Z" }, ] [[package]] @@ -2613,16 +2793,16 @@ wheels = [ [[package]] name = "pytest-asyncio" -version = "1.3.0" +version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" }, { name = "pytest" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42", size = 58514, upload-time = "2026-05-26T09:56:04.083Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, + { url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1", size = 16930, upload-time = "2026-05-26T09:56:02.576Z" }, ] [[package]] @@ -2771,11 +2951,11 @@ wheels = [ [[package]] name = "pytz" -version = "2026.1.post1" +version = "2026.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/56/db/b8721d71d945e6a8ac63c0fc900b2067181dbb50805958d4d4661cf7d277/pytz-2026.1.post1.tar.gz", hash = "sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1", size = 321088, upload-time = "2026-03-03T07:47:50.683Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a", size = 320861, upload-time = "2026-05-04T01:35:29.667Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl", hash = "sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a", size = 510489, upload-time = "2026-03-03T07:47:49.167Z" }, + { url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141, upload-time = "2026-05-04T01:35:27.408Z" }, ] [[package]] @@ -2860,7 +3040,8 @@ version = "0.37.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, - { name = "rpds-py" }, + { name = "rpds-py", version = "0.30.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "rpds-py", version = "2026.6.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } @@ -2920,7 +3101,7 @@ wheels = [ [[package]] name = "requests" -version = "2.33.1" +version = "2.34.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -2928,14 +3109,14 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" }, + { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, ] [[package]] name = "requests-cache" -version = "1.3.1" +version = "1.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, @@ -2945,23 +3126,23 @@ dependencies = [ { name = "url-normalize" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/41/cca56fdb48cbca8feb68770bce70cb315de2a1f7d6bf7ca62c437ac279f0/requests_cache-1.3.1.tar.gz", hash = "sha256:784e9d07f72db4fe234830a065230c59eb446489528f271ba288c640897e47c4", size = 99416, upload-time = "2026-03-04T18:05:50.918Z" } +sdist = { url = "https://files.pythonhosted.org/packages/32/ab/a340c7f529646f16e5656a8ba1424ed0de406203e4554868491786628730/requests_cache-1.3.3.tar.gz", hash = "sha256:79b72d5ac5143992d1836ad78f4d8e65666061dd44e220548caab3723089826b", size = 101179, upload-time = "2026-07-03T19:48:57.963Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/08/48fa499c5c4667d5ceda6bd658dabf327b49997a99ac8674c61f4ba557a2/requests_cache-1.3.1-py3-none-any.whl", hash = "sha256:43a67448c3b2964c631ac7027b84607f2f63438e28104b68ad2211f32d9f606c", size = 70211, upload-time = "2026-03-04T18:05:49.628Z" }, + { url = "https://files.pythonhosted.org/packages/a5/bf/c1775e49b350225bd851576ba75263bc728d8f05c0e31439a45f3429cc7b/requests_cache-1.3.3-py3-none-any.whl", hash = "sha256:c8df20ff874ebfc026959e3874e6c12bd6724934cdb10925915908453d4b17e4", size = 70788, upload-time = "2026-07-03T19:48:56.693Z" }, ] [[package]] name = "responses" -version = "0.26.0" +version = "0.26.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, { name = "requests" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/b4/b7e040379838cc71bf5aabdb26998dfbe5ee73904c92c1c161faf5de8866/responses-0.26.0.tar.gz", hash = "sha256:c7f6923e6343ef3682816ba421c006626777893cb0d5e1434f674b649bac9eb4", size = 81303, upload-time = "2026-02-19T14:38:05.574Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/1a/4af3e6d659394b809838490b144e4ab8d7ed3b9fecc7ca78f5d2f79b1a3d/responses-0.26.2.tar.gz", hash = "sha256:9c9259b46a8349197edebf43cfa68a87e1a2802ef503ff8b2fecbabc0b45afd8", size = 84030, upload-time = "2026-07-03T16:44:50.325Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/04/7f73d05b556da048923e31a0cc878f03be7c5425ed1f268082255c75d872/responses-0.26.0-py3-none-any.whl", hash = "sha256:03ec4409088cd5c66b71ecbbbd27fe2c58ddfad801c66203457b3e6a04868c37", size = 35099, upload-time = "2026-02-19T14:38:03.847Z" }, + { url = "https://files.pythonhosted.org/packages/7c/28/693e1d9ebf72baa062ded80d837a035b86ce75eda5a269379e9e2b1008a8/responses-0.26.2-py3-none-any.whl", hash = "sha256:6fdfeabd58e5ec473b98dfe02e6d46d3173bd8dd573eff2ccccf1a05a5135364", size = 35609, upload-time = "2026-07-03T16:44:49.1Z" }, ] [[package]] @@ -2970,7 +3151,7 @@ version = "15.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } @@ -2980,7 +3161,7 @@ wheels = [ [[package]] name = "rich-click" -version = "1.9.7" +version = "1.9.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -2988,14 +3169,14 @@ dependencies = [ { name = "rich" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/04/27/091e140ea834272188e63f8dd6faac1f5c687582b687197b3e0ec3c78ebf/rich_click-1.9.7.tar.gz", hash = "sha256:022997c1e30731995bdbc8ec2f82819340d42543237f033a003c7b1f843fc5dc", size = 74838, upload-time = "2026-01-31T04:29:27.707Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/ea/21e4867ea0ef881ffd4c0550fc21a061435e50d6324bcd034396633cbc18/rich_click-1.9.8.tar.gz", hash = "sha256:4008f921da88b5d91646c134ec881c1500e5a6b3f093e90e8f29400e09608371", size = 75363, upload-time = "2026-05-28T19:54:59.144Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/e5/d708d262b600a352abe01c2ae360d8ff75b0af819b78e9af293191d928e6/rich_click-1.9.7-py3-none-any.whl", hash = "sha256:2f99120fca78f536e07b114d3b60333bc4bb2a0969053b1250869bcdc1b5351b", size = 71491, upload-time = "2026-01-31T04:29:26.777Z" }, + { url = "https://files.pythonhosted.org/packages/6d/97/a87901aef6b7e7e4a34c6dd6cc17dca8594a592ef9d9dd765fca2b7facf7/rich_click-1.9.8-py3-none-any.whl", hash = "sha256:12873865396e6927835d4eabb1cc3996edcd65b7ac9b2391a29eca4f335a2f93", size = 72189, upload-time = "2026-05-28T19:54:57.867Z" }, ] [[package]] name = "rocrate" -version = "0.15.0" +version = "0.15.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "arcp" }, @@ -3004,9 +3185,9 @@ dependencies = [ { name = "python-dateutil" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ac/4f/bd59926cd240ed55309f8ea71b94c43802d85ef3e0d778ad3c78cfa872fc/rocrate-0.15.0.tar.gz", hash = "sha256:20f0b518dcb1efbf9d25833ec5c24586dee4c39201ed1024e2277a3cd171df3e", size = 320997, upload-time = "2026-04-13T09:19:32.177Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/58/04321e914bf9ae7593ea10baf9a111cb37551e3c442d0dbdcb52f6121f5a/rocrate-0.15.1.tar.gz", hash = "sha256:4f4cf6eea66559baa9d9b8f10ae06e0611ba13eb3644edc783bdf7dd0072fced", size = 321715, upload-time = "2026-07-10T07:07:29.271Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/81/c7fd0f15eb155fb74891fe9cd07f5c4838c509dc3e1b5da9da7d390b75a0/rocrate-0.15.0-py3-none-any.whl", hash = "sha256:faa7b8fe41f84a7a8085cf4e31a973565a391cc25a850e847cdab5c2c2e52cee", size = 349120, upload-time = "2026-04-13T09:19:30.744Z" }, + { url = "https://files.pythonhosted.org/packages/68/c7/3e8a7cdbed5cc7b1295196990f1bdea178ed7e6fc14ef40163e8b61ddca5/rocrate-0.15.1-py3-none-any.whl", hash = "sha256:fc04c1078774259ad8c70779c40acec14d80a8cf310db1e8f51ae65720c153fa", size = 351054, upload-time = "2026-07-10T07:07:27.787Z" }, ] [[package]] @@ -3022,6 +3203,9 @@ wheels = [ name = "rpds-py" version = "0.30.0" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] sdist = { url = "https://files.pythonhosted.org/packages/20/af/3f2f423103f1113b36230496629986e0ef7e199d2aa8392452b484b38ced/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84", size = 69469, upload-time = "2025-11-30T20:24:38.837Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/06/0c/0c411a0ec64ccb6d104dcabe0e713e05e153a9a2c3c2bd2b32ce412166fe/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288", size = 370490, upload-time = "2025-11-30T20:21:33.256Z" }, @@ -3140,6 +3324,134 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/b7/b95708304cd49b7b6f82fdd039f1748b66ec2b21d6a45180910802f1abf1/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e", size = 562191, upload-time = "2025-11-30T20:24:36.853Z" }, ] +[[package]] +name = "rpds-py" +version = "2026.6.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15'", + "python_full_version >= '3.12' and python_full_version < '3.15'", + "python_full_version == '3.11.*'", +] +sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/1f/a2dca5ffdbf1d475ffc4e80e4d5d720ff3a00f691795910116960ee12511/rpds_py-2026.6.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7b689145a1485c335569bd056464f3243a29af7ed3871c7be31ad624ba239bc7", size = 342174, upload-time = "2026-06-30T07:14:54.821Z" }, + { url = "https://files.pythonhosted.org/packages/4d/dc/323d08583c0832911768663d1944f0107fcd4088704858d84b5e06d105a0/rpds_py-2026.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db08f45aecde626498fb3df07bcf6d2ec040af42e859a4f5040d79c200342911", size = 345513, upload-time = "2026-06-30T07:14:56.515Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2a/e31989834d18d2f26ec1d2774c5b1eb3331df4ea8ada525175294c94b48a/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc992ab27b15f852c76755eb2ab7dce86585ddadba6fa5946e58556088845b4", size = 373783, upload-time = "2026-06-30T07:14:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/87/fe/e80107ee3639585c9941c17d6a42cd65325022f656c023191fce78c324c8/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f88d653e7b3b779d71ae7454e20dcc9b6bae903f33c269db9f2be41bda3f261", size = 378316, upload-time = "2026-06-30T07:14:59.077Z" }, + { url = "https://files.pythonhosted.org/packages/22/6f/81e3adf81acfb6fa694de2a6e4e7d8863121e3e0799e0a7725e6cf5679c4/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e52655eaf81e32593abedaa4bfe33170c8cfedf3365ed9be6e11e07f148f0278", size = 499423, upload-time = "2026-06-30T07:15:00.488Z" }, + { url = "https://files.pythonhosted.org/packages/2d/9a/41263969df0ce3d9af2a96d5005a288200af1989aed3354bfceb5fc0b21f/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dfcc8b909769d19db55c7cc9541eb64b9b774b1057ffffb4f1048070475bb9f9", size = 386077, upload-time = "2026-06-30T07:15:01.911Z" }, + { url = "https://files.pythonhosted.org/packages/5e/19/7e98f468bd50346faff5b10e5297374b443bfdddacc8e9fbc65984539597/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c1255b302953c86a486b81d330d5ee1d5bd937691ce271b6be0ef0e299eaab7", size = 371315, upload-time = "2026-06-30T07:15:03.317Z" }, + { url = "https://files.pythonhosted.org/packages/99/3c/2b973b4d371906a134b03decfea7f5d9835a2c6d263454392e15b64b5b18/rpds_py-2026.6.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:8d2294a31386bfa251d8c8a39472beee17db67d4f1a6eabea665d35c9a4461c3", size = 383502, upload-time = "2026-06-30T07:15:04.627Z" }, + { url = "https://files.pythonhosted.org/packages/98/2a/12e2799500af0a307bca76b63361c51f9fe479223561489c29eea1f2ee41/rpds_py-2026.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8f23ead891a3b762f35ab3b04623da7056545b48aa60d59957e6789914545da", size = 402673, upload-time = "2026-06-30T07:15:05.856Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e3/21e5872d165fe08be4f229e3d5ee9d90019c0bf0e5538de60dbd54009450/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:421aba32367055614287a4292b6a17f1939c9452299f7a0209c117e990b646d4", size = 549964, upload-time = "2026-06-30T07:15:07.159Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d0/5ee0fe36844297de8123bee27bc12078c1a7416ad9f1b8a8ca18d6b0c0ac/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1e5822dfc2f0d4ab7e745eaa6d85945069329beeccef965af3f3bb26058fcab6", size = 615446, upload-time = "2026-06-30T07:15:08.531Z" }, + { url = "https://files.pythonhosted.org/packages/b1/80/1ea5873cb683f2fbe5f21b23ea1f6d179ead19f3c5b249b7eb5dca568ef2/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83e35b57523816c8613fd0776b40cd8bb9f596b37ddd2692eb4a6bb5ab2f8c93", size = 576975, upload-time = "2026-06-30T07:15:09.97Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e1/90ef639217a5ddb15b7f4f61b1c33911fd044ad03c311bafdd2bcab85582/rpds_py-2026.6.3-cp311-cp311-win32.whl", hash = "sha256:de3eceba0b683bcbb1ab93da016d0270df1f9ae7be716b40214c5dafac6ea45a", size = 204453, upload-time = "2026-06-30T07:15:11.324Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b7/b7a1695d7af36f521fb11e80d6d3adbd744f73b921859bd3c2a2c0dc706f/rpds_py-2026.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:2c54a076ca4d370980ab57bc0e31df57bbe8d41340436a90ef8b1219a3cbb127", size = 223219, upload-time = "2026-06-30T07:15:12.476Z" }, + { url = "https://files.pythonhosted.org/packages/d7/a2/145afacf796e4506062825941176ad9445c2dcf2b3b6a1f13d3030a15e19/rpds_py-2026.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:168c733a7112e071bb7a66460e667edfcff06c017a3c523f7a8a8e08d0140804", size = 219137, upload-time = "2026-06-30T07:15:13.631Z" }, + { url = "https://files.pythonhosted.org/packages/5c/be/2e8974163072e7bab7df1a5acd54c4498e75e35d6d18b864d3a9d5dadc92/rpds_py-2026.6.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a0811d33247c3d6128a3001d763f2aa056bb3425204335400ac54f89eec3a0d0", size = 343691, upload-time = "2026-06-30T07:15:14.96Z" }, + { url = "https://files.pythonhosted.org/packages/a4/73/319dfa745dd668efe89309141ded489126461fcecd2b8f3a3cda185129b6/rpds_py-2026.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:538949e262e46caa31ac01bdb3c1e8f642622922cacbabbae6a8445d9dc33eaf", size = 338542, upload-time = "2026-06-30T07:15:16.267Z" }, + { url = "https://files.pythonhosted.org/packages/21/63/4239893be1c4d09b709b1a8f6be4188f0870084ff547f46606b8a75f1b03/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55927d532399c2c646100ff7feb48eaa940ad70f42cd68e1328f3ded9f81ca24", size = 368180, upload-time = "2026-06-30T07:15:17.62Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ca/9c5de382225234ceb37b1844ebdb140db12b2a278bb9efe2fcd19f6c82ce/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f56f1695bc5c0871cbc33dc0130fcf503aab0c57dcc5a6700a4f49eba4f2652e", size = 375067, upload-time = "2026-06-30T07:15:18.952Z" }, + { url = "https://files.pythonhosted.org/packages/87/dc/863f69d1bf04ade34b7fe0d59b9fdf6f0135fe2d7cbca74f1d665589559d/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:270b293dae9058fc9fcedab50f13cebf46fb8ed1d1d54e0521a9da5d6b211975", size = 490509, upload-time = "2026-06-30T07:15:20.434Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ef/eac16a12048b45ec7c7fa94f2be3438a5f26bf9cc8580b18a1cfd609b7f6/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:127565fead0a10943b282957bd5447804ff3160ad79f2ad2635e6d249e380680", size = 382754, upload-time = "2026-06-30T07:15:21.831Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/d2f3f532616be4d06c316ef119683e832bd3d41e112bf3a88f4151c95b17/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecabd69db66de867690f9797f2f8fa27ba501bbc24540cbdbdc649cd15888ba6", size = 366189, upload-time = "2026-06-30T07:15:23.371Z" }, + { url = "https://files.pythonhosted.org/packages/e3/29/41a7b0e98a4b44cd676ab7598419623373eb43b20be68c084935c1a8cf88/rpds_py-2026.6.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:58eadac9cd119677b60e1cf8ac4052f35949d71b8a9e5556efccbe82533cf22a", size = 377750, upload-time = "2026-06-30T07:15:24.659Z" }, + { url = "https://files.pythonhosted.org/packages/2e/05/ecda0bec46f9a1565090bcdc941d023f6a25aff85fda28f89f8d19878152/rpds_py-2026.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7491ee23305ac3eb59e492b6945881f5cd77a6f731061a3f25b77fd40f9e99a4", size = 395576, upload-time = "2026-06-30T07:15:25.987Z" }, + { url = "https://files.pythonhosted.org/packages/68/a8/6ed52f03ee6cb854ce78785cc9a9a672eb880e83fd7224d471f667d151f1/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2c99f7e8ccb3dd6e3e4bfeac657a7b208c9bac8075f4b078c02d7404c34107fa", size = 543807, upload-time = "2026-06-30T07:15:27.356Z" }, + { url = "https://files.pythonhosted.org/packages/8f/d6/156c0d3eea27ba09b92562ba2364ba124c0a061b199e17eac637cd25a5e2/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62698275682bf121181861295c9181e789030a2d516071f5b8f3c23c170cd0fc", size = 611187, upload-time = "2026-06-30T07:15:28.931Z" }, + { url = "https://files.pythonhosted.org/packages/f1/31/774212ed989c62f7f310220089f9b0a3fb8f40f5443d1727abd5d9f52bc9/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a214c993455f99a89aaeadc9b21241900037adc9d97203e374d75513c5911822", size = 573030, upload-time = "2026-06-30T07:15:30.553Z" }, + { url = "https://files.pythonhosted.org/packages/c9/50/22f73127a41f1ce4f87fe39aadfb9a126345801c274aa93ae88456249327/rpds_py-2026.6.3-cp312-cp312-win32.whl", hash = "sha256:501f9f04a588d6a09179368c57071301445191767c64e4b52a6aa9871f1ef5ed", size = 202185, upload-time = "2026-06-30T07:15:32.027Z" }, + { url = "https://files.pythonhosted.org/packages/04/3a/f0ee4d4dde9d3b69dedf1b5f74e7a40017046d55052d173e418c6a94f960/rpds_py-2026.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:2c958bf94822e9290a40aaf2a822d4bc5c88099093e3948ad6c571eca9272e5f", size = 220394, upload-time = "2026-06-30T07:15:33.359Z" }, + { url = "https://files.pythonhosted.org/packages/f3/83/3382fe37f809b59f02aac04dbc4e765b480b46ee0227ed516e3bdc4d3dfc/rpds_py-2026.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:22bffe6042b9bcb0822bcd1955ec00e245daf17b4344e4ed8e9551b976b63e96", size = 215753, upload-time = "2026-06-30T07:15:34.778Z" }, + { url = "https://files.pythonhosted.org/packages/a4/9e/b818ee580026ec578138e961027a68820c40afeb1ec8f6819b54fb99e196/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223", size = 343012, upload-time = "2026-06-30T07:15:36.005Z" }, + { url = "https://files.pythonhosted.org/packages/f3/6b/686d9dc4359a8f163cfbbf89ee0b4e586431de22fe8248edb63a8cf50d49/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f", size = 338203, upload-time = "2026-06-30T07:15:37.462Z" }, + { url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" }, + { url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" }, + { url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" }, + { url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" }, + { url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" }, + { url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" }, + { url = "https://files.pythonhosted.org/packages/85/ed/adab103321c0a6565d5ae1c2998349bc3ee175b82ccc5ae8fc04cc413075/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0", size = 201710, upload-time = "2026-06-30T07:15:53.894Z" }, + { url = "https://files.pythonhosted.org/packages/7b/ed/a03b09668e74e5dabbf2e211f6468e1820c0552f7b0500082da31841bf7b/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80", size = 219454, upload-time = "2026-06-30T07:15:55.25Z" }, + { url = "https://files.pythonhosted.org/packages/27/17/b8642c12930b71bc2b25831f6708ccf0f75abcd11883932ec9ce54ba3a78/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb", size = 215063, upload-time = "2026-06-30T07:15:56.573Z" }, + { url = "https://files.pythonhosted.org/packages/b6/36/7fbe9dcdaf857fb3f63c2a2284b62492d95f5e8334e947e5fb6e7f68c9be/rpds_py-2026.6.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:931908d9fc855d8f74783377822be318edb6dcb19e47169dc038f9a1bf60b06e", size = 344510, upload-time = "2026-06-30T07:15:57.921Z" }, + { url = "https://files.pythonhosted.org/packages/ba/54/f785cc3d3f60839ca57a5af4927a9f347b07b2799c373fc20f7949f87c7e/rpds_py-2026.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7469697dce35be237db177d42e2a2ee26e6dcc5fc052078a6fefabd288c6edd", size = 339495, upload-time = "2026-06-30T07:15:59.238Z" }, + { url = "https://files.pythonhosted.org/packages/63/ef/d4cdaf309e6b095b43597103cf8c0b951d6cca2acce68c474f75ec12e0c7/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d", size = 369454, upload-time = "2026-06-30T07:16:01.021Z" }, + { url = "https://files.pythonhosted.org/packages/96/4a/9559a68b7ee15db09d7981212e8c2e219d2a1d6d4faa0391d813c3496a36/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda", size = 374583, upload-time = "2026-06-30T07:16:02.287Z" }, + { url = "https://files.pythonhosted.org/packages/ef/75/8964aa7d2c6e8ac43eba8eb6e6b0fdda1f46d39f2fc3e6aa9f2cb17f485d/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8", size = 492919, upload-time = "2026-06-30T07:16:03.723Z" }, + { url = "https://files.pythonhosted.org/packages/8f/97/6908094ac804115e65aedfd90f1b5fee4eebebd3f6c4cfc5419939267565/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53", size = 383725, upload-time = "2026-06-30T07:16:05.305Z" }, + { url = "https://files.pythonhosted.org/packages/d1/9c/0d1fdc2e7aba23e290d603bc494e97bd205bae262ce33c6b32a69768ed5e/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504", size = 367255, upload-time = "2026-06-30T07:16:07.086Z" }, + { url = "https://files.pythonhosted.org/packages/c4/fe/f0209ca4a9ed074bc8acb44dfd0e81c3122e94c9689f5645b7973a866719/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc", size = 379060, upload-time = "2026-06-30T07:16:08.525Z" }, + { url = "https://files.pythonhosted.org/packages/c6/8d/f1cc54c616b9d8897de8738aac148d20afca93f68187475fe194d09a71b9/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77", size = 395960, upload-time = "2026-06-30T07:16:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/fb/04/aafff00f73aeca2945f734f1d483c64ab8f472d0864ab02377fd8e89c3b2/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698", size = 545356, upload-time = "2026-06-30T07:16:11.816Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cc/e229663b9e4ddac5a4acbe9085dd80a71af2a5d356b8b39d6bff233f24b0/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd", size = 612319, upload-time = "2026-06-30T07:16:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7a/8a0e6d3e6cd066af108b71b43122c3fe158dd9eb86acac626593a2582eb1/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d", size = 573508, upload-time = "2026-06-30T07:16:15.23Z" }, + { url = "https://files.pythonhosted.org/packages/87/03/2a69ab618a789cf6cf85c86bb844c62d090e700ab1a2aa676b3741b6c516/rpds_py-2026.6.3-cp314-cp314-win32.whl", hash = "sha256:882076c00c0a608b131187055ddc5ae29f2e7eaf870d6168980420d58528a5c8", size = 202504, upload-time = "2026-06-30T07:16:16.893Z" }, + { url = "https://files.pythonhosted.org/packages/85/62/a3892ba945f4e24c78f352e5de3c7620d8479f73f211406a97263d13c7d2/rpds_py-2026.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:0be972be84cfcaf46c8c6edf690ca0f154ac17babf1f6a955a51579b34ad2dc5", size = 220380, upload-time = "2026-06-30T07:16:18.108Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e7/c2bd44dc831931815ad11ebb5f430b5a0a4d3caa9de837107876c30c3432/rpds_py-2026.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:2a9c6f195058cb45335e8cc3802745c603d716eb96bc9625950c1aac71c0c703", size = 215976, upload-time = "2026-06-30T07:16:19.654Z" }, + { url = "https://files.pythonhosted.org/packages/79/9c/fff7b74bce9a091ec9a012a03f9ff5f69364eaf9451060dfc4486da2ffdd/rpds_py-2026.6.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f90938e92afda60266da758ee7d363447f7f0138c9559f9e1811629580582d90", size = 346840, upload-time = "2026-06-30T07:16:21.268Z" }, + { url = "https://files.pythonhosted.org/packages/e9/44/77bcb1168b33704908295533d27f10eb811e9e3e193e8993dc99572211d3/rpds_py-2026.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec829541c45bca16e61c7ae50c20501f213605beb75d1aba91a6ee37fbbb56a4", size = 340282, upload-time = "2026-06-30T07:16:22.875Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/7a9081c7c9e645b39efe19e4ffbeccd80add246327cd9b888aecffd72317/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9", size = 370403, upload-time = "2026-06-30T07:16:24.415Z" }, + { url = "https://files.pythonhosted.org/packages/f7/69/af47021eb7dad6ff3396cb001c08f0f3c4d06c20253f75be6421a59fe6b7/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f", size = 376055, upload-time = "2026-06-30T07:16:26.111Z" }, + { url = "https://files.pythonhosted.org/packages/81/fc/a3bcf517084396a6dd258c592567a3c011ba4557f2fde23dceaf26e74f2e/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41", size = 494419, upload-time = "2026-06-30T07:16:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/c9/eb/13d529d1788135425c7bf207f8463458ca5d92e43f3f701365b83e9dffc1/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945", size = 384848, upload-time = "2026-06-30T07:16:29.183Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f4/b7ac49f30013aba8f7b9566b1dd07e81de95e708c1374b7bacc5b9bc5c9c/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f", size = 371369, upload-time = "2026-06-30T07:16:30.912Z" }, + { url = "https://files.pythonhosted.org/packages/31/86/6260bafa622f788b07ddec0e52d810305c8b9b0b8c27f58a2ab04bf62b4f/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1", size = 379673, upload-time = "2026-06-30T07:16:32.486Z" }, + { url = "https://files.pythonhosted.org/packages/19/c3/03f1ee79a047b48daeca157c89a18509cde22b6b951d642b9b0af1be660a/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e", size = 397500, upload-time = "2026-06-30T07:16:34.471Z" }, + { url = "https://files.pythonhosted.org/packages/f0/95/8ed0cd8c377dca12aea498f119fe639fc474d1461545c39d2b5872eb1c0f/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538", size = 545978, upload-time = "2026-06-30T07:16:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f2/0eb57f0eaa83f8fc152a7e03de968ab77e1f00732bebc892b190c6eebde7/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db", size = 613350, upload-time = "2026-06-30T07:16:38.213Z" }, + { url = "https://files.pythonhosted.org/packages/5b/de/e0674bdbc3ef7634989b3f854c3f34bc1f587d36e5bfdc5c378d57034619/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2", size = 576486, upload-time = "2026-06-30T07:16:39.797Z" }, + { url = "https://files.pythonhosted.org/packages/f2/f6/21101359743cd136ada781e8210a85769578422ba460672eea0e29739200/rpds_py-2026.6.3-cp314-cp314t-win32.whl", hash = "sha256:6de4744d05bd1aa1be4ed7ea1189e3979196808008113bbbf899a460966b925e", size = 201068, upload-time = "2026-06-30T07:16:41.316Z" }, + { url = "https://files.pythonhosted.org/packages/a6/b2/9574d4d44f7760c2aa32d92a0a4f41698e33f5b204a0bf5c9758f52c79d5/rpds_py-2026.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:c7b9a2f8f4d8e90af72571d3d495deebdd7e3c75451f5b41719aee166e940fc2", size = 220600, upload-time = "2026-06-30T07:16:43.091Z" }, + { url = "https://files.pythonhosted.org/packages/08/ae/f23a2697e6ee6340a578b0f136be6483657bef0c6f9497b752bb5c0964bb/rpds_py-2026.6.3-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:e059c5dde6452b44424bd1834557556c226b57781dee1227af23518459722b13", size = 344726, upload-time = "2026-06-30T07:16:44.5Z" }, + { url = "https://files.pythonhosted.org/packages/c3/63/e7b3a1a5358dd32c930a1062d8e15b67fd6e8922e81df9e91706d66ee5c8/rpds_py-2026.6.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2f7c26fbc5acd2522b95d4177fe4710ffd8e9b20529e703ffbf8db4d93903f05", size = 339587, upload-time = "2026-06-30T07:16:46.255Z" }, + { url = "https://files.pythonhosted.org/packages/ec/64/10a85681916ca55fffb91b0a211f84e34297c109243484dd6394660a8a7c/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba", size = 369585, upload-time = "2026-06-30T07:16:48.101Z" }, + { url = "https://files.pythonhosted.org/packages/76/c2/baf95c7c38823e12ba34407c5f5767a89e5cf2233895e56f608167ae9493/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617", size = 375479, upload-time = "2026-06-30T07:16:49.93Z" }, + { url = "https://files.pythonhosted.org/packages/6a/94/0aad06c72d65101e11d33528d438cda99a39ce0da99466e156158f2541d3/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9", size = 492418, upload-time = "2026-06-30T07:16:51.641Z" }, + { url = "https://files.pythonhosted.org/packages/b5/17/de3f5a479a1f056535d7489819639d8cd591ea6281d700390b43b1abd745/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb", size = 384123, upload-time = "2026-06-30T07:16:53.622Z" }, + { url = "https://files.pythonhosted.org/packages/46/7d/bf09bd1b145bb2671c03e1e6d1ab8651858d90d8c7dfeadd85a37a934fd8/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885", size = 367351, upload-time = "2026-06-30T07:16:55.241Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ea/1bb734f314b8be319149ddee80b18bd41372bdcfbdf88d28131c0cd37719/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a", size = 378827, upload-time = "2026-06-30T07:16:56.841Z" }, + { url = "https://files.pythonhosted.org/packages/4b/93/d9611e5b25e26df9a3649813ed66193ace9347a7c7fc4ab7cf70e94851c0/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868", size = 395966, upload-time = "2026-06-30T07:16:58.557Z" }, + { url = "https://files.pythonhosted.org/packages/c3/cb/99d77e16e5534ae1d90629bbe419ba6ee170833a6a85e3aa1cc41726fbbc/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187", size = 545680, upload-time = "2026-06-30T07:17:00.164Z" }, + { url = "https://files.pythonhosted.org/packages/59/15/11a29755f790cef7a2f755e8e14f4f0c33f39489e1893a632a2eee59672b/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107", size = 611853, upload-time = "2026-06-30T07:17:01.962Z" }, + { url = "https://files.pythonhosted.org/packages/68/86/0c27547e21644da938fb530f7e1a8148dd24d02db07e7a5f2567a17ce710/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba", size = 573715, upload-time = "2026-06-30T07:17:03.693Z" }, + { url = "https://files.pythonhosted.org/packages/29/71/4d8fcf700931815594bce892255bbd973b94efaf0fc1932b0590df18d886/rpds_py-2026.6.3-cp315-cp315-win32.whl", hash = "sha256:d483fe17f01ad64b7bf7cc38fcefff1ca9fb83f8c2b2542b68f97ffe0611b369", size = 202864, upload-time = "2026-06-30T07:17:05.746Z" }, + { url = "https://files.pythonhosted.org/packages/eb/62/b577562de0edbb55b2be85ce5fd09c33e386b9b13eee09833af4240fd5c4/rpds_py-2026.6.3-cp315-cp315-win_amd64.whl", hash = "sha256:67e3a721ffc5d8d2210d3671872298c4a84e4b8035cfe42ffd7cde35d772b146", size = 220430, upload-time = "2026-06-30T07:17:07.471Z" }, + { url = "https://files.pythonhosted.org/packages/c8/95/d6d0b2509825141eef60669a5739eec88dbc6a48053d6c92993a5704defe/rpds_py-2026.6.3-cp315-cp315-win_arm64.whl", hash = "sha256:6e84adbcf4bf841aed8116a8264b9f50b4cb3e7bd89b516122e616ac56ca269e", size = 215877, upload-time = "2026-06-30T07:17:09.008Z" }, + { url = "https://files.pythonhosted.org/packages/b7/bf/f3ea278f0afd615c1d0f19cb69043a41526e2bb600c2b536eb192218eb27/rpds_py-2026.6.3-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ae6dd8f10bd17aad820876d24caec9efdafd80a318d16c0a48edb5e136902c6b", size = 346933, upload-time = "2026-06-30T07:17:10.762Z" }, + { url = "https://files.pythonhosted.org/packages/9d/29/9907bdf1c5346763cf10b7f6852aad86652168c259def904cbe0082c5864/rpds_py-2026.6.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bdbd97738551fca3917c1bd7188bec1920bb520104f28e7e1007f9ceb17b7690", size = 340274, upload-time = "2026-06-30T07:17:12.266Z" }, + { url = "https://files.pythonhosted.org/packages/6f/2c/8e03767b5778ef25cebf74a7a91a2c3806f8eced4c92cb7406bbe060756d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342", size = 370763, upload-time = "2026-06-30T07:17:14.107Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e1/df2a7e1ba2efd796af26194250b8d42c821b46592311595162af9ef0528d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6", size = 376467, upload-time = "2026-06-30T07:17:15.76Z" }, + { url = "https://files.pythonhosted.org/packages/6b/de/8a0814d1946af29cb068fb259aa8622f856df1d0bab58429448726b537f5/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140", size = 496689, upload-time = "2026-06-30T07:17:17.308Z" }, + { url = "https://files.pythonhosted.org/packages/df/f3/f19e0c852ba13694f5a79f3b719331051573cb5693feacf8a88ffffc3a71/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442", size = 385340, upload-time = "2026-06-30T07:17:18.928Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ae/7ec3a9d2d4351f99e37bcb06b6b6f954512646bfdbf9742e1de727865daf/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12", size = 372179, upload-time = "2026-06-30T07:17:20.539Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ac/9cee911dff2aaa9a5a8354f6610bf2e6a616de9197c5fff4f54f82585f1e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5", size = 379993, upload-time = "2026-06-30T07:17:22.212Z" }, + { url = "https://files.pythonhosted.org/packages/83/6b/7c2a07ba88d1e9a936612f7a5d067467ed03d971d5a06f7d309dff044a7e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf", size = 398909, upload-time = "2026-06-30T07:17:23.66Z" }, + { url = "https://files.pythonhosted.org/packages/97/0b/776ffcb66783637b0031f6d58d6fb55913c8b5abf00aeecd46bf933fb477/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00", size = 546584, upload-time = "2026-06-30T07:17:25.264Z" }, + { url = "https://files.pythonhosted.org/packages/55/33/ba3bc04d7092bd553c9b2b195624992d2cc4f3de1f380b7b93cbee67bd79/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef", size = 614357, upload-time = "2026-06-30T07:17:26.888Z" }, + { url = "https://files.pythonhosted.org/packages/8b/71/14edf065f04630b1a8472f7653cad03f6c478bcf95ea0e6aed55451e33ea/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a", size = 576533, upload-time = "2026-06-30T07:17:28.546Z" }, + { url = "https://files.pythonhosted.org/packages/ba/76/65002b08596c389105720a8c0d22298b8dc25a4baf89b2ce431343c8b1de/rpds_py-2026.6.3-cp315-cp315t-win32.whl", hash = "sha256:913ca42ccad3f8cc6e292b587ae8ae49c8c823e5dce51a736252fc7c7cdfa577", size = 201204, upload-time = "2026-06-30T07:17:30.193Z" }, + { url = "https://files.pythonhosted.org/packages/8c/97/d855d6b3c322d1f27e26f5241c42016b56cf01377ea8ed348285f54652f0/rpds_py-2026.6.3-cp315-cp315t-win_amd64.whl", hash = "sha256:ae3d4fe8c0b9213624fdce7279d70e3b148b682ca20719ebd193a23ebfa47324", size = 220719, upload-time = "2026-06-30T07:17:31.788Z" }, + { url = "https://files.pythonhosted.org/packages/b4/9c/f0d19ac587fd0e4ab6b72cda355e9c5a6166b01ef7e064e437aef8eb9fef/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4cf2d36a2357e4d07bb5a4f98801265327b48256867816cfd2ceb001e9754a8f", size = 349791, upload-time = "2026-06-30T07:17:33.315Z" }, + { url = "https://files.pythonhosted.org/packages/38/c7/1d49d204c9fd2ee6c537601dc4c1ba921e03363ca576bfab94a00254ac9a/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:30c6dc199b24a5e3e81d50da0f00858c5bbdb2617a750395687f4339c5818171", size = 352842, upload-time = "2026-06-30T07:17:34.897Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e5/c0b5dc93cd0d4c06ce1f438907649514e2ea077bcd911e3154a51e96c38e/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9891e594296ab9dada6551c8e7b387b2721f27a67eecd528412e8906247a7b90", size = 382094, upload-time = "2026-06-30T07:17:36.514Z" }, + { url = "https://files.pythonhosted.org/packages/0d/54/ec0e907b4ca8d541112db352409bd15f871c9b243e0c92c9b5a46ae96f01/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5c2dc92304aa48a4a60443b548bb12f12e119d4b72f314015e67b9e1be97fca", size = 388662, upload-time = "2026-06-30T07:17:38.235Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f4/921c22a4fd0f1c1ac13a3996ffbf0aa67951e2c8ad0d1d9574938a2932e8/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:127e08c0642d880cf32ca47ec2a4a77b901f7e2dd1ad9762adb13955d72ffcc9", size = 504896, upload-time = "2026-06-30T07:17:39.689Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1b/a114b972cefa1ab1cdb3c7bb177cd3844a12826c507c722d3a73516dbbaf/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8bb68f03f395eb793220b45c097bd4d8c32944393da0fad8b999efac0868fc8c", size = 391545, upload-time = "2026-06-30T07:17:41.336Z" }, + { url = "https://files.pythonhosted.org/packages/4e/98/af9b3db77d47fcbe6c8c1f36e2c2147ec70292819e99c325f871584a1c11/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3450b693fde92133e9f51060568a4c31fcca76d5e53bbd611e689ca446517e9", size = 380059, upload-time = "2026-06-30T07:17:42.857Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ba/0efd8668b97c1d26a61566386c636a7a7a09829e474fdf807caa15a2c844/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:5e8d07bddee435a2ff6f1920e18feff28d0bc4533e42f4bf6927fbd073312c41", size = 393235, upload-time = "2026-06-30T07:17:44.637Z" }, + { url = "https://files.pythonhosted.org/packages/62/90/8c139ee9690f73b0829f32647de6f40d826f8f443af6fa72644f96351aac/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a83ae6c67b7676b9878378547ca8e93ed77a580037bcbcd1d32f739e1e6089c", size = 413008, upload-time = "2026-06-30T07:17:46.225Z" }, + { url = "https://files.pythonhosted.org/packages/9c/97/0043896fdd7828ce09a1d9a8b06433714d0960fc4ff3fc4aa72b666b764e/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2bfd04c19ddbd6640de0b51894d764bd2758854d5b75bd102d2ef10cb9c293a9", size = 558118, upload-time = "2026-06-30T07:17:47.759Z" }, + { url = "https://files.pythonhosted.org/packages/f6/40/02355f0e134f783a8f9814c4680a1bd311d37671577a5964ea838573ff37/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:ca6546b66be9dc4738b1b043d5ebd5488c66c578c5ff0fd0e8065313fe3afb76", size = 623138, upload-time = "2026-06-30T07:17:49.355Z" }, + { url = "https://files.pythonhosted.org/packages/10/85/48f0abdcef5cce4e034c7a5b0ceeceba0b01bf0d942824f4bb720afe2dec/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8e65860d238379ed982fd9ba690579b5e95af2f4840f99c772816dbe573cb826", size = 586486, upload-time = "2026-06-30T07:17:51.141Z" }, +] + [[package]] name = "ruamel-yaml" version = "0.19.1" @@ -3151,27 +3463,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.12" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/99/43/3291f1cc9106f4c63bdce7a8d0df5047fe8422a75b091c16b5e9355e0b11/ruff-0.15.12.tar.gz", hash = "sha256:ecea26adb26b4232c0c2ca19ccbc0083a68344180bba2a600605538ce51a40a6", size = 4643852, upload-time = "2026-04-24T18:17:14.305Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/6e/e78ffb61d4686f3d96ba3df2c801161843746dcbcbb17a1e927d4829312b/ruff-0.15.12-py3-none-linux_armv6l.whl", hash = "sha256:f86f176e188e94d6bdbc09f09bfd9dc729059ad93d0e7390b5a73efe19f8861c", size = 10640713, upload-time = "2026-04-24T18:17:22.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/08/a317bc231fb9e7b93e4ef3089501e51922ff88d6936ce5cf870c4fe55419/ruff-0.15.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e3bcd123364c3770b8e1b7baaf343cc99a35f197c5c6e8af79015c666c423a6c", size = 11069267, upload-time = "2026-04-24T18:17:30.105Z" }, - { url = "https://files.pythonhosted.org/packages/aa/a4/f828e9718d3dce1f5f11c39c4f65afd32783c8b2aebb2e3d259e492c47bd/ruff-0.15.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fe87510d000220aa1ed530d4448a7c696a0cae1213e5ec30e5874287b66557b5", size = 10397182, upload-time = "2026-04-24T18:17:07.177Z" }, - { url = "https://files.pythonhosted.org/packages/71/e0/3310fc6d1b5e1fdea22bf3b1b807c7e187b581021b0d7d4514cccdb5fb71/ruff-0.15.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84a1630093121375a3e2a95b4a6dc7b59e2b4ee76216e32d81aae550a832d002", size = 10758012, upload-time = "2026-04-24T18:16:55.759Z" }, - { url = "https://files.pythonhosted.org/packages/11/c1/a606911aee04c324ddaa883ae418f3569792fd3c4a10c50e0dd0a2311e1e/ruff-0.15.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fb129f40f114f089ebe0ca56c0d251cf2061b17651d464bb6478dc01e69f11f5", size = 10447479, upload-time = "2026-04-24T18:16:51.677Z" }, - { url = "https://files.pythonhosted.org/packages/9d/68/4201e8444f0894f21ab4aeeaee68aa4f10b51613514a20d80bd628d57e88/ruff-0.15.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0c862b172d695db7598426b8af465e7e9ac00a3ea2a3630ee67eb82e366aaa6", size = 11234040, upload-time = "2026-04-24T18:17:16.529Z" }, - { url = "https://files.pythonhosted.org/packages/34/ff/8a6d6cf4ccc23fd67060874e832c18919d1557a0611ebef03fdb01fff11e/ruff-0.15.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2849ea9f3484c3aca43a82f484210370319e7170df4dfe4843395ddf6c57bc33", size = 12087377, upload-time = "2026-04-24T18:17:04.944Z" }, - { url = "https://files.pythonhosted.org/packages/85/f6/c669cf73f5152f623d34e69866a46d5e6185816b19fcd5b6dd8a2d299922/ruff-0.15.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e77c7e51c07fe396826d5969a5b846d9cd4c402535835fb6e21ce8b28fef847", size = 11367784, upload-time = "2026-04-24T18:17:25.409Z" }, - { url = "https://files.pythonhosted.org/packages/e8/39/c61d193b8a1daaa8977f7dea9e8d8ba866e02ea7b65d32f6861693aa4c12/ruff-0.15.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b2f4f2f3b1026b5fb449b467d9264bf22067b600f7b6f41fc5958909f449d0", size = 11344088, upload-time = "2026-04-24T18:17:12.258Z" }, - { url = "https://files.pythonhosted.org/packages/c2/8d/49afab3645e31e12c590acb6d3b5b69d7aab5b81926dbaf7461f9441f37a/ruff-0.15.12-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:9ba3b8f1afd7e2e43d8943e55f249e13f9682fde09711644a6e7290eb4f3e339", size = 11271770, upload-time = "2026-04-24T18:17:02.457Z" }, - { url = "https://files.pythonhosted.org/packages/46/06/33f41fe94403e2b755481cdfb9b7ef3e4e0ed031c4581124658d935d52b4/ruff-0.15.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e852ba9fdc890655e1d78f2df1499efbe0e54126bd405362154a75e2bde159c5", size = 10719355, upload-time = "2026-04-24T18:17:27.648Z" }, - { url = "https://files.pythonhosted.org/packages/0d/59/18aa4e014debbf559670e4048e39260a85c7fcee84acfd761ac01e7b8d35/ruff-0.15.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dd8aed930da53780d22fc70bdf84452c843cf64f8cb4eb38984319c24c5cd5fd", size = 10462758, upload-time = "2026-04-24T18:17:32.347Z" }, - { url = "https://files.pythonhosted.org/packages/25/e7/cc9f16fd0f3b5fddcbd7ec3d6ae30c8f3fde1047f32a4093a98d633c6570/ruff-0.15.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:01da3988d225628b709493d7dc67c3b9b12c0210016b08690ef9bd27970b262b", size = 10953498, upload-time = "2026-04-24T18:17:20.674Z" }, - { url = "https://files.pythonhosted.org/packages/72/7a/a9ba7f98c7a575978698f4230c5e8cc54bbc761af34f560818f933dafa0c/ruff-0.15.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9cae0f92bd5700d1213188b31cd3bdd2b315361296d10b96b8e2337d3d11f53e", size = 11447765, upload-time = "2026-04-24T18:17:09.755Z" }, - { url = "https://files.pythonhosted.org/packages/ea/f9/0ae446942c846b8266059ad8a30702a35afae55f5cdc54c5adf8d7afdc27/ruff-0.15.12-py3-none-win32.whl", hash = "sha256:d0185894e038d7043ba8fd6aee7499ece6462dc0ea9f1e260c7451807c714c20", size = 10657277, upload-time = "2026-04-24T18:17:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/33/f1/9614e03e1cdcbf9437570b5400ced8a720b5db22b28d8e0f1bda429f660d/ruff-0.15.12-py3-none-win_amd64.whl", hash = "sha256:c87a162d61ab3adca47c03f7f717c68672edec7d1b5499e652331780fe74950d", size = 11837758, upload-time = "2026-04-24T18:17:00.113Z" }, - { url = "https://files.pythonhosted.org/packages/c0/98/6beb4b351e472e5f4c4613f7c35a5290b8be2497e183825310c4c3a3984b/ruff-0.15.12-py3-none-win_arm64.whl", hash = "sha256:a538f7a82d061cee7be55542aca1d86d1393d55d81d4fcc314370f4340930d4f", size = 11120821, upload-time = "2026-04-24T18:16:57.979Z" }, +version = "0.15.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/06/ae069393fc66e8ff33036d4b368003833bf6e88ccf182e17e7a2f1c754fd/ruff-0.15.22.tar.gz", hash = "sha256:3f15175b1fb580126f58285a5dae6b2ea89000136d980c64499211f116b54809", size = 4785063, upload-time = "2026-07-16T15:14:13.244Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/18/ee54b7ae1e121be7a28ea6da4b67564ebb0530e183a54415ab7e3bcd2c4e/ruff-0.15.22-py3-none-linux_armv6l.whl", hash = "sha256:44423e73493737f5e7c5b41d475483898ff37afcdae38bc3da5085e29af1c2d8", size = 10781258, upload-time = "2026-07-16T15:13:19.452Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d2/2520cb14761ddbeaf57642a76942fc36adcbdbe53b4532241995f6fc485c/ruff-0.15.22-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b82c6482946e9eda7ff2e091d25b8bad3f718684e1916d41bd56873cee05b697", size = 10999477, upload-time = "2026-07-16T15:13:23.318Z" }, + { url = "https://files.pythonhosted.org/packages/c9/10/74e53572aa758dfaa678c2a2646b5c5515d884b7ca56be4d2ce03ca4b560/ruff-0.15.22-py3-none-macosx_11_0_arm64.whl", hash = "sha256:11c1c715af53a09f714e011106bffc419751ec8232fcb5da42173284ea3fec6f", size = 10466716, upload-time = "2026-07-16T15:13:26.162Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/44eaaf0844e028182f2d0a8f2190d0f359159aed0a9e5ab861d892f1ae2a/ruff-0.15.22-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742a29cf29bddb7c8327895d6a10e0e6c5b38a96dd407af9b5d0857f809c0576", size = 10892644, upload-time = "2026-07-16T15:13:29.229Z" }, + { url = "https://files.pythonhosted.org/packages/9f/21/8edf559014d2b0f82beea19cfb713993ad802ccda16868769979c6090a84/ruff-0.15.22-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72af58b951b0ae395935ae79763dc349bc0eb706319d28f7a33ad2cfb3cfc178", size = 10576719, upload-time = "2026-07-16T15:13:32.35Z" }, + { url = "https://files.pythonhosted.org/packages/bf/1e/3a13abd392a3b50b62e5938a831f9ab6e588358cacad5c18545b716d2182/ruff-0.15.22-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d425005c1835eb24e2ee4161cb90e8db263415f4a71c8c72c33abaa6c0c224", size = 11376494, upload-time = "2026-07-16T15:13:35.958Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3e/422d3d95bcf04dd78e1aeac22184d4f9a8fb2c01865d39d44618484a0317/ruff-0.15.22-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b9b3f8779a4f08c969defc3c8c35abffaa757e601ed5ae66d6d1db6519969a", size = 12208370, upload-time = "2026-07-16T15:13:39.185Z" }, + { url = "https://files.pythonhosted.org/packages/1e/91/5d065a0e0a02bf4813f5119ad278462eed081d2b832eb7c021ade0ec9e65/ruff-0.15.22-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e0dd1b2e4d3d585f897a0d137cbf4eaf6223bef4e8ce34d6bb12556c5f9249e", size = 11581098, upload-time = "2026-07-16T15:13:42.132Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f9/a0d4871d12fae702eb1f41b686caf05f1f8b124dc6db6f784f53d74918fa/ruff-0.15.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365523eb91d9224e1bcb03b022fbf0facb8f9e23792a2c53d9d4b3924bdbdebb", size = 11399422, upload-time = "2026-07-16T15:13:45.2Z" }, + { url = "https://files.pythonhosted.org/packages/18/80/c843a5176cddbceb0b7e8dd41cf9993490796c1c469348d384f5a5c13c56/ruff-0.15.22-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fabfd168afdf29fee5be98b831efa9683c94d7c5a3b58b9ce5a2e38444589a74", size = 11381683, upload-time = "2026-07-16T15:13:48.46Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/8485de0ae92239438a36cfc51350db9b9e85c9ebdfaea91b18e422706662/ruff-0.15.22-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:225dbf095a87f1d9f90f5fd7924d2613ee452a75a4308c63a8f50f761787aa7c", size = 10850295, upload-time = "2026-07-16T15:13:51.655Z" }, + { url = "https://files.pythonhosted.org/packages/fa/91/24977ec2ec72eaf15e4394ace2959fdff2dd1e14f03e005e838023407169/ruff-0.15.22-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1877d63b9d24ed278744f1523fd11b85540566d54641f97c566d7d9dc5ca5296", size = 10579640, upload-time = "2026-07-16T15:13:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/9c/47/9b51216951974df1f263ac19da550d34252e0ed7218c25f10c5ef9ed7517/ruff-0.15.22-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1606c510bd7215680d32efab38965f7cdec3ef69f5170a3f4791404ffdd5262", size = 11105077, upload-time = "2026-07-16T15:13:57.915Z" }, + { url = "https://files.pythonhosted.org/packages/c2/47/20e9d4a3b8016778acea5fc32bb50d35d207500a17ddb529ffa6996feef8/ruff-0.15.22-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:630479b18625f5ffc373f77603a22a9f8ac0acd7ff0501178b5db28ec71e9c64", size = 11490980, upload-time = "2026-07-16T15:14:01.032Z" }, + { url = "https://files.pythonhosted.org/packages/4d/76/3f72d8fc38c1cb77b38c56a70da9d0c17700cc1cc50f9649c9d3c8f5ba71/ruff-0.15.22-py3-none-win32.whl", hash = "sha256:e5ba0e4a13fd14abbed2a77b517a3911290c6c6c59ef67784328d1668fab76cf", size = 10789165, upload-time = "2026-07-16T15:14:04.16Z" }, + { url = "https://files.pythonhosted.org/packages/cb/46/4965251734c2b6fcdca1b1b187d20bcac3af0ee5b083b89c910bb961ce3a/ruff-0.15.22-py3-none-win_amd64.whl", hash = "sha256:9be63ba1eb936acd2d1342fb8337c356353706fce233b2a15a09a97037e6acde", size = 11938297, upload-time = "2026-07-16T15:14:07.316Z" }, + { url = "https://files.pythonhosted.org/packages/57/c9/e69b1ff4c8b69093ef08b8919ab767af0569666865b39c30a8795d88d3c6/ruff-0.15.22-py3-none-win_arm64.whl", hash = "sha256:e1168075b72158510839f250027659cdd78476f40507dd517892304c41318661", size = 11298172, upload-time = "2026-07-16T15:14:10.51Z" }, ] [[package]] @@ -3212,11 +3524,11 @@ wheels = [ [[package]] name = "snowballstemmer" -version = "3.0.1" +version = "3.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/75/a7/9810d872919697c9d01295633f5d574fb416d47e535f258272ca1f01f447/snowballstemmer-3.0.1.tar.gz", hash = "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895", size = 105575, upload-time = "2025-05-09T16:34:51.843Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/f8/0a71edf031f03c40db17503cb8ca78a69a171254e568e7db241b0ab57ea1/snowballstemmer-3.1.1.tar.gz", hash = "sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260", size = 123314, upload-time = "2026-06-03T00:56:40.194Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl", hash = "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064", size = 103274, upload-time = "2025-05-09T16:34:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/4c/07/2ebca9b11fb9be7340a818d8d6f63feaebb146be2c4afbd6061701d6df6e/snowballstemmer-3.1.1-py3-none-any.whl", hash = "sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752", size = 104164, upload-time = "2026-06-03T00:56:38.614Z" }, ] [[package]] @@ -3430,20 +3742,20 @@ wheels = [ [[package]] name = "textual" -version = "8.2.4" +version = "8.2.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version < '3.11'" }, - { name = "markdown-it-py", version = "4.0.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version >= '3.11'" }, + { name = "markdown-it-py", version = "4.2.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version >= '3.11'" }, { name = "mdit-py-plugins" }, { name = "platformdirs" }, { name = "pygments" }, { name = "rich" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/19/89/bec5709fb759f9c784bbcb30b2e3497df3f901691d13c2b864dbf6694a17/textual-8.2.4.tar.gz", hash = "sha256:d4e2b2ddd7157191d00b228592b7c739ea080b7d792fd410f23ca75f05ea76c4", size = 1848933, upload-time = "2026-04-19T04:20:45.845Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9b/7a/c519db0aba5024f86e71e9631810bfdd6866ed2c8695bd7fa34b90e7ef59/textual-8.2.7.tar.gz", hash = "sha256:658f568ff81e30ed43890c3e07520390e5cf1b4763822006e060656b0a88f105", size = 1859249, upload-time = "2026-05-19T10:52:49.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/32/02932f0d597cdbb34e34bf24266ff0f2cf292ccb3aafc37dd9efcb0cc416/textual-8.2.4-py3-none-any.whl", hash = "sha256:a83bd3f0cc7125ca203845af753f9d6b6be030025ecd1b05cc75ebe645b9c4ba", size = 724390, upload-time = "2026-04-19T04:20:49.968Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f5/c1e18bc0707300a0e90204343abbf7d7acd6fb7ebe03a6d4893b99a234b8/textual-8.2.7-py3-none-any.whl", hash = "sha256:4caaa13a90bc4cf9c6c862c067ccd34fe84e9c161710a2a907a8026313b6bd73", size = 731129, upload-time = "2026-05-19T10:52:51.773Z" }, ] [[package]] @@ -3535,14 +3847,14 @@ wheels = [ [[package]] name = "tqdm" -version = "4.67.3" +version = "4.69.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/69/40407dfc835517f058b603dbf37a6df094d8582b015a51eddc988febbcb7/tqdm-4.69.0.tar.gz", hash = "sha256:700c5e85dcd5f009dd6222588a29180a193a748247a5d855b4d67db93d79a53b", size = 792569, upload-time = "2026-07-17T18:09:06.2Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" }, + { url = "https://files.pythonhosted.org/packages/fe/21/99a0cdaf54eb35e77623c41b5a2c9472ee4404bba687052791fe2aba6773/tqdm-4.69.0-py3-none-any.whl", hash = "sha256:9979978912be667a6ef21fd5d8abf54e324e63d82f7f43c360792ebc2bc4e622", size = 676680, upload-time = "2026-07-17T18:09:04.172Z" }, ] [[package]] @@ -3560,77 +3872,77 @@ wheels = [ [[package]] name = "typer" -version = "0.25.0" +version = "0.27.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, - { name = "click" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "rich" }, { name = "shellingham" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7b/27/ede8cec7596e0041ba7e7b80b47d132562f56ff454313a16f6084e555c9f/typer-0.25.0.tar.gz", hash = "sha256:123eaf9f19bb40fd268310e12a542c0c6b4fab9c98d9d23342a01ff95e3ce930", size = 120150, upload-time = "2026-04-26T08:46:14.767Z" } +sdist = { url = "https://files.pythonhosted.org/packages/37/78/fda3361b56efc27944f24225f6ecd13d96d6fcfe37bd0eb34e2f4c63f9fc/typer-0.27.0.tar.gz", hash = "sha256:629bd12ea5d13a17148125d9a264f949eb171fb3f120f9b04d85873cab054fa5", size = 203430, upload-time = "2026-07-15T19:21:07.007Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/72/193d4e586ec5a4db834a36bbeb47641a62f951f114ffd0fe5b1b46e8d56f/typer-0.25.0-py3-none-any.whl", hash = "sha256:ac01b48823d3db9a83c9e164338057eadbb1c9957a2a6b4eeb486669c560b5dc", size = 55993, upload-time = "2026-04-26T08:46:15.889Z" }, + { url = "https://files.pythonhosted.org/packages/40/03/26a383c9e58c213199d1aad1c3d353cfc22d4444ec6d2c0bf8ad02523843/typer-0.27.0-py3-none-any.whl", hash = "sha256:6f4b27631e47f077871b7dc30e933ec0131c1390fbe0e387ea5574b5bac9ccf1", size = 122716, upload-time = "2026-07-15T19:21:05.553Z" }, ] [[package]] name = "types-jsonschema" -version = "4.26.0.20260408" +version = "4.26.0.20260518" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/4c/2ef5483ef81e7b6e1b901eb2994fd280cb19860134a20ff99e72748f3ccb/types_jsonschema-4.26.0.20260408.tar.gz", hash = "sha256:82b75a976ed1507c473b8dee2d4841bd65926758c6d672bb93d08bf5e16f1b3f", size = 16553, upload-time = "2026-04-08T04:36:00.543Z" } +sdist = { url = "https://files.pythonhosted.org/packages/dd/46/73b6a5d61a61015c4248030a8cb07e5bdddb4041430fae9e585a68692578/types_jsonschema-4.26.0.20260518.tar.gz", hash = "sha256:e1dd53dc97a64f5eccdd6fa9839666e09bb500a8ebba2db6fdaf1789faea81a6", size = 16638, upload-time = "2026-05-18T06:06:44.106Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/3c/724ad6ecaea06e8c6c8a8c9949a0979e6a2149b8aec4fe160135c64dd5ac/types_jsonschema-4.26.0.20260408-py3-none-any.whl", hash = "sha256:1ab0058c2612b0b81fc4e3c88ec3f9ad9b0af3fd31a176030d78b6d6cefb6e7b", size = 16081, upload-time = "2026-04-08T04:35:59.678Z" }, + { url = "https://files.pythonhosted.org/packages/07/d5/134f8a147dcecda10db7f60cfc6af0578a25a5c53c87b3907a64385e0184/types_jsonschema-4.26.0.20260518-py3-none-any.whl", hash = "sha256:30b30a518c7fe335df85c919fcbcc631b69c03d4a4b5b632fa916bea03065307", size = 16072, upload-time = "2026-05-18T06:06:43.264Z" }, ] [[package]] name = "types-markdown" -version = "3.10.2.20260408" +version = "3.10.2.20260712" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dd/0e/a690840934c459aa50e0470e7550d7f151632eafa4a8e3c21d18009ad15c/types_markdown-3.10.2.20260408.tar.gz", hash = "sha256:d5cba15ed65a1420e80e31c17e3d4a2ad7208a3f3a4da97fd2c5f093caf523cd", size = 19784, upload-time = "2026-04-08T04:33:07.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/eb/9520ed01687401b47265594955c0a9202a4f547795176de61bff77c8dfda/types_markdown-3.10.2.20260712.tar.gz", hash = "sha256:25aea17282490f35ab6b17a87771abd2f479185aaff8e8f4a0035043f02f2c52", size = 20185, upload-time = "2026-07-12T05:13:53.537Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/75/7e/265a8df257c8dced6ea89295f793a19f0a49ccbfeae1ed562368b2caf7a3/types_markdown-3.10.2.20260408-py3-none-any.whl", hash = "sha256:b0bbe8b7a8174db732067b86e391262898f5f536589ea81efec6d35ceb829331", size = 25857, upload-time = "2026-04-08T04:33:06.769Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ea/a8dc2c8977870d27b8b44c4ba2952d765f9d39626e42d0083c871c1c1ebf/types_markdown-3.10.2.20260712-py3-none-any.whl", hash = "sha256:a551ddedde46e0eaca7059aa3d0e42db71afe2b53d8b58f72f2de63f3284f625", size = 25842, upload-time = "2026-07-12T05:13:52.702Z" }, ] [[package]] name = "types-pyyaml" -version = "6.0.12.20260408" +version = "6.0.12.20260518" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/74/73/b759b1e413c31034cc01ecdfb96b38115d0ab4db55a752a3929f0cd449fd/types_pyyaml-6.0.12.20260408.tar.gz", hash = "sha256:92a73f2b8d7f39ef392a38131f76b970f8c66e4c42b3125ae872b7c93b556307", size = 17735, upload-time = "2026-04-08T04:30:50.974Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b8/83/4a1afc3fbfcf5b8d46fc390cd95ed6b0dc9010a265f4e9f46314efffa37a/types_pyyaml-6.0.12.20260518.tar.gz", hash = "sha256:d917f83fb38462550338c1297faedd860b3ec83912b96b1e3d73255f7473e466", size = 17850, upload-time = "2026-05-18T06:01:58.675Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/f0/c391068b86abb708882c6d75a08cd7d25b2c7227dab527b3a3685a3c635b/types_pyyaml-6.0.12.20260408-py3-none-any.whl", hash = "sha256:fbc42037d12159d9c801ebfcc79ebd28335a7c13b08a4cfbc6916df78fee9384", size = 20339, upload-time = "2026-04-08T04:30:50.113Z" }, + { url = "https://files.pythonhosted.org/packages/06/a2/c01db32be2ae7d6a1689972f3c492b149ee4e164b12fdfd9f64b50888215/types_pyyaml-6.0.12.20260518-py3-none-any.whl", hash = "sha256:d2150f75a231c9fe9c7463bd29487d93e60bac90400287351384bc2284eba7cd", size = 20312, upload-time = "2026-05-18T06:01:57.368Z" }, ] [[package]] name = "types-requests" -version = "2.33.0.20260408" +version = "2.33.0.20260712" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/69/6a/749dc53a54a3f35842c1f8197b3ca6b54af6d7458a1bfc75f6629b6da666/types_requests-2.33.0.20260408.tar.gz", hash = "sha256:95b9a86376807a216b2fb412b47617b202091c3ea7c078f47cc358d5528ccb7b", size = 23882, upload-time = "2026-04-08T04:34:49.33Z" } +sdist = { url = "https://files.pythonhosted.org/packages/db/51/703318f7b7be8bee126ec13bf615050f932d0179b8784420f3a0199cc769/types_requests-2.33.0.20260712.tar.gz", hash = "sha256:2141b67ab534a5c5cd2dac5034f2a35f42e699c5bf185eee608c5246a069d7fb", size = 25084, upload-time = "2026-07-12T05:14:20.455Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/b8/78fd6c037de4788c040fdd323b3369804400351b7827473920f6c1d03c10/types_requests-2.33.0.20260408-py3-none-any.whl", hash = "sha256:81f31d5ea4acb39f03be7bc8bed569ba6d5a9c5d97e89f45ac43d819b68ca50f", size = 20739, upload-time = "2026-04-08T04:34:48.325Z" }, + { url = "https://files.pythonhosted.org/packages/62/e7/010c87f559e216d83f9dc51e939633fd0d0ead3377340181ab0e223cd3b5/types_requests-2.33.0.20260712-py3-none-any.whl", hash = "sha256:de027e28c171d3da529689cbfa023b0b4eab188c8dfa22fd834eebd2cee6e7bb", size = 21392, upload-time = "2026-07-12T05:14:19.616Z" }, ] [[package]] name = "types-setuptools" -version = "82.0.0.20260408" +version = "83.0.0.20260716" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/12/3464b410c50420dd4674fa5fe9d3880711c1dbe1a06f5fe4960ee9067b9e/types_setuptools-82.0.0.20260408.tar.gz", hash = "sha256:036c68caf7e672a699f5ebbf914708d40644c14e05298bc49f7272be91cf43d3", size = 44861, upload-time = "2026-04-08T04:29:33.292Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/fa/deb7066a472bb23d28205a9dde66caef317db4b0f2ce612068c5d45a9f87/types_setuptools-83.0.0.20260716.tar.gz", hash = "sha256:a36ad71a57919b80db314e6104478ee75376a34abea88ba0f3d28db4d10006d7", size = 45672, upload-time = "2026-07-16T04:47:56.484Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/e1/46a4fc3ef03aabf5d18bac9df5cf37c6b02c3bddf3e05c3533f4b4588331/types_setuptools-82.0.0.20260408-py3-none-any.whl", hash = "sha256:ece0a215cdfa6463a65fd6f68bd940f39e455729300ddfe61cab1147ed1d2462", size = 68428, upload-time = "2026-04-08T04:29:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f9/b89c50c1f482b2b4e038a845c23a3b3fdfd735199634d2452b8951a8629b/types_setuptools-83.0.0.20260716-py3-none-any.whl", hash = "sha256:77315e9a921ced0c7cbef803d7cf06db8e60e9df5661955ee4ce3d1a1675e0dc", size = 68767, upload-time = "2026-07-16T04:47:55.484Z" }, ] [[package]] name = "typing-extensions" -version = "4.15.0" +version = "4.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, ] [[package]] @@ -3647,11 +3959,11 @@ wheels = [ [[package]] name = "tzdata" -version = "2026.2" +version = "2026.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ff/5a28bdfd8c3ebec42564ac7d0e54ca3db65044a9314a97f9564fa7a1e926/tzdata-2026.3.tar.gz", hash = "sha256:4a1518b8993086a7982523e071643f3c0e5f213e75b21318e78bcabfff9d1415", size = 198674, upload-time = "2026-07-10T08:50:37.887Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, + { url = "https://files.pythonhosted.org/packages/e5/6d/b53b99a9f2766d095985947a5782f1702cabb129a34f7a802d7197af832f/tzdata-2026.3-py2.py3-none-any.whl", hash = "sha256:dc096730c87af6cab1b171c9d532be840741ff5d459015e7f6947bd7d7e54931", size = 348168, upload-time = "2026-07-10T08:50:36.46Z" }, ] [[package]] @@ -3686,33 +3998,34 @@ wheels = [ [[package]] name = "urllib3" -version = "2.6.3" +version = "2.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" } +sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, ] [[package]] name = "wcwidth" -version = "0.6.0" +version = "0.8.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/a2/8e3becb46433538a38726c948d3399905a4c7cabd0df578ede5dc51f0ec2/wcwidth-0.6.0.tar.gz", hash = "sha256:cdc4e4262d6ef9a1a57e018384cbeb1208d8abbc64176027e2c2455c81313159", size = 159684, upload-time = "2026-02-06T19:19:40.919Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/74/c6428f875774288bec1396f5bfcbc2d925700a4dad61727fd5f2b12f249d/wcwidth-0.8.2.tar.gz", hash = "sha256:91fbef97204b96a3d4d421609b80340b760cf33e26da123ff243d76b1fda8dda", size = 1466253, upload-time = "2026-06-29T18:11:11.601Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/68/5a/199c59e0a824a3db2b89c5d2dade7ab5f9624dbf6448dc291b46d5ec94d3/wcwidth-0.6.0-py3-none-any.whl", hash = "sha256:1a3a1e510b553315f8e146c54764f4fb6264ffad731b3d78088cdb1478ffbdad", size = 94189, upload-time = "2026-02-06T19:19:39.646Z" }, + { url = "https://files.pythonhosted.org/packages/96/42/3e5985a0a7e57de470b320c6d6a1a67c844f6737a587f3d44dd13d1819e7/wcwidth-0.8.2-py3-none-any.whl", hash = "sha256:d63947694a0539a1d51e01eda7caf800c291020e6cdd7e28ad7b14dd33ad4f85", size = 323166, upload-time = "2026-06-29T18:11:09.888Z" }, ] [[package]] name = "xopen" -version = "2.0.2" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "backports-zstd", marker = "python_full_version < '3.14'" }, { name = "isal", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, { name = "zlib-ng", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'x86_64'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/47/01/0abf3e42bb1bf15ce24e4b235b1274e0c3c9ba8e3bbf2300b6323e6f50c1/xopen-2.0.2.tar.gz", hash = "sha256:f19d83de470f5a81725df0140180ec71d198311a1d7dad48f5467b4ad5df6154", size = 32224, upload-time = "2024-06-12T05:19:11.513Z" } +sdist = { url = "https://files.pythonhosted.org/packages/77/bb/74a5222fc975fccb9f8bfb62613ca42a5a28008362c598df09806ecd12c1/xopen-2.1.0.tar.gz", hash = "sha256:06584821588f813563863b63d5e02568a4328661b7507ea38c432f24c69ea4b7", size = 32424, upload-time = "2026-06-03T05:54:07.392Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/03/c9108ceffdb75f69e1c3bf5d2baadd124acc12ab0a61fb961c66f2b124fd/xopen-2.0.2-py3-none-any.whl", hash = "sha256:74e7f7fb7e7f42bd843c798595fa5a52086d7d1bf3de0e8513c6615516431313", size = 17060, upload-time = "2024-06-12T05:19:09.834Z" }, + { url = "https://files.pythonhosted.org/packages/c1/d7/f27df80071464ea76f092f77e6801534f36c83ab1c24efed885e36166cc1/xopen-2.1.0-py3-none-any.whl", hash = "sha256:0d01d2183e7496594cbed022b1d89a0a7f4e03900da1b8d59047322a5140a66d", size = 17120, upload-time = "2026-06-03T05:54:06.094Z" }, ] [[package]] @@ -3730,142 +4043,118 @@ wheels = [ [[package]] name = "yarl" -version = "1.23.0" +version = "1.24.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz", hash = "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", size = 194676, upload-time = "2026-03-01T22:07:53.373Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", size = 123764, upload-time = "2026-03-01T22:04:09.7Z" }, - { url = "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", size = 86282, upload-time = "2026-03-01T22:04:11.892Z" }, - { url = "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", size = 86053, upload-time = "2026-03-01T22:04:13.292Z" }, - { url = "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", size = 99395, upload-time = "2026-03-01T22:04:15.133Z" }, - { url = "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", size = 92143, upload-time = "2026-03-01T22:04:16.829Z" }, - { url = "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", size = 107643, upload-time = "2026-03-01T22:04:18.519Z" }, - { url = "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", size = 108700, upload-time = "2026-03-01T22:04:20.373Z" }, - { url = "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", size = 102769, upload-time = "2026-03-01T22:04:23.055Z" }, - { url = "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", size = 101114, upload-time = "2026-03-01T22:04:25.031Z" }, - { url = "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", size = 98883, upload-time = "2026-03-01T22:04:27.281Z" }, - { url = "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", size = 94172, upload-time = "2026-03-01T22:04:28.554Z" }, - { url = "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", size = 107010, upload-time = "2026-03-01T22:04:30.385Z" }, - { url = "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", size = 100285, upload-time = "2026-03-01T22:04:31.752Z" }, - { url = "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", size = 108230, upload-time = "2026-03-01T22:04:33.844Z" }, - { url = "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", size = 103008, upload-time = "2026-03-01T22:04:35.856Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl", hash = "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", size = 83073, upload-time = "2026-03-01T22:04:38.268Z" }, - { url = "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", size = 87328, upload-time = "2026-03-01T22:04:39.558Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl", hash = "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", size = 82463, upload-time = "2026-03-01T22:04:41.454Z" }, - { url = "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", size = 123641, upload-time = "2026-03-01T22:04:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", size = 86248, upload-time = "2026-03-01T22:04:44.757Z" }, - { url = "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", size = 85988, upload-time = "2026-03-01T22:04:46.365Z" }, - { url = "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", size = 100566, upload-time = "2026-03-01T22:04:47.639Z" }, - { url = "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", size = 92079, upload-time = "2026-03-01T22:04:48.925Z" }, - { url = "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", size = 108741, upload-time = "2026-03-01T22:04:50.838Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", size = 108099, upload-time = "2026-03-01T22:04:52.499Z" }, - { url = "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", size = 102678, upload-time = "2026-03-01T22:04:55.176Z" }, - { url = "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", size = 100803, upload-time = "2026-03-01T22:04:56.588Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", size = 100163, upload-time = "2026-03-01T22:04:58.492Z" }, - { url = "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", size = 93859, upload-time = "2026-03-01T22:05:00.268Z" }, - { url = "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", size = 108202, upload-time = "2026-03-01T22:05:02.273Z" }, - { url = "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", size = 99866, upload-time = "2026-03-01T22:05:03.597Z" }, - { url = "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", size = 107852, upload-time = "2026-03-01T22:05:04.986Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", size = 102919, upload-time = "2026-03-01T22:05:06.397Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl", hash = "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", size = 82602, upload-time = "2026-03-01T22:05:08.444Z" }, - { url = "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", size = 87461, upload-time = "2026-03-01T22:05:10.145Z" }, - { url = "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl", hash = "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", size = 82336, upload-time = "2026-03-01T22:05:11.554Z" }, - { url = "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", size = 124737, upload-time = "2026-03-01T22:05:12.897Z" }, - { url = "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", size = 87029, upload-time = "2026-03-01T22:05:14.376Z" }, - { url = "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", size = 86310, upload-time = "2026-03-01T22:05:15.71Z" }, - { url = "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", size = 97587, upload-time = "2026-03-01T22:05:17.384Z" }, - { url = "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", size = 92528, upload-time = "2026-03-01T22:05:18.804Z" }, - { url = "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", size = 105339, upload-time = "2026-03-01T22:05:20.235Z" }, - { url = "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", size = 105061, upload-time = "2026-03-01T22:05:22.268Z" }, - { url = "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", size = 100132, upload-time = "2026-03-01T22:05:23.638Z" }, - { url = "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", size = 99289, upload-time = "2026-03-01T22:05:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", size = 96950, upload-time = "2026-03-01T22:05:27.318Z" }, - { url = "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", size = 93960, upload-time = "2026-03-01T22:05:28.738Z" }, - { url = "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", size = 104703, upload-time = "2026-03-01T22:05:30.438Z" }, - { url = "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", size = 98325, upload-time = "2026-03-01T22:05:31.835Z" }, - { url = "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", size = 105067, upload-time = "2026-03-01T22:05:33.358Z" }, - { url = "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", size = 100285, upload-time = "2026-03-01T22:05:35.4Z" }, - { url = "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl", hash = "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", size = 82359, upload-time = "2026-03-01T22:05:36.811Z" }, - { url = "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", size = 87674, upload-time = "2026-03-01T22:05:38.171Z" }, - { url = "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl", hash = "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", size = 81879, upload-time = "2026-03-01T22:05:40.006Z" }, - { url = "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", size = 123796, upload-time = "2026-03-01T22:05:41.412Z" }, - { url = "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", size = 86547, upload-time = "2026-03-01T22:05:42.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", size = 85854, upload-time = "2026-03-01T22:05:44.85Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", size = 98351, upload-time = "2026-03-01T22:05:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", size = 92711, upload-time = "2026-03-01T22:05:48.316Z" }, - { url = "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", size = 106014, upload-time = "2026-03-01T22:05:50.028Z" }, - { url = "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", size = 105557, upload-time = "2026-03-01T22:05:51.416Z" }, - { url = "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", size = 101559, upload-time = "2026-03-01T22:05:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", size = 100502, upload-time = "2026-03-01T22:05:54.954Z" }, - { url = "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", size = 98027, upload-time = "2026-03-01T22:05:56.409Z" }, - { url = "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", size = 95369, upload-time = "2026-03-01T22:05:58.141Z" }, - { url = "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", size = 105565, upload-time = "2026-03-01T22:06:00.286Z" }, - { url = "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", size = 99813, upload-time = "2026-03-01T22:06:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", size = 105632, upload-time = "2026-03-01T22:06:03.188Z" }, - { url = "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", size = 101895, upload-time = "2026-03-01T22:06:04.651Z" }, - { url = "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl", hash = "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", size = 82356, upload-time = "2026-03-01T22:06:06.04Z" }, - { url = "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", size = 87515, upload-time = "2026-03-01T22:06:08.107Z" }, - { url = "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl", hash = "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", size = 81785, upload-time = "2026-03-01T22:06:10.181Z" }, - { url = "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", size = 130719, upload-time = "2026-03-01T22:06:11.708Z" }, - { url = "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", size = 89690, upload-time = "2026-03-01T22:06:13.429Z" }, - { url = "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", size = 89851, upload-time = "2026-03-01T22:06:15.53Z" }, - { url = "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", size = 95874, upload-time = "2026-03-01T22:06:17.553Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", size = 88710, upload-time = "2026-03-01T22:06:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", size = 101033, upload-time = "2026-03-01T22:06:21.203Z" }, - { url = "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", size = 100817, upload-time = "2026-03-01T22:06:22.738Z" }, - { url = "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", size = 97482, upload-time = "2026-03-01T22:06:24.21Z" }, - { url = "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", size = 95949, upload-time = "2026-03-01T22:06:25.697Z" }, - { url = "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", size = 95839, upload-time = "2026-03-01T22:06:27.309Z" }, - { url = "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", size = 90696, upload-time = "2026-03-01T22:06:29.048Z" }, - { url = "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", size = 100865, upload-time = "2026-03-01T22:06:30.525Z" }, - { url = "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", size = 96234, upload-time = "2026-03-01T22:06:32.692Z" }, - { url = "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", size = 100295, upload-time = "2026-03-01T22:06:34.268Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", size = 97784, upload-time = "2026-03-01T22:06:35.864Z" }, - { url = "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl", hash = "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", size = 88313, upload-time = "2026-03-01T22:06:37.39Z" }, - { url = "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", size = 94932, upload-time = "2026-03-01T22:06:39.579Z" }, - { url = "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", size = 84786, upload-time = "2026-03-01T22:06:41.988Z" }, - { url = "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", size = 124455, upload-time = "2026-03-01T22:06:43.615Z" }, - { url = "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", size = 86752, upload-time = "2026-03-01T22:06:45.425Z" }, - { url = "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", size = 86291, upload-time = "2026-03-01T22:06:46.974Z" }, - { url = "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", size = 99026, upload-time = "2026-03-01T22:06:48.459Z" }, - { url = "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", size = 92355, upload-time = "2026-03-01T22:06:50.306Z" }, - { url = "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", size = 106417, upload-time = "2026-03-01T22:06:52.1Z" }, - { url = "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", size = 106422, upload-time = "2026-03-01T22:06:54.424Z" }, - { url = "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", size = 101915, upload-time = "2026-03-01T22:06:55.895Z" }, - { url = "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", size = 100690, upload-time = "2026-03-01T22:06:58.21Z" }, - { url = "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", size = 98750, upload-time = "2026-03-01T22:06:59.794Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", size = 94685, upload-time = "2026-03-01T22:07:01.375Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", size = 106009, upload-time = "2026-03-01T22:07:03.151Z" }, - { url = "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", size = 100033, upload-time = "2026-03-01T22:07:04.701Z" }, - { url = "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", size = 106483, upload-time = "2026-03-01T22:07:06.231Z" }, - { url = "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", size = 102175, upload-time = "2026-03-01T22:07:08.4Z" }, - { url = "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl", hash = "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", size = 83871, upload-time = "2026-03-01T22:07:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", size = 89093, upload-time = "2026-03-01T22:07:11.501Z" }, - { url = "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl", hash = "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", size = 83384, upload-time = "2026-03-01T22:07:13.069Z" }, - { url = "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", size = 131019, upload-time = "2026-03-01T22:07:14.903Z" }, - { url = "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", size = 89894, upload-time = "2026-03-01T22:07:17.372Z" }, - { url = "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", size = 89979, upload-time = "2026-03-01T22:07:19.361Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", size = 95943, upload-time = "2026-03-01T22:07:21.266Z" }, - { url = "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", size = 88786, upload-time = "2026-03-01T22:07:23.129Z" }, - { url = "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", size = 101307, upload-time = "2026-03-01T22:07:24.689Z" }, - { url = "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", size = 100904, upload-time = "2026-03-01T22:07:26.287Z" }, - { url = "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", size = 97728, upload-time = "2026-03-01T22:07:27.906Z" }, - { url = "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", size = 95964, upload-time = "2026-03-01T22:07:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", size = 95882, upload-time = "2026-03-01T22:07:32.132Z" }, - { url = "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", size = 90797, upload-time = "2026-03-01T22:07:34.404Z" }, - { url = "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", size = 101023, upload-time = "2026-03-01T22:07:35.953Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", size = 96227, upload-time = "2026-03-01T22:07:37.594Z" }, - { url = "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", size = 100302, upload-time = "2026-03-01T22:07:39.334Z" }, - { url = "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", size = 98202, upload-time = "2026-03-01T22:07:41.717Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl", hash = "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4", size = 90558, upload-time = "2026-03-01T22:07:43.433Z" }, - { url = "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl", hash = "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", size = 97610, upload-time = "2026-03-01T22:07:45.773Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl", hash = "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", size = 86041, upload-time = "2026-03-01T22:07:49.026Z" }, - { url = "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl", hash = "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", size = 48288, upload-time = "2026-03-01T22:07:51.388Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/31/33/ebe9e3d1f86c7a0b51094c0a146392045ca1631d2664889539dec8088a33/yarl-1.24.5.tar.gz", hash = "sha256:e81b83143bee16329c23db3c1b2d82b29892fcbcb849186d2f6e98a5abe9a57f", size = 228679, upload-time = "2026-07-20T02:07:45.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/ac/cacdda1f0a90441297210bc34cf7e4ac1b7318c8030ebd83bdf6fe82f1db/yarl-1.24.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88f50c94e21a0a7f14042c015b0eba1881af78562e7bf007e0033e624da59750", size = 135466, upload-time = "2026-07-20T02:04:21.695Z" }, + { url = "https://files.pythonhosted.org/packages/c0/a5/1b2ceace0230e40c52ab1b263148059a43a6303219b996affc68f8381836/yarl-1.24.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6efbccc3d7f75d5b03105172a8dc86d82ba4da86817952529dd93185f4a88be2", size = 97291, upload-time = "2026-07-20T02:04:24.045Z" }, + { url = "https://files.pythonhosted.org/packages/59/1d/340d1a0db7bbce1f291afc044255ebf4ebbce2b25ab1b3f7d3d069080f5d/yarl-1.24.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0ebfaffe1a16cb72141c8e09f18cc76856dbe58639f393a4f2b26e474b96b871", size = 97154, upload-time = "2026-07-20T02:04:25.761Z" }, + { url = "https://files.pythonhosted.org/packages/05/41/25596a33c2fb5098dca8dc3773b04221db64ded0b7f8f09885647d864610/yarl-1.24.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ac73abdc7ab75610f95a8fd994c6457e87752b02a63987e188f937a1fc180f0", size = 109196, upload-time = "2026-07-20T02:04:27.543Z" }, + { url = "https://files.pythonhosted.org/packages/f2/df/dd9f2fb8a5c6054fbefd1538d2b9b1127e612d2ee64b307a070173b57afd/yarl-1.24.5-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4d97a951a81039050e45f04e96689b58b8243fa5e62aa14fe67cb6075300885e", size = 102556, upload-time = "2026-07-20T02:04:29.16Z" }, + { url = "https://files.pythonhosted.org/packages/cb/57/4754b9d2c8945880290ecba0864e8b0441e117bba70534fe819e3645e174/yarl-1.24.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe7b7bb170daccbba19ad33012d2b15f1e7942296fd4d45fc1b79013da8cc0f2", size = 117965, upload-time = "2026-07-20T02:04:30.845Z" }, + { url = "https://files.pythonhosted.org/packages/74/b5/6a9ece27d2043c3386f902dd078ab35d29ef5126b3206ebffb673283a7cb/yarl-1.24.5-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:89a1bbb58e0e3f7a283653d854b1e95d65e5cfd4af224dac5f02629ec1a3e621", size = 116266, upload-time = "2026-07-20T02:04:32.573Z" }, + { url = "https://files.pythonhosted.org/packages/9e/bc/a6653249f6ee59ec85dcfec008d9cbc16586dad613963bb17a91b2b993a5/yarl-1.24.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fa5e51397466ea7e98de493fa2ff1b8193cfef8a7b0f9b4842f92d342df0dba", size = 110758, upload-time = "2026-07-20T02:04:34.235Z" }, + { url = "https://files.pythonhosted.org/packages/65/7e/c5a12fb8208df7b981bc82256e7831ce428eeaf893f7bbe6179c57bb9252/yarl-1.24.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4103b77b8a8225e413107d2349b65eb3c1c52627b5cc5c3c4c1c6a798b218950", size = 110120, upload-time = "2026-07-20T02:04:35.85Z" }, + { url = "https://files.pythonhosted.org/packages/04/6c/1b659b964626694667b3ec01bf4bcff564b73ae7c48ea1fbfe588b78b461/yarl-1.24.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f9f3e9c8a9ecffa57bef8fb4fa19e5fa4d2d8307cf6bac5b1fca5e5860f4ba00", size = 108834, upload-time = "2026-07-20T02:04:37.67Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/bf48f55c2104e40c15b7b13fad0a5756a11552a55f01c90bc90a66ab81c3/yarl-1.24.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c0ebc836c47a6477e182169c6a476fc691d12b518894bf7dd2572f0d59f1c7ed", size = 103442, upload-time = "2026-07-20T02:04:39.576Z" }, + { url = "https://files.pythonhosted.org/packages/37/ac/84b273ac133ecdce598fc1f4140a08a1bf2044048bff8106371d207d105f/yarl-1.24.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:96d30286dd02679e32a39aa8f0b7498fc847fcda46cfc09df5513e82ce252440", size = 117413, upload-time = "2026-07-20T02:04:41.549Z" }, + { url = "https://files.pythonhosted.org/packages/a4/55/9307e03977d3b290dfa42e5d2bae7b6140808fd1786fbe70cd9d3bee53c5/yarl-1.24.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:fd8c81f346b58f45818d09ea11db69a8d5fd34a224b79871f6d44f12cd7977b1", size = 109498, upload-time = "2026-07-20T02:04:43.468Z" }, + { url = "https://files.pythonhosted.org/packages/fc/be/791a6f314cb4c989c19f8e3a10271f1e469c077143915e52474d80f26b4b/yarl-1.24.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:5c55256dee8f4b27bfbf636c8363383c7c8db7890c7cba5217d7bd5f5f21dab6", size = 116062, upload-time = "2026-07-20T02:04:45.319Z" }, + { url = "https://files.pythonhosted.org/packages/19/1a/ddd3807b86055010e2f99aa89b3c640effdb65696766c20597f696f48a1c/yarl-1.24.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9f4d8cf085a4c6a40fb97ea0f46938a8df43c85d31f9d45e2a8867ea9293790d", size = 110941, upload-time = "2026-07-20T02:04:47.054Z" }, + { url = "https://files.pythonhosted.org/packages/6d/03/f34271bba042d2187508bf62aea20a14129efb5a1acfc6a2efe7544630b4/yarl-1.24.5-cp310-cp310-win_amd64.whl", hash = "sha256:240cbec09667c1fed4c6cd0060b9ec57332427d7441289a2ed8875dc9fb2b224", size = 97534, upload-time = "2026-07-20T02:04:48.774Z" }, + { url = "https://files.pythonhosted.org/packages/e4/02/ecc8dc31b9f355731e700f8402b8075d2ea1737dbc4baf4abf0f0fc64288/yarl-1.24.5-cp310-cp310-win_arm64.whl", hash = "sha256:8a6987eaad834cb32dd57d9d582225f0054a5d1af706ccfbbdba735af4927e13", size = 93603, upload-time = "2026-07-20T02:04:50.686Z" }, + { url = "https://files.pythonhosted.org/packages/fe/db/3cb5df059756a45761cc3dee8fd25ec82b83a6585ea3542b969fda850f99/yarl-1.24.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2c1fe720934a16ea8e7146175cba2126f87f54912c8c5435e7f7c7a51ef808d3", size = 135043, upload-time = "2026-07-20T02:04:52.39Z" }, + { url = "https://files.pythonhosted.org/packages/44/f8/767d6bd5a03db63bc467df2fb56d6fafeae9667d74aea92cd6af399f828b/yarl-1.24.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c687ed078e145f5fd53a14854beff320e1d2ab76df03e2009c98f39a0f68f39a", size = 96942, upload-time = "2026-07-20T02:04:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/ce/97/10b939c44d7b28d1dbc389cfc7012306d1ea8dba01eaef44b39fffaee52a/yarl-1.24.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:709f1efed56c4a145793c046cd4939f9959bcd818979a787b77d8e09c57a0840", size = 97046, upload-time = "2026-07-20T02:04:56.638Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7a/b410dbe39b6255c55fb2a2bcee96eb844d0789235ddc381a889a90dc72d6/yarl-1.24.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:874019bd513008b009f58657134e5d0c5e030b3559bd0553976837adf52fe966", size = 110512, upload-time = "2026-07-20T02:04:58.955Z" }, + { url = "https://files.pythonhosted.org/packages/83/c7/da591971f78a5617e1f21f5699858ebccd836fe181a6493788ffc91ba69b/yarl-1.24.5-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a4582acf7ef76482f6f511ebaf1946dae7f2e85ec4728b81a678c01df63bd723", size = 102454, upload-time = "2026-07-20T02:05:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8e/73b0ed4de47289a78a96045d76d1cfe5e41848bf0da59ce25b2ec87ee05d/yarl-1.24.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2cabe6546e41dabe439999a23fcb5246e0c3b595b4315b96ef755252be90caeb", size = 117617, upload-time = "2026-07-20T02:05:02.325Z" }, + { url = "https://files.pythonhosted.org/packages/cf/14/b744747bc4f57a8d55bd744df463457524583e1e9f7538b5ace0346ab92e/yarl-1.24.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:17f57620f5475b3c69109376cc87e42a7af5db13c9398e4292772a706ff10780", size = 116135, upload-time = "2026-07-20T02:05:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/66/ca/95aa4d0e5b7ea4f20e4d577c42d001ed9df207569fdb063cc5ed4ebb496b/yarl-1.24.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:570fec8fbd22b032733625f03f10b7ff023bc399213db15e72a7acaef28c2f4e", size = 111935, upload-time = "2026-07-20T02:05:05.738Z" }, + { url = "https://files.pythonhosted.org/packages/72/0d/d2ad8d6b147832d177a4e720ba1962fe686eb0913b74503b3eca094b8bba/yarl-1.24.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5fede79c6f73ff2c3ef822864cb1ada23196e62756df53bc6231d351a49516a2", size = 110010, upload-time = "2026-07-20T02:05:07.471Z" }, + { url = "https://files.pythonhosted.org/packages/50/18/eb335e4120903903f4865041355ae46256a2406eb2865bc24827f4f27b61/yarl-1.24.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8ccf9aca873b767977c73df497a85dbedee4ee086ae9ae49dc461333b9b79f58", size = 110058, upload-time = "2026-07-20T02:05:09.246Z" }, + { url = "https://files.pythonhosted.org/packages/44/70/97353add32c62ad6f206d948ac5a5ee84398225e534dc6ed6433d1b335b6/yarl-1.24.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ad5d8201d310b031e6cd839d9bac2d4e5a01533ce5d3d5b50b7de1ef3af1de61", size = 103308, upload-time = "2026-07-20T02:05:11.31Z" }, + { url = "https://files.pythonhosted.org/packages/68/39/5e7398d4b6f6b3c9062823ebc60802df5b272e3fe9e788f9734c6ee46c85/yarl-1.24.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:841f0852f48fefea3b12c9dfec00704dfa3aef5215d0e3ce564bb3d7cd8d57c6", size = 116898, upload-time = "2026-07-20T02:05:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c9/09e52f2239e8b96357eccca05915382e4ba5405ebfb623b6036040d99654/yarl-1.24.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9baafc71b04f8f4bb0703b21d6fc9f0c30b346c636a532ff16ec8491a5ea4b1f", size = 109400, upload-time = "2026-07-20T02:05:14.821Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6a/e94133d4c2d1a14d2384310bf3e79d9cf32c9d1eae1c6f034fb80d098fa1/yarl-1.24.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d897129df1a22b12aeed2c2c98df0785a2e8e6e0bde87b389491d0025c187077", size = 115934, upload-time = "2026-07-20T02:05:17.78Z" }, + { url = "https://files.pythonhosted.org/packages/4e/3c/34955ed967b976fc38edcbb6d538dee79dbda4cb7fc7f72a0907a7c78e0f/yarl-1.24.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dd625535328fd9882374356269227670189adfcc6a2d90284f323c05862eecbd", size = 112178, upload-time = "2026-07-20T02:05:19.675Z" }, + { url = "https://files.pythonhosted.org/packages/f5/46/d7bd3a8859d47dcfaffd7127af7076032a7da278a9a02e17b5f37bfb6712/yarl-1.24.5-cp311-cp311-win_amd64.whl", hash = "sha256:f4239bbec5a3577ddb49e4b50aeb32d8e5792098262ae2f63723f916a29b1a25", size = 97544, upload-time = "2026-07-20T02:05:21.523Z" }, + { url = "https://files.pythonhosted.org/packages/01/69/c1bfd21e32c638974ea2c542a0b8c53ef1fa9eff336020f5d014f9503ff2/yarl-1.24.5-cp311-cp311-win_arm64.whl", hash = "sha256:3ac6aff147deb9c09461b2d4bbdf6256831198f5d8a23f5d37138213090b6d8a", size = 93359, upload-time = "2026-07-20T02:05:23.493Z" }, + { url = "https://files.pythonhosted.org/packages/1b/84/71d051c850b5af41d168c679d9eb67eb7c55283ac4ee131673edf134bc4e/yarl-1.24.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d693396e5aea78db03decd60aec9ece16c9b40ba00a587f089615ff4e718a81d", size = 136035, upload-time = "2026-07-20T02:05:25.489Z" }, + { url = "https://files.pythonhosted.org/packages/03/4d/8ad27f9a1b7e69313cca5d695b925b48efe51208d3490e0844bae97cabc0/yarl-1.24.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3363fcc96e665878946ad7a106b9a13eac0541766a690ef287c0232ac768b6ec", size = 97642, upload-time = "2026-07-20T02:05:27.429Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b4/05b4131c407006cd1e410e9c6539f16a0945724677e5364447313c15ea3e/yarl-1.24.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9d399bdcfb4a0f659b9b3788bbc89babe63d9a6a65aacdf4d4e7065ff2e6316c", size = 97323, upload-time = "2026-07-20T02:05:29.441Z" }, + { url = "https://files.pythonhosted.org/packages/20/16/e618c875c73e0e39611f20a581b3d5e8d59b8857bf001bee3263044c6deb/yarl-1.24.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90333fd89b43c0d08ac85f3f1447593fc2c66de18c3d6378d7125ea118dc7a54", size = 107741, upload-time = "2026-07-20T02:05:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c4defeaf3ed33fcb346aacf9c6e971a8d4e2bde04a0310e79abb208e7965/yarl-1.24.5-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:665b0a2c463cc9423dd647e0bfd9f4ccc9b50f768c55304d5e9f80b177c1de12", size = 103570, upload-time = "2026-07-20T02:05:33.303Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e7/0e0e0de5865ebd5914537ef486f36c727a59865c3ac0cf5ff1b32aececbf/yarl-1.24.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e006d3a974c4ee19512e5f058abedb6eef36a5e553c14812bdeba1758d812e6d", size = 115815, upload-time = "2026-07-20T02:05:35.292Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/ca56b700cb170aba25a3893b75355b213935657dc5714d2383354a270e62/yarl-1.24.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e7d42c531243450ef0d4d9c172e7ed6ef052640f195629065041b5add4e058d1", size = 116025, upload-time = "2026-07-20T02:05:37.503Z" }, + { url = "https://files.pythonhosted.org/packages/d6/d0/d56c859b8222116f5d68459199f48359e0bf121b6f65a69bf329b3602ba0/yarl-1.24.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f08c7513ecef5aad65687bfdf6bc601ae9fccd04a42904501f8f7141abad9eb9", size = 109835, upload-time = "2026-07-20T02:05:39.506Z" }, + { url = "https://files.pythonhosted.org/packages/70/a2/3a35557e4d1a79425040eba202ccaf08bdc8717680fc77e2498a1ad2e0a5/yarl-1.24.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c95b17fe34ed802f17e205112e6e10db92275c34fee290aa9bdc55a9c724027", size = 108884, upload-time = "2026-07-20T02:05:41.584Z" }, + { url = "https://files.pythonhosted.org/packages/e4/35/ef4c26356b7913c68983bac2d72a4212b3347af551cb8d250b99b5ed7b7f/yarl-1.24.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56b149b22de33b23b0c6077ab9518c6dcb538ad462e1830e68d06591ccf6e38b", size = 107308, upload-time = "2026-07-20T02:05:43.697Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/ff0dc66c2ccf3e0153ab97ff61eabab4400e6a5264af427ab30cd69f1857/yarl-1.24.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a8fe66b8f300da93798025a785a5b90b42f3810dc2b72283ff84a41aaaebc293", size = 103646, upload-time = "2026-07-20T02:05:45.895Z" }, + { url = "https://files.pythonhosted.org/packages/74/f0/33b9271c7f881766359d58266fa0811d2e5210ed860e28da7dc6d7786344/yarl-1.24.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:377fe3732edbaf78ee74efdf2c9f49f6e99f20e7f9d2649fda3eb4badd77d76e", size = 115305, upload-time = "2026-07-20T02:05:47.832Z" }, + { url = "https://files.pythonhosted.org/packages/ef/65/fd79fb1868c4a80db8661091de525bf430f63c3bea1b20e8b6a84fc7d359/yarl-1.24.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e8ffa78582120024f476a611d7befc123cee59e47e8309d470cf667d806e613b", size = 108404, upload-time = "2026-07-20T02:05:49.604Z" }, + { url = "https://files.pythonhosted.org/packages/ff/ba/dbabe6b262f17a816c70cfc09558dbf03ece3ec76684d02f911a3d3a189c/yarl-1.24.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:daba5e594f06114e37db186efd2dd916609071e59daca901a0a2e71f02b142ce", size = 115940, upload-time = "2026-07-20T02:05:51.741Z" }, + { url = "https://files.pythonhosted.org/packages/a5/43/fab2d1dad9d340a268cdde63756a123d069723efff6a372d123fa74a9517/yarl-1.24.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:65be18ec59496c13908f02a2472751d9ef840b4f3fb5726f129306bf6a2a7bba", size = 110006, upload-time = "2026-07-20T02:05:53.554Z" }, + { url = "https://files.pythonhosted.org/packages/c4/27/41eb51bbd1b8d89546b83897cfb0164f1e109304fd408dbb151b639eec0f/yarl-1.24.5-cp312-cp312-win_amd64.whl", hash = "sha256:a929d878fec099030c292803b31e5d5540a7b6a31e6a3cc76cb4685fc2a2f51b", size = 97618, upload-time = "2026-07-20T02:05:55.57Z" }, + { url = "https://files.pythonhosted.org/packages/3c/25/b2553764b3d65db711d8f45416351ec4f420847558eb669edcbcaadf5780/yarl-1.24.5-cp312-cp312-win_arm64.whl", hash = "sha256:7ce27823052e2013b597e0c738b13e7e36b8ccb9400df8959417b052ab0fd92c", size = 93018, upload-time = "2026-07-20T02:05:57.554Z" }, + { url = "https://files.pythonhosted.org/packages/e1/63/64ef361967cc983573149dc1515d531db5da8a4c92d22bb833d59e01b313/yarl-1.24.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:79af890482fc94648e8cde4c68620378f7fef60932710fa17a66abc039244da2", size = 135075, upload-time = "2026-07-20T02:05:59.671Z" }, + { url = "https://files.pythonhosted.org/packages/bb/89/55920fd853ce43e608adbc3962456f0d649d6bb15250dc2988321da0fe1c/yarl-1.24.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:46c2f213e23a04b93a392942d782eb9e413e6ef6bf7c8c53884e599a5c174dcb", size = 97225, upload-time = "2026-07-20T02:06:01.769Z" }, + { url = "https://files.pythonhosted.org/packages/15/f0/7688d3f2cfff7590df2af38ec46d969f4281a4dddb08a9ad2eafbcdddf98/yarl-1.24.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92ab3e11448f2ff7bf53c5a26eff0edc086898ec8b21fb154b85839ce1d88075", size = 96751, upload-time = "2026-07-20T02:06:03.676Z" }, + { url = "https://files.pythonhosted.org/packages/05/1a/a851a0f94aaaf379dd4f901bfc80f634280bec51eb260b47363e2a4cd62e/yarl-1.24.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ebb0ec7f17803063d5aeb982f3b1bd2b2f4e4fae6751226cbd6ba1fcfe9e63ff", size = 107960, upload-time = "2026-07-20T02:06:05.699Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a8/faea066c12f9c77ca0de90641f1655f9dd7b412477bf28c76d692f3aecff/yarl-1.24.5-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:82632daed195dcc8ea664e8556dc9bdbd671960fb3776bd92806ce05792c2448", size = 103500, upload-time = "2026-07-20T02:06:07.556Z" }, + { url = "https://files.pythonhosted.org/packages/fb/9c/1e67084c2a6e2f2db0e3be798328cb3be42c0119b621d25461479a224d21/yarl-1.24.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:53e549287ef628fecba270045c9701b0c564563a9b0577d24a4ec75b8ab8040f", size = 115780, upload-time = "2026-07-20T02:06:09.599Z" }, + { url = "https://files.pythonhosted.org/packages/58/86/1f94664e147474337e3359f52012cf3d02f825f694317b178bfba1078c62/yarl-1.24.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fcd3b77e2f17bbe4ca56ec7bcb07992647d19d0b9c05d84886dcd6f9eb810afd", size = 115308, upload-time = "2026-07-20T02:06:11.352Z" }, + { url = "https://files.pythonhosted.org/packages/0a/43/8e55ae7538ba5f28ccb3c845c6dd4549cf7016d5992e5326512519107cdd/yarl-1.24.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d46b86567dd4e248c6c159fcbcdcce01e0a5c8a7cd2334a0fff759d0fa075b16", size = 110574, upload-time = "2026-07-20T02:06:13.129Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ba/a889ec8765cedcf2ac44dcb02d6a21e4861399b243b263c5f2dde27ee740/yarl-1.24.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f72c74aa99359e27a2ee8d6613fefa28b5f76a983c083074dfc2aaa4ab46213", size = 109914, upload-time = "2026-07-20T02:06:15.243Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c3/e45f821af67b791c2dbbe4a9f4137a1d33f8d386654a05a0c3f47bdfa25d/yarl-1.24.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3f45789ce415a7ec0820dc4f82925f9b5f7732070be1dec1f5f23ec381435a24", size = 107712, upload-time = "2026-07-20T02:06:17.443Z" }, + { url = "https://files.pythonhosted.org/packages/02/00/2ab0f42c9857fcb490bfaa6647b14540b53d241ab209f23220b958cc5832/yarl-1.24.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6e73e7fe93f17a7b191f52ec9da9dd8c06a8fe735a1ecbd13b97d1c723bff385", size = 104251, upload-time = "2026-07-20T02:06:19.259Z" }, + { url = "https://files.pythonhosted.org/packages/7a/70/709d9a286e98af2c7fd8e4e6cada658b5c0e30d87dd7e2a63c2fb5767217/yarl-1.24.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4a36f9becdd4c5c52a20c3e9484128b070b1dcfc8944c006f3a528295a359a9c", size = 115319, upload-time = "2026-07-20T02:06:21.207Z" }, + { url = "https://files.pythonhosted.org/packages/5c/6c/3eaa515142991fe84cfc483ff986492211f1978f90161ccefdbec919d09b/yarl-1.24.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:7bcbe0fcf850eae67b6b01749815a4f7161c560a844c769ad7b48fcd99f791c4", size = 109163, upload-time = "2026-07-20T02:06:23.006Z" }, + { url = "https://files.pythonhosted.org/packages/bb/64/711dafce66c323a3144d470547a71c5384c57623308ac8bb5e4b903ac148/yarl-1.24.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:24e861e9630e0daddcb9191fb187f60f034e17a4426f8101279f0c475cd74144", size = 115435, upload-time = "2026-07-20T02:06:24.923Z" }, + { url = "https://files.pythonhosted.org/packages/cf/f3/9b9d0e6d84bea851eb1ba99e4bdc755b86fd813e49ec86dfe42f26befdef/yarl-1.24.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9335a099ad87287c37fe5d1a982ff392fa5efe5d14b40a730b1ec1d6a41382b4", size = 110691, upload-time = "2026-07-20T02:06:26.973Z" }, + { url = "https://files.pythonhosted.org/packages/86/e4/62a06b7e87c4246ac76b7c2da136f972eb4a3a1fc94abb07e7022d6fdb0a/yarl-1.24.5-cp313-cp313-win_amd64.whl", hash = "sha256:2dbe06fc16bc91502bca713704022182e5729861ae00277c3a23354b40929740", size = 97454, upload-time = "2026-07-20T02:06:29.163Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c9/5fc8025b318ab10db413b61056bd0d95c557a70e8df4210c7511f866329c/yarl-1.24.5-cp313-cp313-win_arm64.whl", hash = "sha256:6b8536851f9f65e7f00c7a1d49ba7f2be0ffe2c11555367fc9f50d9f842410a1", size = 92813, upload-time = "2026-07-20T02:06:31.113Z" }, + { url = "https://files.pythonhosted.org/packages/a9/08/5f3085fef9564217074db9dd8573de1795bc82cde61a7ad10b6a7234a569/yarl-1.24.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:2729fcfc4f6a596fb0c50f32090400aa9367774ac296a00387e65098c0befa76", size = 135680, upload-time = "2026-07-20T02:06:33.273Z" }, + { url = "https://files.pythonhosted.org/packages/98/35/ba9436e579bd48a8801f2021d842d9ab4994c26e4c7dd3a4c1f1bcb57a9e/yarl-1.24.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ff330d3c30db4eb6b01d79e29d2d0b407a7ecad39cfd9ec993ece57396a2ec0d", size = 97395, upload-time = "2026-07-20T02:06:35.259Z" }, + { url = "https://files.pythonhosted.org/packages/18/a9/a07f76f3c44e02b25cc743af5ef93eef27f7013eadca770451b6a6ccb5db/yarl-1.24.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e42d75862735da90e7fc5a7b23db0c976f737113a54b3c9777a9b665e9cbff75", size = 97223, upload-time = "2026-07-20T02:06:37.216Z" }, + { url = "https://files.pythonhosted.org/packages/77/f7/a9a1d6fa7dd9e388f95b30f6ad3ec4e285f6c8f61f44ce16070c3fcfe414/yarl-1.24.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3732e66413163e72508da9eff9ce9d2846fde51fae45d3605393d3e6cd303e9", size = 108777, upload-time = "2026-07-20T02:06:39.292Z" }, + { url = "https://files.pythonhosted.org/packages/2f/44/e0b86c302471fabd6f02808ecf2ac52b8412b624787849d4bf2cdb466f6f/yarl-1.24.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b8ee53be440a0cffc991a27be3057e0530122548dbe7c0892df08822fce5ede", size = 103119, upload-time = "2026-07-20T02:06:41.456Z" }, + { url = "https://files.pythonhosted.org/packages/d1/16/9c16d180bf8faaf223225eb50e1245870ff1ae0e302a27153988e65c51fd/yarl-1.24.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:af3aefa655adb5869491fa907e652290386800ae99cc50095cba71e2c6aefdca", size = 116471, upload-time = "2026-07-20T02:06:43.696Z" }, + { url = "https://files.pythonhosted.org/packages/d2/8d/b219b9df28a02ce95cfbdd41d2f7caa5669d0ff979c1c9975697145e33c5/yarl-1.24.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2120b96872df4a117cde97d270bac96aea7cc52205d305cf4611df694a487027", size = 115974, upload-time = "2026-07-20T02:06:45.874Z" }, + { url = "https://files.pythonhosted.org/packages/9b/e8/f20557aca240d88e69850ad1ee91756821d094bb1310565c04d25c6682a2/yarl-1.24.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:66410eb6345d467151934b49bfa70fb32f5b35a6140baa40ad97d6436abea2e9", size = 110830, upload-time = "2026-07-20T02:06:47.852Z" }, + { url = "https://files.pythonhosted.org/packages/db/18/199b85109a53eeca64ee19c9cca228287e8e4ab0cc1a09b28f530e65cce0/yarl-1.24.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4af7b7e1be0a69bee8210735fe6dcfc38879adfac6d62e789d53ba432d1ffa41", size = 110054, upload-time = "2026-07-20T02:06:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/aa/2f/ed28147f8cd7f48c49367c90713b30a555284b6105a6a56f3a05568da795/yarl-1.24.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa139875ff98ab97da323cfadfaff08900d1ad42f1b5087b0b812a55c5a06373", size = 108312, upload-time = "2026-07-20T02:06:51.835Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c5/55e16ae0a5c227cea8df1c6871ba57d614a34243146c05729caf2a1bd9c5/yarl-1.24.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:0055afc45e864b92729ac7600e2d102c17bef060647e74bca75fa84d66b9ff36", size = 103662, upload-time = "2026-07-20T02:06:54.061Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ea/dbd7c2caec459c9a426f18b02688ecbfb58620d0f6a3422d24769fbaf8ab/yarl-1.24.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f0e466ed7511fe9d459a819edbc6c2585c0b6eabde9fa8a8947552468a7a6ef0", size = 116090, upload-time = "2026-07-20T02:06:56.015Z" }, + { url = "https://files.pythonhosted.org/packages/06/84/39ce4ce3059e07fece5fbdbee8c4053406af9aca911ce9fa5f8548aab6af/yarl-1.24.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f141474e85b7e54998ec5180530a7cda99ab29e282fa50e0756d89981a9b43c5", size = 109523, upload-time = "2026-07-20T02:06:57.926Z" }, + { url = "https://files.pythonhosted.org/packages/a9/8b/71ff44137b405c64a7788075669c24010019f57a7464b78c3a6cbee539d9/yarl-1.24.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:e2935f8c39e3b03e83519292d78f075189978f3f4adc15a78144c7c8e2a1cba5", size = 116084, upload-time = "2026-07-20T02:06:59.868Z" }, + { url = "https://files.pythonhosted.org/packages/62/c0/423078fdd4042e1862c11f0ffd977a0ffa393783c12bee94685923bc189e/yarl-1.24.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9d1216a7f6f77836617dba35687c5b78a4170afc3c3f18fc788f785ba26565c4", size = 111006, upload-time = "2026-07-20T02:07:01.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/52/6daa2ee9d95e5c98b8128f8df91eb692eb423ab274b8cf08db52152fad26/yarl-1.24.5-cp314-cp314-win_amd64.whl", hash = "sha256:5ba4f78df2bcc19f764a4b26a8a4f5049c110090ad5825993aacb052bf8003ad", size = 99215, upload-time = "2026-07-20T02:07:03.852Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0e/464a847d7359e0da75dd9fc5c1d1aa35d0159ea31e5f8e66a3c1c29ff3d0/yarl-1.24.5-cp314-cp314-win_arm64.whl", hash = "sha256:9e4e16c73d717c5cf27626c524d0a2e261ad20e46932b2670f64ad5dde23e26f", size = 94566, upload-time = "2026-07-20T02:07:06.074Z" }, + { url = "https://files.pythonhosted.org/packages/e2/55/e03acc4446772660bc335e86e41ef31e4d0d838fd641531a11a5ee33b493/yarl-1.24.5-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e1ae548a9d901adca07899a4147a7c826bbcc06239d3ce9a59f57886a28a4c88", size = 142533, upload-time = "2026-07-20T02:07:08.284Z" }, + { url = "https://files.pythonhosted.org/packages/ae/71/4acd3a1fc7cf14345cdb302665ecd2097f62c365b4f14ca17d4f37775cf9/yarl-1.24.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ff405d91509d88e8d44129cd87b18d70acd1f0c1aeabd7bc3c46792b1fe2acba", size = 100776, upload-time = "2026-07-20T02:07:10.197Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/cfb76b7fe99686db264bff829779a539d923e7564ffd7ef18da6c54c3774/yarl-1.24.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:47e98aab9d8d82ff682e7b0b5dded33bf138a32b817fcf7fa3b27b2d7c412928", size = 100913, upload-time = "2026-07-20T02:07:12.357Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3f/7116e782992abbd4fb6948488aec72078895e929a23078290739e8396fce/yarl-1.24.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f0a658a6d3fafee5c6f63c58f3e785c8c43c93fbc02bf9f2b6663f8185e0971f", size = 106507, upload-time = "2026-07-20T02:07:14.173Z" }, + { url = "https://files.pythonhosted.org/packages/33/90/d4d2d73ee78229cc889872eb8e085d8f5c6f51abdb178409fd9b23cf74fd/yarl-1.24.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4377407001ca3c057773f44d8ddd6358fa5f691407c1ba92210bd3cf8d9e4c95", size = 99219, upload-time = "2026-07-20T02:07:16.019Z" }, + { url = "https://files.pythonhosted.org/packages/3e/fa/a6df1a9bccd644eec00abee0dff4277416222cec435330fd1f2858523ec1/yarl-1.24.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7c0494a31a1ac5461a226e7947a9c9b78c44e1dc7185164fa7e9651557a5d9bc", size = 111804, upload-time = "2026-07-20T02:07:18.141Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9e/7b2a1f4bcc20e9447156dd2b1c4d01f70d9df0759025ee7d09a84ffae134/yarl-1.24.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a7cff474ab7cd149765bb784cf6d78b32e18e20473fb7bda860bce98ab58e9da", size = 110943, upload-time = "2026-07-20T02:07:20.06Z" }, + { url = "https://files.pythonhosted.org/packages/08/ff/22c92affb0f9b623ca753d27d968b5625b868f12c6378d049d55ae247643/yarl-1.24.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cbb833ccacdb5519eff9b8b71ee618cc2801c878e77e288775d77c3a2ced858a", size = 108251, upload-time = "2026-07-20T02:07:22.217Z" }, + { url = "https://files.pythonhosted.org/packages/45/44/5769b96298c1e195fb412997b6090af2a84105cf59c17613558a2d011d1f/yarl-1.24.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:82f75e05912e84b7a0fe57075d9c59de3cb352b928330f2eb69b2e1f54c3e1f0", size = 106025, upload-time = "2026-07-20T02:07:24.083Z" }, + { url = "https://files.pythonhosted.org/packages/4c/40/009e8e791fd9762c0e1567e69248acb4f49064597e1680874c16dd8bb798/yarl-1.24.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:16a2f5010280020e90f5330257e6944bc33e73593b136cc5a241e6c1dc292498", size = 106573, upload-time = "2026-07-20T02:07:26.248Z" }, + { url = "https://files.pythonhosted.org/packages/20/c6/b7480578f8a0a80946f36ad6df547ecec704f9ba69d2de60f8aa6f1c1cbf/yarl-1.24.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ffcd54362564dc1a30fb74d8b8a6e5a6b11ebd5e27266adc3b7427a21a6c9104", size = 100751, upload-time = "2026-07-20T02:07:28.098Z" }, + { url = "https://files.pythonhosted.org/packages/d4/27/4476f3360b91a48c5cf125e91f59a3bd35299d84a431a258d57f5977bb11/yarl-1.24.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0465ec8cedc2349b97a6b595ace64084a50c6e839eca40aa0626f38b8350e331", size = 111643, upload-time = "2026-07-20T02:07:30.88Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4b/5cdd3e5ee944e8af31e52f6cd3d3af5fd7b937e036ccbbba2c9ffebede95/yarl-1.24.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4db9aecb141cb7a5447171b57aa1ed3a8fee06af40b992ffc31206c0b0121550", size = 106312, upload-time = "2026-07-20T02:07:33.06Z" }, + { url = "https://files.pythonhosted.org/packages/18/86/f406b0c2a6f99575de2da671ef47aa06f89a5be83a27a46971c3b86cecdb/yarl-1.24.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f540c013589084679a6c7fac07096b10159737918174f5dfc5e11bf5bca4dfe6", size = 110379, upload-time = "2026-07-20T02:07:35.155Z" }, + { url = "https://files.pythonhosted.org/packages/f0/6c/9f3adfbd3b30b4fa0f7ccb3a83eba2c1152d3fff554d535e640ba0f7ba2b/yarl-1.24.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a61834fb15d81322d872eaafd333838ae7c9cea84067f232656f75965933d047", size = 108497, upload-time = "2026-07-20T02:07:37.35Z" }, + { url = "https://files.pythonhosted.org/packages/dd/37/91eb2e5ca883a529c1b390348a74cd9fc0512171727f547ce70bfe02be5c/yarl-1.24.5-cp314-cp314t-win_amd64.whl", hash = "sha256:5c88e5815a49d289e599f3513aa7fde0bc2092ff188f99c940f007f90f53d104", size = 102450, upload-time = "2026-07-20T02:07:39.578Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f4/ed5c402ac8fde4403ed3366c2716bfddc8a6677ebd59f3d62772cc7fe468/yarl-1.24.5-cp314-cp314t-win_arm64.whl", hash = "sha256:cf139c02f5f23ef6532040a30ff662c00a318c952334f211046b8e60b7f17688", size = 97222, upload-time = "2026-07-20T02:07:41.55Z" }, + { url = "https://files.pythonhosted.org/packages/61/02/962c1cbfc401a30c1d034dc67ff395f64b52302c6d62de556c1fca99acc0/yarl-1.24.5-py3-none-any.whl", hash = "sha256:a33700d13d9b7d84fd10947b09ff69fb9a792e519c8cb9764a3ca70baa6c23a7", size = 58612, upload-time = "2026-07-20T02:07:43.461Z" }, ] [[package]] From 8724e1d3d0dd4e546076c43382d0e39411acdda0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2026 09:37:49 +0200 Subject: [PATCH 119/135] Update nf-core/setup-nextflow digest to 893c28b (#4407) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/actions/create-lint-wf/action.yml | 2 +- .github/workflows/codspeed.yml | 2 +- .github/workflows/create-test-lint-wf-template.yml | 2 +- .github/workflows/create-test-wf.yml | 2 +- .github/workflows/pytest.yml | 2 +- .github/workflows/sync.yml | 2 +- .github/workflows/update-template-snapshots.yml | 2 +- nf_core/pipeline-template/.github/actions/nf-test/action.yml | 2 +- .../pipeline-template/.github/workflows/download_pipeline.yml | 2 +- nf_core/pipeline-template/.github/workflows/fix_linting.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 4 ++-- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/actions/create-lint-wf/action.yml b/.github/actions/create-lint-wf/action.yml index 97a6b95cd9..69d42c5d07 100644 --- a/.github/actions/create-lint-wf/action.yml +++ b/.github/actions/create-lint-wf/action.yml @@ -16,7 +16,7 @@ runs: export NXF_WORK=$(pwd) - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 with: version: ${{ matrix.NXF_VER }} diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index c13facfee6..607dc41355 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -37,7 +37,7 @@ jobs: python-version: "3.14" - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 with: version: ${{ github.event.inputs.nextflow-version || matrix.nextflow-version }} diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index aa5ed29547..ef35dded8b 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -72,7 +72,7 @@ jobs: run: uv sync - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 with: version: latest-everything diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index 2e3c321877..afccfb30d8 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -58,7 +58,7 @@ jobs: run: uv sync - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 with: version: ${{ matrix.NXF_VER }} diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 7b3fea2056..58584d131e 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -94,7 +94,7 @@ jobs: uses: eWaterCycle/setup-apptainer@4bb22c52d4f63406c49e94c804632975787312b3 # v2.0.0 - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 with: version: ${{ github.event.inputs.nextflow-version || matrix.nextflow-version }} diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 7740311e1a..03946f3d23 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -90,7 +90,7 @@ jobs: run: uv sync - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 with: version: "25.10.4" diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index 9223af6b9b..a1791323b1 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -69,7 +69,7 @@ jobs: run: uv sync - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 with: version: latest-everything diff --git a/nf_core/pipeline-template/.github/actions/nf-test/action.yml b/nf_core/pipeline-template/.github/actions/nf-test/action.yml index abda901dd6..960418271f 100644 --- a/nf_core/pipeline-template/.github/actions/nf-test/action.yml +++ b/nf_core/pipeline-template/.github/actions/nf-test/action.yml @@ -20,7 +20,7 @@ runs: using: "composite" steps: - name: Setup Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 with: version: "{% raw %}${{ env.NXF_VERSION }}" diff --git a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml index a5750329df..cd11a93b11 100644 --- a/nf_core/pipeline-template/.github/workflows/download_pipeline.yml +++ b/nf_core/pipeline-template/.github/workflows/download_pipeline.yml @@ -42,7 +42,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 - name: Disk space cleanup uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be # v1.3.1 diff --git a/nf_core/pipeline-template/.github/workflows/fix_linting.yml b/nf_core/pipeline-template/.github/workflows/fix_linting.yml index e417e863a9..4c91656253 100644 --- a/nf_core/pipeline-template/.github/workflows/fix_linting.yml +++ b/nf_core/pipeline-template/.github/workflows/fix_linting.yml @@ -32,7 +32,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.nf_core_bot_auth_token }} - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 # Install and run prek - name: Run prek diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index f3740cf96a..fa18f32cad 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 - name: Run prek uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2 @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Install Nextflow - uses: nf-core/setup-nextflow@b4ec1bc7c16a94435159de94a05253542fddf6ef # v3 + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 with: From f79d71c8a03b7f386ad4663c5398c265f3d72977 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2026 07:45:21 +0000 Subject: [PATCH 120/135] Update astral-sh/setup-uv action to v9 (#4408) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codspeed.yml | 2 +- .github/workflows/create-lint-wf.yml | 2 +- .github/workflows/create-test-lint-wf-template.yml | 2 +- .github/workflows/create-test-wf.yml | 2 +- .github/workflows/deploy-pypi.yml | 2 +- .github/workflows/nextflow-source-test.yml | 2 +- .github/workflows/pytest.yml | 2 +- .github/workflows/sync.yml | 2 +- .github/workflows/update-template-snapshots.yml | 2 +- .github/workflows/update-textual-snapshots.yml | 2 +- nf_core/pipeline-template/.github/workflows/linting.yml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 607dc41355..085e6d5b2e 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -42,7 +42,7 @@ jobs: version: ${{ github.event.inputs.nextflow-version || matrix.nextflow-version }} - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/.github/workflows/create-lint-wf.yml b/.github/workflows/create-lint-wf.yml index f613a66237..c078ac4068 100644 --- a/.github/workflows/create-lint-wf.yml +++ b/.github/workflows/create-lint-wf.yml @@ -52,7 +52,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/.github/workflows/create-test-lint-wf-template.yml b/.github/workflows/create-test-lint-wf-template.yml index ef35dded8b..9c101fbdd5 100644 --- a/.github/workflows/create-test-lint-wf-template.yml +++ b/.github/workflows/create-test-lint-wf-template.yml @@ -64,7 +64,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/.github/workflows/create-test-wf.yml b/.github/workflows/create-test-wf.yml index afccfb30d8..9a3774ac2b 100644 --- a/.github/workflows/create-test-wf.yml +++ b/.github/workflows/create-test-wf.yml @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/.github/workflows/deploy-pypi.yml b/.github/workflows/deploy-pypi.yml index 2ebd3e12dc..8786b5a084 100644 --- a/.github/workflows/deploy-pypi.yml +++ b/.github/workflows/deploy-pypi.yml @@ -22,7 +22,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/.github/workflows/nextflow-source-test.yml b/.github/workflows/nextflow-source-test.yml index ec21e5a264..649fdc42dc 100644 --- a/.github/workflows/nextflow-source-test.yml +++ b/.github/workflows/nextflow-source-test.yml @@ -50,7 +50,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 58584d131e..fd2f04dd2d 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -82,7 +82,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index 03946f3d23..e62b7a4869 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -82,7 +82,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index a1791323b1..c37087b611 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -61,7 +61,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index ec5da6f216..9d1728d676 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -42,7 +42,7 @@ jobs: python-version: "3.14" - name: Install uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 with: enable-cache: true diff --git a/nf_core/pipeline-template/.github/workflows/linting.yml b/nf_core/pipeline-template/.github/workflows/linting.yml index fa18f32cad..80c7055ef1 100644 --- a/nf_core/pipeline-template/.github/workflows/linting.yml +++ b/nf_core/pipeline-template/.github/workflows/linting.yml @@ -34,7 +34,7 @@ jobs: architecture: "x64" - name: Setup uv - uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 - name: read .nf-core.yml uses: pietrobolcato/action-read-yaml@9f13718d61111b69f30ab4ac683e67a56d254e1d # 1.1.0 From e2faa414b380b836043fef4f90da09af576e12d1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2026 11:52:00 +0200 Subject: [PATCH 121/135] Update docker/login-action digest to 06fb636 (#4417) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codspeed.yml | 2 +- .github/workflows/push_dockerhub.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 085e6d5b2e..4a616d2ccb 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -60,7 +60,7 @@ jobs: # import/start-up cost, which CodSpeed's instruction-counting # "simulation" instrument can't see. Use "walltime" mode instead. - name: Run start-up benchmarks - uses: CodSpeedHQ/action@f99becdce5e5d51fd556489ebef684f4ecfd6286 # v4.18.5 + uses: CodSpeedHQ/action@f22792bfac16f3e14eb9fbea76f4a48e9cc22b93 # v4.19.1 with: mode: walltime run: uv run pytest benchmarks/test_startup_benchmarks.py --codspeed diff --git a/.github/workflows/push_dockerhub.yml b/.github/workflows/push_dockerhub.yml index 162495c6e8..fbd208cddc 100644 --- a/.github/workflows/push_dockerhub.yml +++ b/.github/workflows/push_dockerhub.yml @@ -43,7 +43,7 @@ jobs: uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 - name: Log in to Docker Hub - uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4 + uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASS }} From 8190b0818fc4f320ca835158d7f17b183e9f03aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 28 Jul 2026 11:53:17 +0200 Subject: [PATCH 122/135] Update github/branch-deploy action to v12 (#4418) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/changelog.yml | 2 +- .github/workflows/clean-up.yml | 2 +- .github/workflows/fix-linting.yml | 2 +- .github/workflows/update-template-snapshots.yml | 2 +- .github/workflows/update-textual-snapshots.yml | 2 +- nf_core/pipeline-template/.github/workflows/clean-up.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 8f4242bfe4..7129fb31e7 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -12,7 +12,7 @@ jobs: - name: branch-deploy id: branch-deploy if: github.event_name == 'issue_comment' - uses: github/branch-deploy@de4d10ee17c3117a2076aff489ba03fadf225f35 # v11.1.5 + uses: github/branch-deploy@f0984057ffe1aa340aa017b6eafb894310aed88e # v12.0.0 with: trigger: "@nf-core-bot changelog" reaction: "eyes" diff --git a/.github/workflows/clean-up.yml b/.github/workflows/clean-up.yml index 4a51eef698..866b79f14b 100644 --- a/.github/workflows/clean-up.yml +++ b/.github/workflows/clean-up.yml @@ -10,7 +10,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11 with: stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment if it is still useful." diff --git a/.github/workflows/fix-linting.yml b/.github/workflows/fix-linting.yml index 4c0b2fd2a1..4415e97907 100644 --- a/.github/workflows/fix-linting.yml +++ b/.github/workflows/fix-linting.yml @@ -12,7 +12,7 @@ jobs: steps: - name: branch-deploy id: branch-deploy - uses: github/branch-deploy@de4d10ee17c3117a2076aff489ba03fadf225f35 # v11.1.5 + uses: github/branch-deploy@f0984057ffe1aa340aa017b6eafb894310aed88e # v12.0.0 with: trigger: "@nf-core-bot fix linting" reaction: "eyes" diff --git a/.github/workflows/update-template-snapshots.yml b/.github/workflows/update-template-snapshots.yml index c37087b611..8adbcda40e 100644 --- a/.github/workflows/update-template-snapshots.yml +++ b/.github/workflows/update-template-snapshots.yml @@ -15,7 +15,7 @@ jobs: steps: - name: branch-deploy id: branch-deploy - uses: github/branch-deploy@de4d10ee17c3117a2076aff489ba03fadf225f35 # v11.1.5 + uses: github/branch-deploy@f0984057ffe1aa340aa017b6eafb894310aed88e # v12.0.0 with: trigger: "@nf-core-bot update template snapshots" reaction: "eyes" diff --git a/.github/workflows/update-textual-snapshots.yml b/.github/workflows/update-textual-snapshots.yml index 9d1728d676..fe029d48b9 100644 --- a/.github/workflows/update-textual-snapshots.yml +++ b/.github/workflows/update-textual-snapshots.yml @@ -10,7 +10,7 @@ jobs: steps: - name: branch-deploy id: branch-deploy - uses: github/branch-deploy@de4d10ee17c3117a2076aff489ba03fadf225f35 # v11.1.5 + uses: github/branch-deploy@f0984057ffe1aa340aa017b6eafb894310aed88e # v12.0.0 with: trigger: "@nf-core-bot update textual snapshots" reaction: "eyes" diff --git a/nf_core/pipeline-template/.github/workflows/clean-up.yml b/nf_core/pipeline-template/.github/workflows/clean-up.yml index 309a0c5790..93f7941d75 100644 --- a/nf_core/pipeline-template/.github/workflows/clean-up.yml +++ b/nf_core/pipeline-template/.github/workflows/clean-up.yml @@ -10,7 +10,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/stale@1e223db275d687790206a7acac4d1a11bd6fe629 # v10 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11 with: stale-issue-message: "This issue has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment otherwise this issue will be closed in 20 days." stale-pr-message: "This PR has been tagged as awaiting-changes or awaiting-feedback by an nf-core contributor. Remove stale label or add a comment if it is still useful." From 97044e9949de0b1598b842636f6c3157fb685bbb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:40:10 +0200 Subject: [PATCH 123/135] Update docker/login-action digest to 371161b (#4421) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/push_dockerhub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_dockerhub.yml b/.github/workflows/push_dockerhub.yml index fbd208cddc..557c9b8a46 100644 --- a/.github/workflows/push_dockerhub.yml +++ b/.github/workflows/push_dockerhub.yml @@ -43,7 +43,7 @@ jobs: uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 - name: Log in to Docker Hub - uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4 + uses: docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c # v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASS }} From 3c84e83107cead22171727f5aa5676e1f6b3fc0e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 10:19:25 +0000 Subject: [PATCH 124/135] Update dependency setuptools to v83 [SECURITY] (#4413) --- pyproject.toml | 2 +- uv.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0ece14b915..e0b973fec3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ dependencies = [ "rich>=13.3.1", "rocrate", "repo2rocrate", - "setuptools<81", + "setuptools<84", "tabulate", "textual==8.2.7", "trogon", diff --git a/uv.lock b/uv.lock index 880e096a8e..05ba222567 100644 --- a/uv.lock +++ b/uv.lock @@ -1823,7 +1823,7 @@ requires-dist = [ { name = "rich-click", specifier = "==1.9.*" }, { name = "rocrate" }, { name = "ruamel-yaml" }, - { name = "setuptools", specifier = "<81" }, + { name = "setuptools", specifier = "<84" }, { name = "tabulate" }, { name = "textual", specifier = "==8.2.7" }, { name = "trogon" }, @@ -3488,11 +3488,11 @@ wheels = [ [[package]] name = "setuptools" -version = "80.10.2" +version = "83.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/76/95/faf61eb8363f26aa7e1d762267a8d602a1b26d4f3a1e758e92cb3cb8b054/setuptools-80.10.2.tar.gz", hash = "sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70", size = 1200343, upload-time = "2026-01-25T22:38:17.252Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/26/f5d29e25ffdb535afef2d35cdb55b325298f96debd670da4c325e08d70f4/setuptools-83.0.0.tar.gz", hash = "sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef", size = 1154254, upload-time = "2026-07-04T15:31:22.699Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/b8/f1f62a5e3c0ad2ff1d189590bfa4c46b4f3b6e49cef6f26c6ee4e575394d/setuptools-80.10.2-py3-none-any.whl", hash = "sha256:95b30ddfb717250edb492926c92b5221f7ef3fbcc2b07579bcd4a27da21d0173", size = 1064234, upload-time = "2026-01-25T22:38:15.216Z" }, + { url = "https://files.pythonhosted.org/packages/5d/40/e1e72872c6354b306daef1703549e8e83b4d43cfea356311bf722a043752/setuptools-83.0.0-py3-none-any.whl", hash = "sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3", size = 1008090, upload-time = "2026-07-04T15:31:20.885Z" }, ] [[package]] From be3afc3bccf58a29371088146727646d1625d2b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 10:26:08 +0000 Subject: [PATCH 125/135] Update pre-commit hooks (#4424) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 63fff74030..9e70f640c2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.22 + rev: v0.16.0 hooks: - id: ruff-check # linter args: [--fix, --exit-non-zero-on-fix] # sort imports and fix @@ -49,7 +49,7 @@ repos: - types-setuptools - pydantic - repo: https://github.com/astral-sh/uv-pre-commit - rev: 0.11.30 + rev: 0.12.0 hooks: - id: uv-lock priority: 20 From 2c0bf873be9ce2d83dce4358c97f5f4e21e9fd29 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 10:27:45 +0000 Subject: [PATCH 126/135] Update mcr.microsoft.com/devcontainers/base Docker tag to v2.1.11 (#4423) --- .devcontainer/build-devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/build-devcontainer/Dockerfile b/.devcontainer/build-devcontainer/Dockerfile index e1a66c1181..355041eb35 100644 --- a/.devcontainer/build-devcontainer/Dockerfile +++ b/.devcontainer/build-devcontainer/Dockerfile @@ -27,7 +27,7 @@ RUN rm -f /etc/apt/sources.list.d/yarn.list && \ rm -rf /var/lib/apt/lists/* # Final stage to copy only the required files after installation -FROM mcr.microsoft.com/devcontainers/base:2.1.8-debian12@sha256:17e6cc517b483d1108b333d4c34352b0a21617f0117052e9b259d47113a9dc37 AS final +FROM mcr.microsoft.com/devcontainers/base:2.1.11-debian12@sha256:bb7b81b6e5be17b5267f92f4ffda534fea37dab1df97b5e86c1f9b91da5c0b5d AS final # Copy only the conda environment and site-packages from build stage COPY --from=build /opt/conda /opt/conda From 87320d96117d01df1b394d70756050b5e2e8a9aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 12:43:24 +0200 Subject: [PATCH 127/135] Update dependency textual to v8.2.8 (#4422) --- pyproject.toml | 2 +- uv.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e0b973fec3..74f20613f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ dependencies = [ "repo2rocrate", "setuptools<84", "tabulate", - "textual==8.2.7", + "textual==8.2.8", "trogon", "pdiff", "ruamel.yaml", diff --git a/uv.lock b/uv.lock index 05ba222567..274bdb5bfd 100644 --- a/uv.lock +++ b/uv.lock @@ -1825,7 +1825,7 @@ requires-dist = [ { name = "ruamel-yaml" }, { name = "setuptools", specifier = "<84" }, { name = "tabulate" }, - { name = "textual", specifier = "==8.2.7" }, + { name = "textual", specifier = "==8.2.8" }, { name = "trogon" }, ] @@ -3742,7 +3742,7 @@ wheels = [ [[package]] name = "textual" -version = "8.2.7" +version = "8.2.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, extra = ["linkify"], marker = "python_full_version < '3.11'" }, @@ -3753,9 +3753,9 @@ dependencies = [ { name = "rich" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9b/7a/c519db0aba5024f86e71e9631810bfdd6866ed2c8695bd7fa34b90e7ef59/textual-8.2.7.tar.gz", hash = "sha256:658f568ff81e30ed43890c3e07520390e5cf1b4763822006e060656b0a88f105", size = 1859249, upload-time = "2026-05-19T10:52:49.531Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/21/39a76b01bd5eea82a04baaca7580e105d8c59450df03998345bb2cfb307b/textual-8.2.8.tar.gz", hash = "sha256:3f106a9fbc73e39dd266c9712432087de78a6d644084c7c241d6a25c3169115b", size = 1860502, upload-time = "2026-06-30T06:51:24.495Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/f5/c1e18bc0707300a0e90204343abbf7d7acd6fb7ebe03a6d4893b99a234b8/textual-8.2.7-py3-none-any.whl", hash = "sha256:4caaa13a90bc4cf9c6c862c067ccd34fe84e9c161710a2a907a8026313b6bd73", size = 731129, upload-time = "2026-05-19T10:52:51.773Z" }, + { url = "https://files.pythonhosted.org/packages/fb/be/35261223d9416a0751cdff1c7b4a6f881387218a12d439fe22fefebc8c04/textual-8.2.8-py3-none-any.whl", hash = "sha256:267375fd402dc8d981457212efa71f0e3365fd17bba144ba9bb3ed7563cb374a", size = 731418, upload-time = "2026-06-30T06:51:26.364Z" }, ] [[package]] From d809a90da2f910d66f9e2978053165009baa2a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 29 Jul 2026 14:26:54 +0200 Subject: [PATCH 128/135] add nextflow version fallback to sync action (#4425) --- .github/workflows/sync.yml | 24 ++++++++++++++++++++++++ nf_core/utils.py | 7 ++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index e62b7a4869..7d9cf05901 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -108,7 +108,31 @@ jobs: git config --global init.defaultBranch $defaultBranch - name: Run synchronisation + id: sync if: github.repository == 'nf-core/tools' + continue-on-error: true + env: + GITHUB_AUTH_TOKEN: ${{ secrets.nf_core_bot_auth_token }} + run: | + git config --global user.email "core@nf-co.re" + git config --global user.name "nf-core-bot" + uv run nf-core --log-file sync_log_${{ matrix.pipeline }}.txt \ + ${{ github.event.inputs.debug == 'true' && '--verbose' || '' }} \ + pipelines sync -d nf-core/${{ matrix.pipeline }} \ + --from-branch dev \ + --pull-request \ + --username nf-core-bot \ + --github-repository nf-core/${{ matrix.pipeline }} \ + --blog-post ${{inputs.blog_post}} + + - name: Install newer Nextflow (retry fallback) + if: github.repository == 'nf-core/tools' && steps.sync.outcome == 'failure' + uses: nf-core/setup-nextflow@893c28b667aedeba26e37f296d260ccc5bc4d914 # v3 + with: + version: "26.04.6" + + - name: Retry synchronisation with newer Nextflow + if: github.repository == 'nf-core/tools' && steps.sync.outcome == 'failure' env: GITHUB_AUTH_TOKEN: ${{ secrets.nf_core_bot_auth_token }} run: | diff --git a/nf_core/utils.py b/nf_core/utils.py index e53744bb88..93a09971ba 100644 --- a/nf_core/utils.py +++ b/nf_core/utils.py @@ -553,7 +553,12 @@ def fetch_wf_config(wf_path: Path, cache_config: bool = True) -> dict: log.debug("No config cache found") # Call `nextflow config` - result = run_cmd("nextflow", f"config -o json {wf_path}") + try: + result = run_cmd("nextflow", f"config -o json {wf_path}") + except RuntimeError as e: + raise UserWarning( + f"Could not parse Nextflow config for '{wf_path}'. Possibly because of a Nextflow version mismatch?\n{e}" + ) from e if result is not None: nfconfig_raw, _ = result try: From 491ab83e0d64e113a9d15fed280cc740706a85af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 29 Jul 2026 14:29:11 +0200 Subject: [PATCH 129/135] fix changelog action (#4426) --- .github/workflows/changelog.yml | 56 ++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 7129fb31e7..dd5ff6e347 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -3,27 +3,46 @@ on: issue_comment: types: [created] # Add "@nf-core-bot changelog" as a PR comment to trigger this workflow. +permissions: {} + jobs: update_changelog: runs-on: ubuntu-latest - if: contains(github.event.comment.body, '@nf-core-bot changelog') + if: > + github.event.issue.pull_request && + contains(github.event.comment.body, '@nf-core-bot changelog') steps: - - name: branch-deploy - id: branch-deploy - if: github.event_name == 'issue_comment' - uses: github/branch-deploy@f0984057ffe1aa340aa017b6eafb894310aed88e # v12.0.0 - with: - trigger: "@nf-core-bot changelog" - reaction: "eyes" - stable_branch: "dev" + - name: Verify commenter is on the nf-core/infrastructure team + env: + GH_TOKEN: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} + ACTOR: ${{ github.event.comment.user.login }} + run: | + state=$(gh api "orgs/nf-core/teams/infrastructure/memberships/${ACTOR}" --jq '.state' 2>/dev/null || true) + if [ "$state" != "active" ]; then + echo "::error::@${ACTOR} is not an active member of nf-core/infrastructure; refusing to run." + exit 1 + fi + echo "@${ACTOR} is on nf-core/infrastructure — proceeding." + + - name: React to the triggering comment + env: + GH_TOKEN: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} + run: | + gh api --method POST \ + "repos/${{ github.repository }}/issues/comments/${{ github.event.comment.id }}/reactions" \ + -f content=eyes - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + # Checks out the base ref (the trusted version of the repo) first. + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: token: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} - # Action runs on the issue comment, so we don't get the PR by default. - # Use the GitHub CLI to check out the PR: + - name: Save trusted scripts + run: | + cp "${GITHUB_WORKSPACE}/.github/workflows/changelog.py" "${RUNNER_TEMP}/changelog.py" + cp "${GITHUB_WORKSPACE}/.pre-commit-config.yaml" "${RUNNER_TEMP}/pre-commit-config.yaml" + - name: Checkout Pull Request env: GH_TOKEN: ${{ secrets.NF_CORE_BOT_AUTH_TOKEN }} @@ -45,19 +64,19 @@ jobs: PR_NUMBER: ${{ github.event.issue.number || github.event.pull_request.number }} PR_TITLE: ${{ github.event.issue.title || github.event.pull_request.title }} run: | - python ${GITHUB_WORKSPACE}/.github/workflows/changelog.py + python "${RUNNER_TEMP}/changelog.py" - name: Check if CHANGELOG.md actually changed id: file_changed run: | # Show the diff for debugging - git diff -- ${GITHUB_WORKSPACE}/CHANGELOG.md + git diff -- "${GITHUB_WORKSPACE}/CHANGELOG.md" # Check if file has unstaged changes - [ -n "$(git diff -- ${GITHUB_WORKSPACE}/CHANGELOG.md)" ] && file_changed="TRUE" || file_changed="FALSE" + [ -n "$(git diff -- "${GITHUB_WORKSPACE}/CHANGELOG.md")" ] && file_changed="TRUE" || file_changed="FALSE" echo "File changed: $file_changed" - echo "changed=$file_changed" >> $GITHUB_OUTPUT + echo "changed=$file_changed" >> "$GITHUB_OUTPUT" - name: Set up Python 3.14 uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7 @@ -65,10 +84,11 @@ jobs: python-version: "3.14" - name: Run pre-commit rules with prek + if: steps.file_changed.outputs.changed == 'TRUE' uses: j178/prek-action@5337cb91e0fa35a7ff31b9ca345126d8bbbcdf16 # v2 continue-on-error: true with: - extra-args: --config .pre-commit-config.yaml --all-files + extra-args: --config ${{ runner.temp }}/pre-commit-config.yaml --files CHANGELOG.md - name: Commit and push changes if: steps.file_changed.outputs.changed == 'TRUE' @@ -77,7 +97,7 @@ jobs: run: | git config user.email "core@nf-co.re" git config user.name "nf-core-bot" - git add ${GITHUB_WORKSPACE}/CHANGELOG.md + git add "${GITHUB_WORKSPACE}/CHANGELOG.md" git status git commit -m "[automated] Update CHANGELOG.md [skip ci]" git push From efb1a478ea82a74d3bc5c3fe9a223bee3a2e2864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 29 Jul 2026 15:11:21 +0200 Subject: [PATCH 130/135] bump to 4.1.0 and update components in template (#4398) --- CHANGELOG.md | 2 +- nf_core/pipeline-template/modules.json | 6 +- .../linux_amd64-bd-c17fb751507e9dfc_1.txt | 1526 +++++++++++++++++ .../linux_arm64-bd-5c84a5000a226ab5_1.txt | 1476 ++++++++++++++++ .../modules/nf-core/multiqc/environment.yml | 2 +- .../modules/nf-core/multiqc/main.nf | 4 +- .../modules/nf-core/multiqc/meta.yml | 28 +- .../nf-core/multiqc/tests/main.nf.test.snap | 10 +- .../utils_nfcore_pipeline_pipeline/main.nf | 3 +- .../nf-core/utils_nfschema_plugin/main.nf | 12 +- .../nf-core/utils_nfschema_plugin/meta.yml | 24 + .../utils_nfschema_plugin/tests/main.nf.test | 5 + .../tests/nextflow.config | 2 +- pyproject.toml | 2 +- tests/pipelines/test_sync.py | 4 +- uv.lock | 572 +++--- 16 files changed, 3425 insertions(+), 253 deletions(-) create mode 100644 nf_core/pipeline-template/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt create mode 100644 nf_core/pipeline-template/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-5c84a5000a226ab5_1.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aa19be175..c169f3a630 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # nf-core/tools: Changelog -## v4.1.0dev +## [v4.1.0 - marshalled mamba](https://github.com/nf-core/tools/releases/tag/4.1.0) - [2026-07-21] ### General diff --git a/nf_core/pipeline-template/modules.json b/nf_core/pipeline-template/modules.json index cac8420ac2..85c482327c 100644 --- a/nf_core/pipeline-template/modules.json +++ b/nf_core/pipeline-template/modules.json @@ -13,7 +13,7 @@ }{% endif %}{%- if multiqc %}{% if fastqc %},{% endif %} "multiqc": { "branch": "master", - "git_sha": "008f9d3e61209bf995edac3ba531f54e269e1215", + "git_sha": "98403d15b0e50edae1f3fec5eae5e24982f1fade", "installed_by": ["modules"] } {%- endif %} @@ -23,7 +23,7 @@ "nf-core": { "utils_nextflow_pipeline": { "branch": "master", - "git_sha": "05954dab2ff481bcb999f24455da29a5828af08d", + "git_sha": "c2b22d85f30a706a3073387f30380704fcae013b", "installed_by": ["subworkflows"] }, "utils_nfcore_pipeline": { @@ -33,7 +33,7 @@ }{% if nf_schema %}, "utils_nfschema_plugin": { "branch": "master", - "git_sha": "fdc08b8b1ae74f56686ce21f7ea11ad11990ce57", + "git_sha": "a7b27fd25bfa8dcc07d299e88bd790585901a436", "installed_by": ["subworkflows"] }{% endif %} } diff --git a/nf_core/pipeline-template/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt b/nf_core/pipeline-template/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt new file mode 100644 index 0000000000..2a91c22d61 --- /dev/null +++ b/nf_core/pipeline-template/modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt @@ -0,0 +1,1526 @@ + +version: 6 +environments: +default: +channels: +- url: https://conda.anaconda.org/conda-forge/ +- url: https://conda.anaconda.org/bioconda/ +- url: https://conda.anaconda.org/bioconda/ +options: +pypi-prerelease-mode: if-necessary-or-explicit +packages: +linux-64: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.5.0-py314h680f03e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.0-pyhc90fa1f_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.5-py314hd8ed1ab_100.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.8.1-hecca717_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.18.0-h27c8c51_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.15-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/kaleido-core-0.2.1-h3644ca4_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-7_h4a7cf45_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-7_h0358290_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-7_h47877c9_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.33-pthreads_h94d23a6_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.2.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/mathjax-2.7.7-ha770c72_3.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.35-pyhdfd78af_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.6-py314h2b28147_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.41.0-pyh58ad624_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.41.0-py310h49dadd8_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.41.0-py310hcbd6021_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py314h2e6c369_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.5-habeac84_100_cp314.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.5-h4df99d1_100.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/regex-2026.5.9-py314h5bd0f2a_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.53.1-hbc0de68_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/tiktoken-0.12.0-py314h67fec18_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda +build_number: 20 +sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 +md5: a9f577daf3de00bca7c3c76c0ecbd1de +depends: +- __glibc >=2.17,<3.0.a0 +- libgomp >=7.5.0 +constrains: +- openmp_impl <0.0a0 +license: BSD-3-Clause +license_family: BSD +size: 28948 +timestamp: 1770939786096 +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda +sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 +md5: aaa2a381ccc56eac91d63b6c1240312f +depends: +- cpython +- python-gil +license: MIT +license_family: MIT +size: 8191 +timestamp: 1744137672556 +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda +sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 +md5: 2934f256a8acfe48f6ebb4fce6cde29c +depends: +- python >=3.9 +- typing-extensions >=4.0.0 +license: MIT +license_family: MIT +size: 18074 +timestamp: 1733247158254 +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda +sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab +md5: c6b0543676ecb1fb2d7643941fe375f2 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 64927 +timestamp: 1773935801332 +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.5.0-py314h680f03e_0.conda +noarch: generic +sha256: a1c97297e867776760489537bc5ae36fa83a154be30e3b79385a39ca4cb058fe +md5: 1133126d840e75287d83947be3fc3e71 +depends: +- python >=3.14 +license: BSD-3-Clause AND MIT AND EPL-2.0 +size: 7533 +timestamp: 1778594057496 +- conda: https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda +sha256: 3ad3500bff54a781c29f16ce1b288b36606e2189d0b0ef2f67036554f47f12b0 +md5: 8910d2c46f7e7b519129f486e0fe927a +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +constrains: +- libbrotlicommon 1.2.0 hb03c661_1 +license: MIT +license_family: MIT +size: 367376 +timestamp: 1764017265553 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda +sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 +md5: d2ffd7602c02f2b316fd921d39876885 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: bzip2-1.0.6 +license_family: BSD +size: 260182 +timestamp: 1771350215188 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda +sha256: 9812a303a1395e1dafbd92e5bc8a1ff6013bcbba0a09c7f03a8d23e43560aa9b +md5: 489b8e97e666c93f68fdb35c3c9b957f +depends: +- __unix +license: ISC +size: 129868 +timestamp: 1779289852439 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda +sha256: 645655a3510e38e625da136595f3f16f2130c3263630cc3bc8f60f619ddbe490 +md5: 9fefff2f745ea1cc2ef15211a20c054a +depends: +- python >=3.10 +license: ISC +size: 134201 +timestamp: 1779285131141 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda +sha256: 3f9483d62ce24ecd063f8a5a714448445dc8d9e201147c46699fc0033e824457 +md5: a9167b9571f3baa9d448faa2139d1089 +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 58872 +timestamp: 1775127203018 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.0-pyhc90fa1f_0.conda +sha256: 99ab8ef815c4520cce3a7482c2513f377c14348206857661d84c76a55e030f97 +md5: 003767c47f1f0a474c4de268b57839c3 +depends: +- __unix +- python +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 104631 +timestamp: 1779108494556 +- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda +sha256: 8021c76eeadbdd5784b881b165242db9449783e12ce26d6234060026fd6a8680 +md5: b866ff7007b934d564961066c8195983 +depends: +- humanfriendly >=9.1 +- python >=3.9 +license: MIT +license_family: MIT +size: 43758 +timestamp: 1733928076798 +- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda +sha256: 59c9e29800b483b390467f90e82b0da3a4fbf0612efe1c90813fca232780e160 +md5: 071cf7b0ce333c81718b054066c15102 +depends: +- networkx >=2.0 +- numpy +- python >=3.9 +license: BSD-3-Clause +license_family: BSD +size: 39326 +timestamp: 1735759976140 +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.5-py314hd8ed1ab_100.conda +noarch: generic +sha256: 777882d2685f368417f31bbe1b28f73687fc6c8f6a5768bda20ffeefa6b07f5b +md5: a749029ce5d0632a913db19d17f944ab +depends: +- python >=3.14,<3.15.0a0 +- python_abi * *_cp314 +license: Python-2.0 +size: 50212 +timestamp: 1779236682725 +- conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.8.1-hecca717_0.conda +sha256: 29a10599d56d93bd750914888ebe6822d47722070762b4647b34d12df9f4476e +md5: d0757fd84af06f065eba49d39af6c546 +depends: +- __glibc >=2.17,<3.0.a0 +- libexpat 2.8.1 hecca717_0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 148238 +timestamp: 1779278694477 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b +md5: 0c96522c6bdaed4b1566d11387caaf45 +license: BSD-3-Clause +license_family: BSD +size: 397370 +timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c +md5: 34893075a5c9e55cdafac56607368fc6 +license: OFL-1.1 +license_family: Other +size: 96530 +timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 +md5: 4d59c254e01d9cde7957100457e2d5fb +license: OFL-1.1 +license_family: Other +size: 700814 +timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 +md5: 49023d73832ef61042f6a237cb2687e7 +license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 +license_family: Other +size: 1620504 +timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.18.0-h27c8c51_0.conda +sha256: e798086d8a65d55dc4c51f5746705639c9a5f2eeb0b8fc50e6152cfc0d69a4e8 +md5: 06965b2f9854d0b15e0443ee81fe83dc +depends: +- __glibc >=2.17,<3.0.a0 +- libexpat >=2.8.1,<3.0a0 +- libfreetype >=2.14.3 +- libfreetype6 >=2.14.3 +- libgcc >=14 +- libuuid >=2.42.1,<3.0a0 +- libzlib >=1.3.2,<2.0a0 +license: MIT +license_family: MIT +size: 280882 +timestamp: 1779421631622 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 +md5: a7970cd949a077b7cb9696379d338681 +depends: +- font-ttf-ubuntu +- font-ttf-inconsolata +- font-ttf-dejavu-sans-mono +- font-ttf-source-code-pro +license: BSD-3-Clause +license_family: BSD +size: 4059 +timestamp: 1762351264405 +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda +sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 +md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 +depends: +- python >=3.10 +- hyperframe >=6.1,<7 +- hpack >=4.1,<5 +- python +license: MIT +license_family: MIT +size: 95967 +timestamp: 1756364871835 +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda +sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba +md5: 0a802cb9888dd14eeefc611f05c40b6e +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 30731 +timestamp: 1737618390337 +- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda +sha256: fa2071da7fab758c669e78227e6094f6b3608228740808a6de5d6bce83d9e52d +md5: 7fe569c10905402ed47024fc481bb371 +depends: +- __unix +- python >=3.9 +license: MIT +license_family: MIT +size: 73563 +timestamp: 1733928021866 +- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda +sha256: 6c4343b376d0b12a4c75ab992640970d36c933cad1fd924f6a1181fa91710e80 +md5: daddf757c3ecd6067b9af1df1f25d89e +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 67994 +timestamp: 1766267728652 +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda +sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 +md5: 8e6923fc12f1fe8f8c4e5c9f343256ac +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 17397 +timestamp: 1737618427549 +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.15-pyhcf101f3_0.conda +sha256: 3d25f9f6f7ab3e1ce6429fc8c8aae0335cf446692e715068488536d220cc43de +md5: 1b9083b7f00609605d1483dbc6071a81 +depends: +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 62642 +timestamp: 1779294335905 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda +sha256: 43e2a5497cad1598ff88a3e69f69bc88b7b8f141fa63c60eab5db296317318b8 +md5: ffc17e785d64e12fc311af9184221839 +depends: +- python >=3.10 +- zipp >=3.20 +- python +license: Apache-2.0 +size: 34766 +timestamp: 1779714582554 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda +sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b +md5: 04558c96691bed63104678757beb4f8d +depends: +- markupsafe >=2.0 +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 120685 +timestamp: 1764517220861 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda +sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 +md5: ada41c863af263cc4c5fcbaff7c3e4dc +depends: +- attrs >=22.2.0 +- jsonschema-specifications >=2023.3.6 +- python >=3.10 +- referencing >=0.28.4 +- rpds-py >=0.25.0 +- python +license: MIT +license_family: MIT +size: 82356 +timestamp: 1767839954256 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda +sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 +md5: 439cd0f567d697b20a8f45cb70a1005a +depends: +- python >=3.10 +- referencing >=0.31.0 +- python +license: MIT +license_family: MIT +size: 19236 +timestamp: 1757335715225 +- conda: https://conda.anaconda.org/conda-forge/linux-64/kaleido-core-0.2.1-h3644ca4_0.tar.bz2 +sha256: 7f243680ca03eba7457b7a48f93a9440ba8181a8eac20a3eb5ef165ab6c96664 +md5: b3723b235b0758abaae8c82ce4d80146 +depends: +- __glibc >=2.17,<3.0.a0 +- expat >=2.2.10,<3.0.0a0 +- fontconfig +- fonts-conda-forge +- libgcc-ng >=9.3.0 +- mathjax 2.7.* +- nspr >=4.29,<5.0a0 +- nss >=3.62,<4.0a0 +- sqlite >=3.34.0,<4.0a0 +license: MIT +license_family: MIT +size: 62099926 +timestamp: 1615199463039 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_0.conda +sha256: eb89c6c39f2f6a93db55723dbb2f6bba8c8e63e6312bf1abf13e6e9ff45849c8 +md5: f92f984b558e6e6204014b16d212b271 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.4.1,<4.0a0 +- libtiff >=4.7.1,<4.8.0a0 +license: MIT +license_family: MIT +size: 251086 +timestamp: 1778079286384 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda +sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c +md5: 18335a698559cdbcd86150a48bf54ba6 +depends: +- __glibc >=2.17,<3.0.a0 +- zstd >=1.5.7,<1.6.0a0 +constrains: +- binutils_impl_linux-64 2.45.1 +license: GPL-3.0-only +license_family: GPL +size: 728002 +timestamp: 1774197446916 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda +sha256: f84cb54782f7e9cea95e810ea8fef186e0652d0fa73d3009914fa2c1262594e1 +md5: a752488c68f2e7c456bcbd8f16eec275 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: Apache-2.0 +license_family: Apache +size: 261513 +timestamp: 1773113328888 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-7_h4a7cf45_openblas.conda +build_number: 7 +sha256: 081c850f99bc355821fac9c6e3727d40b3f8ce3beb50a5437cf03726b611ff39 +md5: 955b44e8b00b7f7ef4ce0130cef12394 +depends: +- libopenblas >=0.3.33,<0.3.34.0a0 +- libopenblas >=0.3.33,<1.0a0 +constrains: +- libcblas 3.11.0 7*_openblas +- blas 2.307 openblas +- liblapack 3.11.0 7*_openblas +- liblapacke 3.11.0 7*_openblas +- mkl <2027 +license: BSD-3-Clause +license_family: BSD +size: 18716 +timestamp: 1778489854108 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-7_h0358290_openblas.conda +build_number: 7 +sha256: 956ae0bb1ec8b0c3663d75b151aceb0521b54e513bf97f621a035f9c87037970 +md5: 0675639dc24cb0032f199e7ff68e4633 +depends: +- libblas 3.11.0 7_h4a7cf45_openblas +constrains: +- liblapacke 3.11.0 7*_openblas +- blas 2.307 openblas +- liblapack 3.11.0 7*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18675 +timestamp: 1778489861559 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda +sha256: aa8e8c4be9a2e81610ddf574e05b64ee131fab5e0e3693210c9d6d2fba32c680 +md5: 6c77a605a7a689d17d4819c0f8ac9a00 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 73490 +timestamp: 1761979956660 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_0.conda +sha256: 363018b25fdb5534c79783d912bd4b685a3547f4fc5996357ad548899b0ee8e7 +md5: 93764a5ca80616e9c10106cdaec92f74 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- expat 2.8.1.* +license: MIT +license_family: MIT +size: 77294 +timestamp: 1779278686680 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda +sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 +md5: a360c33a5abe61c07959e449fa1453eb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 58592 +timestamp: 1769456073053 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda +sha256: 38f014a7129e644636e46064ecd6b1945e729c2140e21d75bb476af39e692db2 +md5: e289f3d17880e44b633ba911d57a321b +depends: +- libfreetype6 >=2.14.3 +license: GPL-2.0-only OR FTL +size: 8049 +timestamp: 1774298163029 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda +sha256: 16f020f96da79db1863fcdd8f2b8f4f7d52f177dd4c58601e38e9182e91adf1d +md5: fb16b4b69e3f1dcfe79d80db8fd0c55d +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libpng >=1.6.55,<1.7.0a0 +- libzlib >=1.3.2,<2.0a0 +constrains: +- freetype >=2.14.3 +license: GPL-2.0-only OR FTL +size: 384575 +timestamp: 1774298162622 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda +sha256: 8e0a3b5e41272e5678499b5dfc4cddb673f9e935de01eb0767ce857001229f46 +md5: 57736f29cc2b0ec0b6c2952d3f101b6a +depends: +- __glibc >=2.17,<3.0.a0 +- _openmp_mutex >=4.5 +constrains: +- libgcc-ng ==15.2.0=*_19 +- libgomp 15.2.0 he0feb66_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 1041084 +timestamp: 1778269013026 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda +sha256: 9dcf54adfaa5e861123c2da4f2f0451a685464ea7e5a41ad91cf67b31d658d98 +md5: 331ee9b72b9dff570d56b1302c5ab37d +depends: +- libgcc 15.2.0 he0feb66_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27694 +timestamp: 1778269016987 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda +sha256: 561a42758ef25b9ce308c4e2cf56daee4f06138385a17e29a492cd928e00be6f +md5: 42bf7eca1a951735fa06c0e3c0d5c8e6 +depends: +- libgfortran5 15.2.0 h68bc16d_19 +constrains: +- libgfortran-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27655 +timestamp: 1778269042954 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda +sha256: 057978bb69fea29ed715a9b98adf71015c31baecc4aeb2bfc20d4fd5d83579d4 +md5: 85072b0ad177c966294f129b7c04a2d5 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=15.2.0 +constrains: +- libgfortran 15.2.0 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 2483673 +timestamp: 1778269025089 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda +sha256: 5abe4ab9d93f6c9757d654f1969ae2267d4505315c1f2f8fe705fd60af084f1b +md5: faac990cb7aedc7f3a2224f2c9b0c26c +depends: +- __glibc >=2.17,<3.0.a0 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 603817 +timestamp: 1778268942614 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda +sha256: 10056646c28115b174de81a44e23e3a0a3b95b5347d2e6c45cc6d49d35294256 +md5: 6178c6f2fb254558238ef4e6c56fb782 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- jpeg <0.0.0a +license: IJG AND BSD-3-Clause AND Zlib +size: 633831 +timestamp: 1775962768273 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-7_h47877c9_openblas.conda +build_number: 7 +sha256: 96962084921f197c9ad13fb7f8b324f2351d50ff3d8d962148751ad532f54a01 +md5: 6569b4f273740e25dc0dc7e3232c2a6c +depends: +- libblas 3.11.0 7_h4a7cf45_openblas +constrains: +- liblapacke 3.11.0 7*_openblas +- libcblas 3.11.0 7*_openblas +- blas 2.307 openblas +license: BSD-3-Clause +license_family: BSD +size: 18694 +timestamp: 1778489869038 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda +sha256: ec30e52a3c1bf7d0425380a189d209a52baa03f22fb66dd3eb587acaa765bd6d +md5: b88d90cad08e6bc8ad540cb310a761fb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- xz 5.8.3.* +license: 0BSD +size: 113478 +timestamp: 1775825492909 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda +sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 +md5: 2c21e66f50753a083cbe6b80f38268fa +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: BSD-2-Clause +license_family: BSD +size: 92400 +timestamp: 1769482286018 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.33-pthreads_h94d23a6_0.conda +sha256: 3d9aa85648e5e18a6d66db98b8c4317cc426721ad7a220aa86330d1ccedc8903 +md5: 2d3278b721e40468295ca755c3b84070 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libgfortran +- libgfortran5 >=14.3.0 +constrains: +- openblas >=0.3.33,<0.3.34.0a0 +license: BSD-3-Clause +license_family: BSD +size: 5931919 +timestamp: 1776993658641 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda +sha256: 377cfe037f3eeb3b1bf3ad333f724a64d32f315ee1958581fc671891d63d3f89 +md5: eba48a68a1a2b9d3c0d9511548db85db +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libzlib >=1.3.2,<2.0a0 +license: zlib-acknowledgement +size: 317729 +timestamp: 1776315175087 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda +sha256: 54cdcd3214313b62c2a8ee277e6f42150d9b748264c1b70d958bf735e420ef8d +md5: 7dc38adcbf71e6b38748e919e16e0dce +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libzlib >=1.3.2,<2.0a0 +license: blessing +size: 954962 +timestamp: 1777986471789 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda +sha256: dff1058c76ec6b8759e41cefa2508162d00e4a5e6721aa68ec3fd10094e702dc +md5: 5794b3bdc38177caf969dabd3af08549 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc 15.2.0 he0feb66_19 +constrains: +- libstdcxx-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 5852044 +timestamp: 1778269036376 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda +sha256: e5f8c38625aa6d567809733ae04bb71c161a42e44a9fa8227abe61fa5c60ebe0 +md5: cd5a90476766d53e901500df9215e927 +depends: +- __glibc >=2.17,<3.0.a0 +- lerc >=4.0.0,<5.0a0 +- libdeflate >=1.25,<1.26.0a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.0,<4.0a0 +- liblzma >=5.8.1,<6.0a0 +- libstdcxx >=14 +- libwebp-base >=1.6.0,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- zstd >=1.5.7,<1.6.0a0 +license: HPND +size: 435273 +timestamp: 1762022005702 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda +sha256: 3f0edf1280e2f6684a986f821eaa3e123d2694a00b31b96ca0d4a4c12c129231 +md5: 7d0a66598195ef00b6efc55aefc7453b +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: BSD-3-Clause +license_family: BSD +size: 40163 +timestamp: 1779118517630 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda +sha256: 3aed21ab28eddffdaf7f804f49be7a7d701e8f0e46c856d801270b470820a37b +md5: aea31d2e5b1091feca96fcfe945c3cf9 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +constrains: +- libwebp 1.6.0 +license: BSD-3-Clause +license_family: BSD +size: 429011 +timestamp: 1752159441324 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda +sha256: 666c0c431b23c6cec6e492840b176dde533d48b7e6fb8883f5071223433776aa +md5: 92ed62436b625154323d40d5f2f11dd7 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +- pthread-stubs +- xorg-libxau >=1.0.11,<2.0a0 +- xorg-libxdmcp +license: MIT +license_family: MIT +size: 395888 +timestamp: 1727278577118 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda +sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 +md5: d87ff7921124eccd67248aa483c23fec +depends: +- __glibc >=2.17,<3.0.a0 +constrains: +- zlib 1.3.2 *_2 +license: Zlib +license_family: Other +size: 63629 +timestamp: 1774072609062 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda +sha256: 20e0892592a3e7c683e3d66df704a9425d731486a97c34fc56af4da1106b2b6b +md5: ba0a9221ce1063f31692c07370d062f3 +depends: +- importlib-metadata >=4.4 +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 85893 +timestamp: 1770694658918 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.2.0-pyhd8ed1ab_0.conda +sha256: 0c4c35376fe920714390d46e4b8d31c876d65f18e1655899e0763ec25f2a902f +md5: 6d03368f2b2b0a5fb6839df53b2eb5e0 +depends: +- mdurl >=0.1,<1 +- python >=3.10 +license: MIT +license_family: MIT +size: 69017 +timestamp: 1778169663339 +- conda: https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda +sha256: c279be85b59a62d5c52f5dd9a4cd43ebd08933809a8416c22c3131595607d4cf +md5: 9a17c4307d23318476d7fbf0fedc0cde +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +constrains: +- jinja2 >=3.0.0 +license: BSD-3-Clause +license_family: BSD +size: 27424 +timestamp: 1772445227915 +- conda: https://conda.anaconda.org/conda-forge/linux-64/mathjax-2.7.7-ha770c72_3.tar.bz2 +sha256: 02fef69bde69db264a12f21386612262f545b6e3e68d8f1ccec19f3eaae58edf +md5: 86e69bd82c2a2c6fd29f5ab7e02b3691 +license: Apache-2.0 +license_family: Apache +size: 22281629 +timestamp: 1662784498331 +- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda +sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 +md5: 592132998493b3ff25fd7479396e8351 +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 14465 +timestamp: 1733255681319 +- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.35-pyhdfd78af_1.conda +sha256: e86033aa55a9e915e2d0957e770bdb81e3feb26a227d1adb17f9d6c528da6a71 +md5: cdb20309681ba3ce8f52c110e214d4f3 +depends: +- click +- coloredlogs +- humanize +- importlib-metadata +- jinja2 >=3.0.0 +- jsonschema +- markdown +- natsort +- numpy +- packaging +- pillow >=10.2.0 +- plotly >=5.18 +- polars >=1.34.0 +- polars-runtime-compat >=1.34.0 +- pyaml-env +- pydantic >=2.7.1 +- python >=3.9,!=3.14.1 +- python-dotenv +- python-kaleido 0.2.1 +- pyyaml >=4 +- requests +- rich >=10 +- rich-click +- spectra >=0.0.10 +- tiktoken +- tqdm +- typeguard >=4 +license: GPL-3.0-or-later +license_family: GPL3 +size: 4282188 +timestamp: 1779465338806 +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.2-pyhcf101f3_0.conda +sha256: 70f43d62450927d51673eecd8823e14f5b3cfebdb43cda1d502eba97162bab42 +md5: 6687827c332121727ce383919e1ec8c2 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 284323 +timestamp: 1778929680962 +- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda +sha256: aeb1548eb72e4f198e72f19d242fb695b35add2ac7b2c00e0d83687052867680 +md5: e941e85e273121222580723010bd4fa2 +depends: +- python >=3.9 +- python +license: MIT +license_family: MIT +size: 39262 +timestamp: 1770905275632 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda +sha256: fc89f74bbe362fb29fa3c037697a89bec140b346a2469a90f7936d1d7ea4d8a3 +md5: fc21868a1a5aacc937e7a18747acb8a5 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: X11 AND BSD-3-Clause +size: 918956 +timestamp: 1777422145199 +- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda +sha256: f6a82172afc50e54741f6f84527ef10424326611503c64e359e25a19a8e4c1c6 +md5: a2c1eeadae7a309daed9d62c96012a2b +depends: +- python >=3.11 +- python +constrains: +- numpy >=1.25 +- scipy >=1.11.2 +- matplotlib-base >=3.8 +- pandas >=2.0 +license: BSD-3-Clause +license_family: BSD +size: 1587439 +timestamp: 1765215107045 +- conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda +sha256: e3664264bd936c357523b55c71ed5a30263c6ba278d726a75b1eb112e6fb0b64 +md5: e235d5566c9cc8970eb2798dd4ecf62f +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: MPL-2.0 +license_family: MOZILLA +size: 228588 +timestamp: 1762348634537 +- conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda +sha256: 44dd98ffeac859d84a6dcba79a2096193a42fc10b29b28a5115687a680dd6aea +md5: 567fbeed956c200c1db5782a424e58ee +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libsqlite >=3.51.0,<4.0a0 +- libstdcxx >=14 +- libzlib >=1.3.1,<2.0a0 +- nspr >=4.38,<5.0a0 +license: MPL-2.0 +license_family: MOZILLA +size: 2057773 +timestamp: 1763485556350 +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.6-py314h2b28147_0.conda +sha256: bc61ae892973751a6b0e6ecea57ed6d7053224bddcb007165d6ceb1d7344ad47 +md5: f49b5f950379e0b97c35ca97682f7c6a +depends: +- python +- libstdcxx >=14 +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- liblapack >=3.9.0,<4.0a0 +- python_abi 3.14.* *_cp314 +- libblas >=3.9.0,<4.0a0 +- libcblas >=3.9.0,<4.0a0 +constrains: +- numpy-base <0a0 +license: BSD-3-Clause +license_family: BSD +size: 8928909 +timestamp: 1779169198391 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda +sha256: 3900f9f2dbbf4129cf3ad6acf4e4b6f7101390b53843591c53b00f034343bc4d +md5: 11b3379b191f63139e29c0d19dee24cd +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libpng >=1.6.50,<1.7.0a0 +- libstdcxx >=14 +- libtiff >=4.7.1,<4.8.0a0 +- libzlib >=1.3.1,<2.0a0 +license: BSD-2-Clause +license_family: BSD +size: 355400 +timestamp: 1758489294972 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda +sha256: c0ef482280e38c71a08ad6d71448194b719630345b0c9c60744a2010e8a8e0cb +md5: da1b85b6a87e141f5140bb9924cecab0 +depends: +- __glibc >=2.17,<3.0.a0 +- ca-certificates +- libgcc >=14 +license: Apache-2.0 +license_family: Apache +size: 3167099 +timestamp: 1775587756857 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda +sha256: 3906abfb6511a3bb309e39b9b1b7bc38f50a723971de2395489fd1f379255890 +md5: 4c06a92e74452cfa53623a81592e8934 +depends: +- python >=3.8 +- python +license: Apache-2.0 +license_family: APACHE +size: 91574 +timestamp: 1777103621679 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda +sha256: 123d8a7c16c88658b4f29e9f115a047598c941708dade74fbaff373a32dbec5e +md5: 76c4757c0ec9d11f969e8eb44899307b +depends: +- python +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- libtiff >=4.7.1,<4.8.0a0 +- openjpeg >=2.5.4,<3.0a0 +- libxcb >=1.17.0,<2.0a0 +- libwebp-base >=1.6.0,<2.0a0 +- zlib-ng >=2.3.3,<2.4.0a0 +- libjpeg-turbo >=3.1.2,<4.0a0 +- python_abi 3.14.* *_cp314 +- libfreetype >=2.14.3 +- libfreetype6 >=2.14.3 +- lcms2 >=2.18,<3.0a0 +- tk >=8.6.13,<8.7.0a0 +license: HPND +size: 1082797 +timestamp: 1775060059882 +- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda +sha256: c418d325359fc7a0074cea7f081ef1bce26e114d2da8a0154c5d27ecc87a08e7 +md5: 3e9427ee186846052e81fadde8ebe96a +depends: +- narwhals >=1.15.1 +- packaging +- python >=3.10 +constrains: +- ipywidgets >=7.6 +license: MIT +license_family: MIT +size: 5251872 +timestamp: 1772628857717 +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.41.0-pyh58ad624_0.conda +sha256: 70fc56877c4a095ee658d61924d8019768fbae4a48437058d181fc94b0a7c4d8 +md5: 25a883fed9f1f3f21ff317a3e7c92ac4 +depends: +- polars-runtime-32 ==1.41.0 +- python >=3.10 +- python +constrains: +- numpy >=1.16.0 +- pyarrow >=7.0.0 +- fastexcel >=0.9 +- openpyxl >=3.0.0 +- xlsx2csv >=0.8.0 +- connectorx >=0.3.2 +- deltalake >=1.0.0 +- pyiceberg >=0.7.1 +- altair >=5.4.0 +- great_tables >=0.8.0 +- polars-runtime-32 ==1.41.0 +- polars-runtime-64 ==1.41.0 +- polars-runtime-compat ==1.41.0 +license: MIT +size: 539656 +timestamp: 1779630790562 +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.41.0-py310h49dadd8_0.conda +noarch: python +sha256: e51ee3fe5259f2e115b2f78f8fbe3554e419c7c82b0c110878e12a5ff95ce3ab +md5: 7682765a1588e5ac887c99736d297c93 +depends: +- python +- __glibc >=2.17,<3.0.a0 +- libstdcxx >=14 +- libgcc >=14 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +size: 42578921 +timestamp: 1779630790562 +- conda: https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-compat-1.41.0-py310hcbd6021_0.conda +noarch: python +sha256: 29c3831c92394af11d9f7d04882dda9479ffbb76a3d36ba155d52159d67805fa +md5: cb0b620c9914a07a9022cb8b183ea9ee +depends: +- python +- libstdcxx >=14 +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +size: 41864944 +timestamp: 1779630722548 +- conda: https://conda.anaconda.org/conda-forge/linux-64/procps-ng-4.0.6-h18c060e_0.conda +sha256: 4ce2e1ee31a6217998f78c31ce7dc0a3e0557d9238b51d49dd20c52d467a126d +md5: f2c23a77b25efcad57d377b34bd84941 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-2.0-or-later AND LGPL-2.0-or-later +license_family: GPL +size: 593603 +timestamp: 1769710381284 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda +sha256: 9c88f8c64590e9567c6c80823f0328e58d3b1efb0e1c539c0315ceca764e0973 +md5: b3c17d95b5a10c6e64a21fa17573e70e +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=13 +license: MIT +license_family: MIT +size: 8252 +timestamp: 1726802366959 +- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda +sha256: 58994e0d2ea8584cb399546e6f6896d771995e6121d1a7b6a2c9948388358932 +md5: e17be1016bcc3516827b836cd3e4d9dc +depends: +- python >=3.9 +- pyyaml >=5.0,<=7.0 +license: MIT +license_family: MIT +size: 14645 +timestamp: 1736766960536 +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda +sha256: 69700e31165df070e9716315e042196aa92525dae5deb5107785847ab9f4189f +md5: 729843edafc0899b3348bd3f19525b9d +depends: +- typing-inspection >=0.4.2 +- typing_extensions >=4.14.1 +- python >=3.10 +- annotated-types >=0.6.0 +- pydantic-core ==2.46.4 +- python +license: MIT +license_family: MIT +size: 346511 +timestamp: 1778103405862 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.46.4-py314h2e6c369_0.conda +sha256: 802e216c39f1359aed60823b6e11d8ccd812b0ae1c81ae5ac1c81f99446409ab +md5: 0c96993dbeadf3a277cf757b9f1c9412 +depends: +- python +- typing-extensions >=4.6.0,!=4.7.0 +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- python_abi 3.14.* *_cp314 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 1895020 +timestamp: 1778084229247 +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda +sha256: cf70b2f5ad9ae472b71235e5c8a736c9316df3705746de419b59d442e8348e86 +md5: 16c18772b340887160c79a6acc022db0 +depends: +- python >=3.10 +license: BSD-2-Clause +license_family: BSD +size: 893031 +timestamp: 1774796815820 +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda +sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 +md5: 461219d1a5bd61342293efa2c0c90eac +depends: +- __unix +- python >=3.9 +license: BSD-3-Clause +license_family: BSD +size: 21085 +timestamp: 1733217331982 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.5-habeac84_100_cp314.conda +build_number: 100 +sha256: 55eed9bf2a3f6e90311276f0834737fe7c2d9ec3e5e2e557507858df4c7521e6 +md5: da92e59ff92f2d5ede4f612af20f583f +depends: +- __glibc >=2.17,<3.0.a0 +- bzip2 >=1.0.8,<2.0a0 +- ld_impl_linux-64 >=2.36.1 +- libexpat >=2.8.0,<3.0a0 +- libffi >=3.5.2,<3.6.0a0 +- libgcc >=14 +- liblzma >=5.8.3,<6.0a0 +- libmpdec >=4.0.0,<5.0a0 +- libsqlite >=3.53.1,<4.0a0 +- libuuid >=2.42.1,<3.0a0 +- libzlib >=1.3.2,<2.0a0 +- ncurses >=6.6,<7.0a0 +- openssl >=3.5.6,<4.0a0 +- python_abi 3.14.* *_cp314 +- readline >=8.3,<9.0a0 +- tk >=8.6.13,<8.7.0a0 +- tzdata +- zstd >=1.5.7,<1.6.0a0 +license: Python-2.0 +size: 36745188 +timestamp: 1779236923603 +python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda +sha256: 74e417a768f59f02a242c25e7db0aa796627b5bc8c818863b57786072aeb85e5 +md5: 130584ad9f3a513cdd71b1fdc1244e9c +depends: +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 27848 +timestamp: 1772388605021 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.5-h4df99d1_100.conda +sha256: 41dd7da285d71d519257fa7dacb1cae060d5ebfaa5f92cba5994899d2978e943 +md5: 41954747ba952ec4b01e16c2c9e8d8ff +depends: +- cpython 3.14.5.* +- python_abi * *_cp314 +license: Python-2.0 +size: 50212 +timestamp: 1779236703009 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 +sha256: e17bf63a30aec33432f1ead86e15e9febde9fc40a7f869c0e766be8d2db44170 +md5: 310259a5b03ff02289d7705f39e2b1d2 +depends: +- kaleido-core 0.2.1.* +- python >=3.5 +license: MIT +license_family: MIT +size: 18320 +timestamp: 1615204747600 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda +build_number: 8 +sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 +md5: 0539938c55b6b1a59b560e843ad864a4 +constrains: +- python 3.14.* *_cp314 +license: BSD-3-Clause +license_family: BSD +size: 6989 +timestamp: 1752805904792 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda +sha256: b318fb070c7a1f89980ef124b80a0b5ccf3928143708a85e0053cde0169c699d +md5: 2035f68f96be30dc60a5dfd7452c7941 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +- yaml >=0.2.5,<0.3.0a0 +license: MIT +license_family: MIT +size: 202391 +timestamp: 1770223462836 +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda +sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 +md5: d7d95fc8287ea7bf33e0e7116d2b95ec +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-3.0-only +license_family: GPL +size: 345073 +timestamp: 1765813471974 +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda +sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 +md5: 870293df500ca7e18bedefa5838a22ab +depends: +- attrs >=22.2.0 +- python >=3.10 +- rpds-py >=0.7.0 +- typing_extensions >=4.4.0 +- python +license: MIT +license_family: MIT +size: 51788 +timestamp: 1760379115194 +- conda: https://conda.anaconda.org/conda-forge/linux-64/regex-2026.5.9-py314h5bd0f2a_0.conda +sha256: c7a4aca4977c15c82d053b06cbc676460974c1b25757cfeea8a9a2497ac911f8 +md5: 9dd235b6ac69a0198080dac39f9891aa +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +license: Apache-2.0 AND CNRI-Python +license_family: PSF +size: 413611 +timestamp: 1778374155646 +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda +sha256: 1715246b19c9f85ee022933b4845f2fc14ac9184981b7b7d9b728bec8e9588da +md5: 4a85203c1d80c1059086ae860836ffb9 +depends: +- python >=3.10 +- certifi >=2023.5.7 +- charset-normalizer >=2,<4 +- idna >=2.5,<4 +- urllib3 >=1.26,<3 +- python +constrains: +- chardet >=3.0.2,<8 +license: Apache-2.0 +license_family: APACHE +size: 68709 +timestamp: 1778851103479 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda +sha256: 3d6ba2c0fcdac3196ba2f0615b4104e532525ffa1335b50a2878be5ff488814a +md5: 0242025a3c804966bf71aa04eee82f66 +depends: +- markdown-it-py >=2.2.0 +- pygments >=2.13.0,<3.0.0 +- python >=3.10 +- typing_extensions >=4.0.0,<5.0.0 +- python +license: MIT +license_family: MIT +size: 208577 +timestamp: 1775991661559 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda +sha256: aa3fcb167321bae51998de2e94d199109c9024f25a5a063cb1c28d8f1af33436 +md5: 0c20a8ebcddb24a45da89d5e917e6cb9 +depends: +- python >=3.10 +- rich >=12 +- click >=8 +- typing-extensions >=4 +- __unix +- python +license: MIT +license_family: MIT +size: 64356 +timestamp: 1769850479089 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda +sha256: e53b0cbf3b324eaa03ca1fe1a688fdf4ab42cea9c25270b0a7307d8aaaa4f446 +md5: c1c368b5437b0d1a68f372ccf01cb133 +depends: +- python +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +- python_abi 3.14.* *_cp314 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 376121 +timestamp: 1764543122774 +- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda +sha256: 7c65782d2511738e62c70462e89d65da4fa54d5a7e47c46667bcd27a59f81876 +md5: 472239e4eb7b5a84bb96b3ed7e3a596a +depends: +- colormath >=3.0.0 +- python >=3.9 +license: MIT +license_family: MIT +size: 22284 +timestamp: 1735770589188 +- conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.53.1-hbc0de68_0.conda +sha256: d167fa92781bcdcd3b9aaa6bb1cd50c5b108f6190c170098a118b5cf5df2f881 +md5: 8e0b8654ead18e50af552e54b5a08a61 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libsqlite 3.53.1 h0c1763c_0 +- libzlib >=1.3.2,<2.0a0 +- ncurses >=6.6,<7.0a0 +- readline >=8.3,<9.0a0 +license: blessing +size: 205399 +timestamp: 1777986477546 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tiktoken-0.12.0-py314h67fec18_3.conda +sha256: 7e395d67fd249d901beb1ae269057763c0d8c3ee5f7a348694bdb16d158a37d9 +md5: d705f9d8a1185a2b01cced191177a028 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +- regex >=2022.1.18 +- requests >=2.26.0 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 939648 +timestamp: 1764028306357 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda +sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac +md5: cffd3bdd58090148f4cfcd831f4b26ab +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +constrains: +- xorg-libx11 >=1.8.12,<2.0a0 +license: TCL +license_family: BSD +size: 3301196 +timestamp: 1769460227866 +- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda +sha256: 9ef8e47cf00e4d6dcc114eb32a1504cc18206300572ef14d76634ba29dfe1eb6 +md5: e5ce43272193b38c2e9037446c1d9206 +depends: +- python >=3.10 +- __unix +- python +license: MPL-2.0 and MIT +size: 94132 +timestamp: 1770153424136 +- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.2-pyhcf101f3_0.conda +sha256: 59d7851d32fddb5b510272e6557aa982edeb927d349648dac27f5bf01d18bb26 +md5: 4460f039b7dedf15f7df086446ca75ae +depends: +- typing_extensions >=4.14.0 +- python >=3.10 +- importlib-metadata >=3.6 +- python +constrains: +- pytest >=7 +license: MIT +license_family: MIT +size: 38297 +timestamp: 1778779291237 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda +sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c +md5: edd329d7d3a4ab45dcf905899a7a6115 +depends: +- typing_extensions ==4.15.0 pyhcf101f3_0 +license: PSF-2.0 +license_family: PSF +size: 91383 +timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda +sha256: 8b90d2f19f9458b8c58a55e1fcdc1d90c1603a847a47654d8a454549413ba60a +md5: 53f5409c5cfd6c5a66417d68e3f0a864 +depends: +- python >=3.10 +- typing_extensions >=4.12.0 +- python +license: MIT +license_family: MIT +size: 20935 +timestamp: 1777105465795 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda +sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 +md5: 0caa1af407ecff61170c9437a808404d +depends: +- python >=3.10 +- python +license: PSF-2.0 +license_family: PSF +size: 51692 +timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda +sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c +md5: ad659d0a2b3e47e38d829aa8cad2d610 +license: LicenseRef-Public-Domain +size: 119135 +timestamp: 1767016325805 +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda +sha256: feff959a816f7988a0893201aa9727bbb7ee1e9cec2c4f0428269b489eb93fb4 +md5: cbb88288f74dbe6ada1c6c7d0a97223e +depends: +- backports.zstd >=1.0.0 +- brotli-python >=1.2.0 +- h2 >=4,<5 +- pysocks >=1.5.6,<2.0,!=1.5.7 +- python >=3.10 +license: MIT +license_family: MIT +size: 103560 +timestamp: 1778188657149 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda +sha256: 6bc6ab7a90a5d8ac94c7e300cc10beb0500eeba4b99822768ca2f2ef356f731b +md5: b2895afaf55bf96a8c8282a2e47a5de0 +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 15321 +timestamp: 1762976464266 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda +sha256: 25d255fb2eef929d21ff660a0c687d38a6d2ccfbcbf0cc6aa738b12af6e9d142 +md5: 1dafce8548e38671bea82e3f5c6ce22f +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 20591 +timestamp: 1762976546182 +- conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda +sha256: 6d9ea2f731e284e9316d95fa61869fe7bbba33df7929f82693c121022810f4ad +md5: a77f85f77be52ff59391544bfe73390a +depends: +- libgcc >=14 +- __glibc >=2.17,<3.0.a0 +license: MIT +license_family: MIT +size: 85189 +timestamp: 1753484064210 +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda +sha256: 210bd31c22bb88f5e2a167df24c95bb5f152b2ada7502f9b8c49d1f5366db423 +md5: ba3dcdc8584155c97c648ae9c044b7a3 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 24190 +timestamp: 1779159948016 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda +sha256: ea4e50c465d70236408cb0bfe0115609fd14db1adcd8bd30d8918e0291f8a75f +md5: 2aadb0d17215603a82a2a6b0afd9a4cb +depends: +- __glibc >=2.17,<3.0.a0 +- libgcc >=14 +- libstdcxx >=14 +license: Zlib +license_family: Other +size: 122618 +timestamp: 1770167931827 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda +sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 +md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 +depends: +- __glibc >=2.17,<3.0.a0 +- libzlib >=1.3.1,<2.0a0 +license: BSD-3-Clause +license_family: BSD +size: 601375 +timestamp: 1764777111296 diff --git a/nf_core/pipeline-template/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-5c84a5000a226ab5_1.txt b/nf_core/pipeline-template/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-5c84a5000a226ab5_1.txt new file mode 100644 index 0000000000..3d5b93db98 --- /dev/null +++ b/nf_core/pipeline-template/modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-5c84a5000a226ab5_1.txt @@ -0,0 +1,1476 @@ + +version: 6 +environments: +default: +channels: +- url: https://conda.anaconda.org/conda-forge/ +- url: https://conda.anaconda.org/bioconda/ +- url: https://conda.anaconda.org/bioconda/ +options: +pypi-prerelease-mode: if-necessary-or-explicit +packages: +linux-aarch64: +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.5.0-py314h680f03e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.0-pyhc90fa1f_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.5-py314hd8ed1ab_100.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.8.1-hfae3067_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.18.0-hba86a56_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.15-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/kaleido-core-0.2.1-he5a581e_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.19.1-h9d5b58d_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-7_haddc8a3_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-7_hd72aa62_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.8.1-hfae3067_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-7_h88aeb00_openblas.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.33-pthreads_h9d3fd7e_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.1-h022381a_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_19.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42.1-h1022ec0_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.2.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.3-py314hb76de3f_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mathjax-2.7.7-h8af1aa0_3.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda +- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.35-pyhdfd78af_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.6-hf8d1292_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nspr-4.38-h3ad9384_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nss-3.118-h544fa81_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.6-py314he1698a1_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.2-h546c87b_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.2.0-py314hac3e5ec_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.41.0-pyh58ad624_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.41.0-py310h32c7c23_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.41.0-py310hc0e61be_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.46.4-py314h451b6cc_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.5-hfd9ac0a_100_cp314.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.5-h4df99d1_100.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/regex-2026.5.9-py314h51f160d_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rpds-py-0.30.0-py314h02b7a91_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sqlite-3.53.1-he8854b5_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tiktoken-0.12.0-py314h6a36e60_3.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.2-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda +build_number: 20 +sha256: a2527b1d81792a0ccd2c05850960df119c2b6d8f5fdec97f2db7d25dc23b1068 +md5: 468fd3bb9e1f671d36c2cbc677e56f1d +depends: +- libgomp >=7.5.0 +constrains: +- openmp_impl <0.0a0 +license: BSD-3-Clause +license_family: BSD +size: 28926 +timestamp: 1770939656741 +- conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda +sha256: a3967b937b9abf0f2a99f3173fa4630293979bd1644709d89580e7c62a544661 +md5: aaa2a381ccc56eac91d63b6c1240312f +depends: +- cpython +- python-gil +license: MIT +license_family: MIT +size: 8191 +timestamp: 1744137672556 +- conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_1.conda +sha256: e0ea1ba78fbb64f17062601edda82097fcf815012cf52bb704150a2668110d48 +md5: 2934f256a8acfe48f6ebb4fce6cde29c +depends: +- python >=3.9 +- typing-extensions >=4.0.0 +license: MIT +license_family: MIT +size: 18074 +timestamp: 1733247158254 +- conda: https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda +sha256: 1b6124230bb4e571b1b9401537ecff575b7b109cc3a21ee019f65e083b8399ab +md5: c6b0543676ecb1fb2d7643941fe375f2 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 64927 +timestamp: 1773935801332 +- conda: https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.5.0-py314h680f03e_0.conda +noarch: generic +sha256: a1c97297e867776760489537bc5ae36fa83a154be30e3b79385a39ca4cb058fe +md5: 1133126d840e75287d83947be3fc3e71 +depends: +- python >=3.14 +license: BSD-3-Clause AND MIT AND EPL-2.0 +size: 7533 +timestamp: 1778594057496 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-python-1.2.0-py314h352cb57_1.conda +sha256: 5a5b0cdcd7ed89c6a8fb830924967f6314a2b71944bc1ebc2c105781ba97aa75 +md5: a1b5c571a0923a205d663d8678df4792 +depends: +- libgcc >=14 +- libstdcxx >=14 +- python >=3.14,<3.15.0a0 +- python >=3.14,<3.15.0a0 *_cp314 +- python_abi 3.14.* *_cp314 +constrains: +- libbrotlicommon 1.2.0 he30d5cf_1 +license: MIT +license_family: MIT +size: 373193 +timestamp: 1764017486851 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda +sha256: b3495077889dde6bb370938e7db82be545c73e8589696ad0843a32221520ad4c +md5: 840d8fc0d7b3209be93080bc20e07f2d +depends: +- libgcc >=14 +license: bzip2-1.0.6 +license_family: BSD +size: 192412 +timestamp: 1771350241232 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda +sha256: 9812a303a1395e1dafbd92e5bc8a1ff6013bcbba0a09c7f03a8d23e43560aa9b +md5: 489b8e97e666c93f68fdb35c3c9b957f +depends: +- __unix +license: ISC +size: 129868 +timestamp: 1779289852439 +- conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2026.5.20-pyhd8ed1ab_0.conda +sha256: 645655a3510e38e625da136595f3f16f2130c3263630cc3bc8f60f619ddbe490 +md5: 9fefff2f745ea1cc2ef15211a20c054a +depends: +- python >=3.10 +license: ISC +size: 134201 +timestamp: 1779285131141 +- conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda +sha256: 3f9483d62ce24ecd063f8a5a714448445dc8d9e201147c46699fc0033e824457 +md5: a9167b9571f3baa9d448faa2139d1089 +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 58872 +timestamp: 1775127203018 +- conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.0-pyhc90fa1f_0.conda +sha256: 99ab8ef815c4520cce3a7482c2513f377c14348206857661d84c76a55e030f97 +md5: 003767c47f1f0a474c4de268b57839c3 +depends: +- __unix +- python +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 104631 +timestamp: 1779108494556 +- conda: https://conda.anaconda.org/conda-forge/noarch/coloredlogs-15.0.1-pyhd8ed1ab_4.conda +sha256: 8021c76eeadbdd5784b881b165242db9449783e12ce26d6234060026fd6a8680 +md5: b866ff7007b934d564961066c8195983 +depends: +- humanfriendly >=9.1 +- python >=3.9 +license: MIT +license_family: MIT +size: 43758 +timestamp: 1733928076798 +- conda: https://conda.anaconda.org/conda-forge/noarch/colormath-3.0.0-pyhd8ed1ab_4.conda +sha256: 59c9e29800b483b390467f90e82b0da3a4fbf0612efe1c90813fca232780e160 +md5: 071cf7b0ce333c81718b054066c15102 +depends: +- networkx >=2.0 +- numpy +- python >=3.9 +license: BSD-3-Clause +license_family: BSD +size: 39326 +timestamp: 1735759976140 +- conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.5-py314hd8ed1ab_100.conda +noarch: generic +sha256: 777882d2685f368417f31bbe1b28f73687fc6c8f6a5768bda20ffeefa6b07f5b +md5: a749029ce5d0632a913db19d17f944ab +depends: +- python >=3.14,<3.15.0a0 +- python_abi * *_cp314 +license: Python-2.0 +size: 50212 +timestamp: 1779236682725 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.8.1-hfae3067_0.conda +sha256: a9cd5eb1700e11cc39acc36630a2d72a4e317943bd7c5695cd8804419f04ff42 +md5: 89f0247b3cea528d8ad1a6664a313153 +depends: +- libexpat 2.8.1 hfae3067_0 +- libgcc >=14 +license: MIT +license_family: MIT +size: 140114 +timestamp: 1779278679081 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 +sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b +md5: 0c96522c6bdaed4b1566d11387caaf45 +license: BSD-3-Clause +license_family: BSD +size: 397370 +timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 +sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c +md5: 34893075a5c9e55cdafac56607368fc6 +license: OFL-1.1 +license_family: Other +size: 96530 +timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 +sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 +md5: 4d59c254e01d9cde7957100457e2d5fb +license: OFL-1.1 +license_family: Other +size: 700814 +timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda +sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 +md5: 49023d73832ef61042f6a237cb2687e7 +license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 +license_family: Other +size: 1620504 +timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.18.0-hba86a56_0.conda +sha256: 1805f4ab3d9e1734a5a17abccc2cb0fdade51d4d5f29bdc410600ea0115ec050 +md5: b660d59a9d0fb3297327418624acaec3 +depends: +- libexpat >=2.8.1,<3.0a0 +- libfreetype >=2.14.3 +- libfreetype6 >=2.14.3 +- libgcc >=14 +- libuuid >=2.42.1,<3.0a0 +- libzlib >=1.3.2,<2.0a0 +license: MIT +license_family: MIT +size: 293348 +timestamp: 1779421661332 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda +sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 +md5: a7970cd949a077b7cb9696379d338681 +depends: +- font-ttf-ubuntu +- font-ttf-inconsolata +- font-ttf-dejavu-sans-mono +- font-ttf-source-code-pro +license: BSD-3-Clause +license_family: BSD +size: 4059 +timestamp: 1762351264405 +- conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda +sha256: 84c64443368f84b600bfecc529a1194a3b14c3656ee2e832d15a20e0329b6da3 +md5: 164fc43f0b53b6e3a7bc7dce5e4f1dc9 +depends: +- python >=3.10 +- hyperframe >=6.1,<7 +- hpack >=4.1,<5 +- python +license: MIT +license_family: MIT +size: 95967 +timestamp: 1756364871835 +- conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda +sha256: 6ad78a180576c706aabeb5b4c8ceb97c0cb25f1e112d76495bff23e3779948ba +md5: 0a802cb9888dd14eeefc611f05c40b6e +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 30731 +timestamp: 1737618390337 +- conda: https://conda.anaconda.org/conda-forge/noarch/humanfriendly-10.0-pyh707e725_8.conda +sha256: fa2071da7fab758c669e78227e6094f6b3608228740808a6de5d6bce83d9e52d +md5: 7fe569c10905402ed47024fc481bb371 +depends: +- __unix +- python >=3.9 +license: MIT +license_family: MIT +size: 73563 +timestamp: 1733928021866 +- conda: https://conda.anaconda.org/conda-forge/noarch/humanize-4.15.0-pyhd8ed1ab_0.conda +sha256: 6c4343b376d0b12a4c75ab992640970d36c933cad1fd924f6a1181fa91710e80 +md5: daddf757c3ecd6067b9af1df1f25d89e +depends: +- python >=3.10 +license: MIT +license_family: MIT +size: 67994 +timestamp: 1766267728652 +- conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda +sha256: 77af6f5fe8b62ca07d09ac60127a30d9069fdc3c68d6b256754d0ffb1f7779f8 +md5: 8e6923fc12f1fe8f8c4e5c9f343256ac +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 17397 +timestamp: 1737618427549 +- conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.15-pyhcf101f3_0.conda +sha256: 3d25f9f6f7ab3e1ce6429fc8c8aae0335cf446692e715068488536d220cc43de +md5: 1b9083b7f00609605d1483dbc6071a81 +depends: +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 62642 +timestamp: 1779294335905 +- conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda +sha256: 43e2a5497cad1598ff88a3e69f69bc88b7b8f141fa63c60eab5db296317318b8 +md5: ffc17e785d64e12fc311af9184221839 +depends: +- python >=3.10 +- zipp >=3.20 +- python +license: Apache-2.0 +size: 34766 +timestamp: 1779714582554 +- conda: https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda +sha256: fc9ca7348a4f25fed2079f2153ecdcf5f9cf2a0bc36c4172420ca09e1849df7b +md5: 04558c96691bed63104678757beb4f8d +depends: +- markupsafe >=2.0 +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 120685 +timestamp: 1764517220861 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda +sha256: db973a37d75db8e19b5f44bbbdaead0c68dde745407f281e2a7fe4db74ec51d7 +md5: ada41c863af263cc4c5fcbaff7c3e4dc +depends: +- attrs >=22.2.0 +- jsonschema-specifications >=2023.3.6 +- python >=3.10 +- referencing >=0.28.4 +- rpds-py >=0.25.0 +- python +license: MIT +license_family: MIT +size: 82356 +timestamp: 1767839954256 +- conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda +sha256: 0a4f3b132f0faca10c89fdf3b60e15abb62ded6fa80aebfc007d05965192aa04 +md5: 439cd0f567d697b20a8f45cb70a1005a +depends: +- python >=3.10 +- referencing >=0.31.0 +- python +license: MIT +license_family: MIT +size: 19236 +timestamp: 1757335715225 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/kaleido-core-0.2.1-he5a581e_0.tar.bz2 +sha256: d3c7f4797566e6f983d16c2a87063a18e4b2d819a66230190a21584d70042755 +md5: 4f0d284f5d11e04277b552eb1c172c7f +depends: +- __glibc >=2.17,<3.0.a0 +- expat >=2.2.10,<3.0.0a0 +- fontconfig +- fonts-conda-forge +- libgcc-ng >=9.3.0 +- mathjax 2.7.* +- nspr >=4.29,<5.0a0 +- nss >=3.62,<4.0a0 +- sqlite >=3.34.0,<4.0a0 +license: MIT +license_family: MIT +size: 65750397 +timestamp: 1615199465742 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.19.1-h9d5b58d_0.conda +sha256: 1e5f68e4b36a0e1a278c6dc026bc3d7775518a15832cbc9d7fc1c0e4c47784b1 +md5: b1f8bee3c53a6d2c103fb4a1ae44f5c4 +depends: +- libgcc >=14 +- libjpeg-turbo >=3.1.4.1,<4.0a0 +- libtiff >=4.7.1,<4.8.0a0 +license: MIT +license_family: MIT +size: 296899 +timestamp: 1778079402392 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda +sha256: 7abd913d81a9bf00abb699e8987966baa2065f5132e37e815f92d90fc6bba530 +md5: a21644fc4a83da26452a718dc9468d5f +depends: +- zstd >=1.5.7,<1.6.0a0 +constrains: +- binutils_impl_linux-aarch64 2.45.1 +license: GPL-3.0-only +license_family: GPL +size: 875596 +timestamp: 1774197520746 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda +sha256: 8957fd460c1c132c8031f65fd5f56ec3807fd71b7cab2c5e2b0937b13404ab36 +md5: d13423b06447113a90b5b1366d4da171 +depends: +- libgcc >=14 +- libstdcxx >=14 +license: Apache-2.0 +license_family: Apache +size: 240444 +timestamp: 1773114901155 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-7_haddc8a3_openblas.conda +build_number: 7 +sha256: f27ba323c2f1e1731b5e880fe520f178f55047f25be94f77e649605b2343c066 +md5: e8d07b777f6ff1fab69665336561910b +depends: +- libopenblas >=0.3.33,<0.3.34.0a0 +- libopenblas >=0.3.33,<1.0a0 +constrains: +- liblapack 3.11.0 7*_openblas +- libcblas 3.11.0 7*_openblas +- mkl <2027 +- blas 2.307 openblas +- liblapacke 3.11.0 7*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18696 +timestamp: 1778489796402 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-7_hd72aa62_openblas.conda +build_number: 7 +sha256: c8f0192362966df0828419f042d6f94c079e5df00ad6bd05b5e84c12b42f8cc7 +md5: 90ac57b82c055faa9be25031864b7d8f +depends: +- libblas 3.11.0 7_haddc8a3_openblas +constrains: +- liblapack 3.11.0 7*_openblas +- blas 2.307 openblas +- liblapacke 3.11.0 7*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18664 +timestamp: 1778489802790 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda +sha256: 48814b73bd462da6eed2e697e30c060ae16af21e9fbed30d64feaf0aad9da392 +md5: a9138815598fe6b91a1d6782ca657b0c +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 71117 +timestamp: 1761979776756 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.8.1-hfae3067_0.conda +sha256: 1fc392b997c6ee2bd3226a7cd870d0edbcbb367e25f9f18dd4a7025fced6efc0 +md5: 513dd884361dfb8a554298ed69b58823 +depends: +- libgcc >=14 +constrains: +- expat 2.8.1.* +license: MIT +license_family: MIT +size: 77140 +timestamp: 1779278671302 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda +sha256: 3df4c539449aabc3443bbe8c492c01d401eea894603087fca2917aa4e1c2dea9 +md5: 2f364feefb6a7c00423e80dcb12db62a +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 55952 +timestamp: 1769456078358 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda +sha256: 752e4f66283d7deb4c6fd47d88df644d8daa2aaa825a54f3bf350a625190192a +md5: a229e22d4d8814a07702b0919d8e6701 +depends: +- libfreetype6 >=2.14.3 +license: GPL-2.0-only OR FTL +size: 8125 +timestamp: 1774301094057 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda +sha256: 8e6b27fe4eec4c2fa7b7769a21973734c8dba1de80086fb0213e58375ac09f4c +md5: b99ed99e42dafb27889483b3098cace7 +depends: +- libgcc >=14 +- libpng >=1.6.55,<1.7.0a0 +- libzlib >=1.3.2,<2.0a0 +constrains: +- freetype >=2.14.3 +license: GPL-2.0-only OR FTL +size: 422941 +timestamp: 1774301093473 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_19.conda +sha256: 4592b096e553f67799ae70d4b6167eeda3ec74587d68c7aecbf4e7b1df136681 +md5: f35b3f52d0a2ec4ffe3c89ba135cdb9a +depends: +- _openmp_mutex >=4.5 +constrains: +- libgomp 15.2.0 h8acb6b2_19 +- libgcc-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 622462 +timestamp: 1778268755949 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_19.conda +sha256: 1137f93f477f56199ded24117430045a0c02cbe8b10031beac3b9ad2138539d3 +md5: 770cf892e5530f43e63cadc673e85653 +depends: +- libgcc 15.2.0 h8acb6b2_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27738 +timestamp: 1778268759211 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_19.conda +sha256: e5ad94be72634233510b33ba792a3339921bd468f0b8bc6961ea05eded251d9b +md5: c7a5b5decf969ead5ecada83654164cf +depends: +- libgfortran5 15.2.0 h1b7bec0_19 +constrains: +- libgfortran-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 27728 +timestamp: 1778268784621 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_19.conda +sha256: af8e9bdcaa77f133a8ee4c1ef57ef564d9c45aa262abf9f5ef9b50eb99d96407 +md5: 779dbb494de6d3d6477cab52eb34285a +depends: +- libgcc >=15.2.0 +constrains: +- libgfortran 15.2.0 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 1487244 +timestamp: 1778268767295 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_19.conda +sha256: 2370ef0ffcbae5bede3c4bf136add4abc257245eb91f724c99bb4a43116c5a83 +md5: c5e8a379c4a2ec2aea4ba22758c001d9 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 587387 +timestamp: 1778268674393 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda +sha256: e97ec2af5f09f8f6ea8ecd550055c95ae80fae22015fcfadaa94eafe025c9ccc +md5: a85ba48648f6868016f2741fd9170250 +depends: +- libgcc >=14 +constrains: +- jpeg <0.0.0a +license: IJG AND BSD-3-Clause AND Zlib +size: 693143 +timestamp: 1775962625956 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-7_h88aeb00_openblas.conda +build_number: 7 +sha256: 20b38a0156200ac65f597bf0a93914c565435f2cc58b1042581854231a99ac35 +md5: 5899cbd743cc74fd655c1ed2af7120f3 +depends: +- libblas 3.11.0 7_haddc8a3_openblas +constrains: +- libcblas 3.11.0 7*_openblas +- blas 2.307 openblas +- liblapacke 3.11.0 7*_openblas +license: BSD-3-Clause +license_family: BSD +size: 18685 +timestamp: 1778489809140 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda +sha256: d61962b9cd54c3554361550203c64d5b65b71e3058a285b66e4b04b9769f0a5c +md5: 76298a9e6d71ee6e832a8d0d7373b261 +depends: +- libgcc >=14 +constrains: +- xz 5.8.3.* +license: 0BSD +size: 126102 +timestamp: 1775828008518 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libmpdec-4.0.0-he30d5cf_1.conda +sha256: 57c0dd12d506e84541c4e877898bd2a59cca141df493d34036f18b2751e0a453 +md5: 7b9813e885482e3ccb1fa212b86d7fd0 +depends: +- libgcc >=14 +license: BSD-2-Clause +license_family: BSD +size: 114056 +timestamp: 1769482343003 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.33-pthreads_h9d3fd7e_0.conda +sha256: b018ecfb05e75a8eea3f21f6b5c5c2a54b5178bdcf19e2e2df2735740214a8c8 +md5: 58a66cd95e9692f08abe89f55a6f3f12 +depends: +- libgcc >=14 +- libgfortran +- libgfortran5 >=14.3.0 +constrains: +- openblas >=0.3.33,<0.3.34.0a0 +license: BSD-3-Clause +license_family: BSD +size: 5121336 +timestamp: 1776993423004 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda +sha256: 483eaa53da40a6a3e558709d9f7b1ca388735364ae21a1ba58cf942514649c92 +md5: f51503ac45a4888bce71af9027a2ecc9 +depends: +- libgcc >=14 +- libzlib >=1.3.2,<2.0a0 +license: zlib-acknowledgement +size: 341202 +timestamp: 1776315188425 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.1-h022381a_0.conda +sha256: ad03b7d8e4d08001f0df88ee7a56108bb35bae4795a42b9a04cc1abfa822bd07 +md5: 2ec1119217d8f0d086e9a62f3cb0e5ea +depends: +- libgcc >=14 +- libzlib >=1.3.2,<2.0a0 +license: blessing +size: 955361 +timestamp: 1777986487553 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_19.conda +sha256: 1dadc45e599f510dd5f97141dddcdbb9844d9f1430c1f3a38075cf1c58f87b4e +md5: 543fbc8d71f2a0baf04cf88ce96cb8bb +depends: +- libgcc 15.2.0 h8acb6b2_19 +constrains: +- libstdcxx-ng ==15.2.0=*_19 +license: GPL-3.0-only WITH GCC-exception-3.1 +license_family: GPL +size: 5546559 +timestamp: 1778268777463 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda +sha256: 7ff79470db39e803e21b8185bc8f19c460666d5557b1378d1b1e857d929c6b39 +md5: 8c6fd84f9c87ac00636007c6131e457d +depends: +- lerc >=4.0.0,<5.0a0 +- libdeflate >=1.25,<1.26.0a0 +- libgcc >=14 +- libjpeg-turbo >=3.1.0,<4.0a0 +- liblzma >=5.8.1,<6.0a0 +- libstdcxx >=14 +- libwebp-base >=1.6.0,<2.0a0 +- libzlib >=1.3.1,<2.0a0 +- zstd >=1.5.7,<1.6.0a0 +license: HPND +size: 488407 +timestamp: 1762022048105 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42.1-h1022ec0_0.conda +sha256: 1628839b062e98b2192857d4da8496ac9ac6b0dbb77aa040c34efc9192c440ee +md5: 0f42f9fedd2a32d798de95a7f65c456f +depends: +- libgcc >=14 +license: BSD-3-Clause +license_family: BSD +size: 43453 +timestamp: 1779118526838 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda +sha256: b03700a1f741554e8e5712f9b06dd67e76f5301292958cd3cb1ac8c6fdd9ed25 +md5: 24e92d0942c799db387f5c9d7b81f1af +depends: +- libgcc >=14 +constrains: +- libwebp 1.6.0 +license: BSD-3-Clause +license_family: BSD +size: 359496 +timestamp: 1752160685488 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda +sha256: 461cab3d5650ac6db73a367de5c8eca50363966e862dcf60181d693236b1ae7b +md5: cd14ee5cca2464a425b1dbfc24d90db2 +depends: +- libgcc >=13 +- pthread-stubs +- xorg-libxau >=1.0.11,<2.0a0 +- xorg-libxdmcp +license: MIT +license_family: MIT +size: 397493 +timestamp: 1727280745441 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda +sha256: eb111e32e5a7313a5bf799c7fb2419051fa2fe7eff74769fac8d5a448b309f7f +md5: 502006882cf5461adced436e410046d1 +constrains: +- zlib 1.3.2 *_2 +license: Zlib +license_family: Other +size: 69833 +timestamp: 1774072605429 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-3.10.2-pyhcf101f3_0.conda +sha256: 20e0892592a3e7c683e3d66df704a9425d731486a97c34fc56af4da1106b2b6b +md5: ba0a9221ce1063f31692c07370d062f3 +depends: +- importlib-metadata >=4.4 +- python >=3.10 +- python +license: BSD-3-Clause +license_family: BSD +size: 85893 +timestamp: 1770694658918 +- conda: https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.2.0-pyhd8ed1ab_0.conda +sha256: 0c4c35376fe920714390d46e4b8d31c876d65f18e1655899e0763ec25f2a902f +md5: 6d03368f2b2b0a5fb6839df53b2eb5e0 +depends: +- mdurl >=0.1,<1 +- python >=3.10 +license: MIT +license_family: MIT +size: 69017 +timestamp: 1778169663339 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/markupsafe-3.0.3-py314hb76de3f_1.conda +sha256: 383c188496d13a55658c06e61e7d4cdff2c9f9d5a0648769fca8250bece7e0ef +md5: e5de3c36dd548b35ff2a8aa49208dcb3 +depends: +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +constrains: +- jinja2 >=3.0.0 +license: BSD-3-Clause +license_family: BSD +size: 27913 +timestamp: 1772446407659 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/mathjax-2.7.7-h8af1aa0_3.tar.bz2 +sha256: 8fd4c79d6eda3d4cba73783114305a53a154ada4d1e334d4e02cb3521429599b +md5: 7b08314a6867a9d5648a1c3265e9eb8e +license: Apache-2.0 +license_family: Apache +size: 22257008 +timestamp: 1662784555011 +- conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda +sha256: 78c1bbe1723449c52b7a9df1af2ee5f005209f67e40b6e1d3c7619127c43b1c7 +md5: 592132998493b3ff25fd7479396e8351 +depends: +- python >=3.9 +license: MIT +license_family: MIT +size: 14465 +timestamp: 1733255681319 +- conda: https://conda.anaconda.org/bioconda/noarch/multiqc-1.35-pyhdfd78af_1.conda +sha256: e86033aa55a9e915e2d0957e770bdb81e3feb26a227d1adb17f9d6c528da6a71 +md5: cdb20309681ba3ce8f52c110e214d4f3 +depends: +- click +- coloredlogs +- humanize +- importlib-metadata +- jinja2 >=3.0.0 +- jsonschema +- markdown +- natsort +- numpy +- packaging +- pillow >=10.2.0 +- plotly >=5.18 +- polars >=1.34.0 +- polars-runtime-compat >=1.34.0 +- pyaml-env +- pydantic >=2.7.1 +- python >=3.9,!=3.14.1 +- python-dotenv +- python-kaleido 0.2.1 +- pyyaml >=4 +- requests +- rich >=10 +- rich-click +- spectra >=0.0.10 +- tiktoken +- tqdm +- typeguard >=4 +license: GPL-3.0-or-later +license_family: GPL3 +size: 4282188 +timestamp: 1779465338806 +- conda: https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.2-pyhcf101f3_0.conda +sha256: 70f43d62450927d51673eecd8823e14f5b3cfebdb43cda1d502eba97162bab42 +md5: 6687827c332121727ce383919e1ec8c2 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 284323 +timestamp: 1778929680962 +- conda: https://conda.anaconda.org/conda-forge/noarch/natsort-8.4.0-pyhcf101f3_2.conda +sha256: aeb1548eb72e4f198e72f19d242fb695b35add2ac7b2c00e0d83687052867680 +md5: e941e85e273121222580723010bd4fa2 +depends: +- python >=3.9 +- python +license: MIT +license_family: MIT +size: 39262 +timestamp: 1770905275632 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.6-hf8d1292_0.conda +sha256: 369db85c5cd8d99dde364ce70725d76511d9c8199e5b820c740414091bf5bcca +md5: b2a43456aa56fe80c2477a5094899eff +depends: +- libgcc >=14 +license: X11 AND BSD-3-Clause +size: 960036 +timestamp: 1777422174534 +- conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda +sha256: f6a82172afc50e54741f6f84527ef10424326611503c64e359e25a19a8e4c1c6 +md5: a2c1eeadae7a309daed9d62c96012a2b +depends: +- python >=3.11 +- python +constrains: +- numpy >=1.25 +- scipy >=1.11.2 +- matplotlib-base >=3.8 +- pandas >=2.0 +license: BSD-3-Clause +license_family: BSD +size: 1587439 +timestamp: 1765215107045 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nspr-4.38-h3ad9384_0.conda +sha256: 78a06e89285fef242e272998b292c1e621e3ee3dd4fba62ec014e503c7ec118f +md5: 6dd4f07147774bf720075a210f8026b9 +depends: +- libgcc >=14 +- libstdcxx >=14 +license: MPL-2.0 +license_family: MOZILLA +size: 235140 +timestamp: 1762350120355 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/nss-3.118-h544fa81_0.conda +sha256: 48942696889367ffd448f8dccfc080fb7e130b9938a4a3b6b20ef8e6af856463 +md5: 4540f9570d12db2150f42ba036154552 +depends: +- libgcc >=14 +- libsqlite >=3.51.0,<4.0a0 +- libstdcxx >=14 +- libzlib >=1.3.1,<2.0a0 +- nspr >=4.38,<5.0a0 +license: MPL-2.0 +license_family: MOZILLA +size: 2061869 +timestamp: 1763490303490 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.6-py314he1698a1_0.conda +sha256: 04af718b911f8a3a0095481c7e283aa081a175fe626eccbc2c5644bcb2aba9a1 +md5: 8b173772deea177b45d2a133b509b3f7 +depends: +- python +- libstdcxx >=14 +- libgcc >=14 +- python_abi 3.14.* *_cp314 +- libblas >=3.9.0,<4.0a0 +- liblapack >=3.9.0,<4.0a0 +- libcblas >=3.9.0,<4.0a0 +constrains: +- numpy-base <0a0 +license: BSD-3-Clause +license_family: BSD +size: 8002900 +timestamp: 1779169206742 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda +sha256: bd1bc8bdde5e6c5cbac42d462b939694e40b59be6d0698f668515908640c77b8 +md5: cea962410e327262346d48d01f05936c +depends: +- libgcc >=14 +- libpng >=1.6.50,<1.7.0a0 +- libstdcxx >=14 +- libtiff >=4.7.1,<4.8.0a0 +- libzlib >=1.3.1,<2.0a0 +license: BSD-2-Clause +license_family: BSD +size: 392636 +timestamp: 1758489353577 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.2-h546c87b_0.conda +sha256: 348cb74c1530ac241215d047ef65d134cf797af935c97a68655319362b7e6a01 +md5: 3b129669089e4d6a5c6871dbb4669b99 +depends: +- ca-certificates +- libgcc >=14 +license: Apache-2.0 +license_family: Apache +size: 3706406 +timestamp: 1775589602258 +- conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda +sha256: 3906abfb6511a3bb309e39b9b1b7bc38f50a723971de2395489fd1f379255890 +md5: 4c06a92e74452cfa53623a81592e8934 +depends: +- python >=3.8 +- python +license: Apache-2.0 +license_family: APACHE +size: 91574 +timestamp: 1777103621679 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.2.0-py314hac3e5ec_0.conda +sha256: 96b26c2657275ffe84ab510edf0865e21999d791485d12794edd4a71b837beb6 +md5: 87d58d103b47c4a8567b3d7666647684 +depends: +- python +- libgcc >=14 +- python 3.14.* *_cp314 +- openjpeg >=2.5.4,<3.0a0 +- libxcb >=1.17.0,<2.0a0 +- libwebp-base >=1.6.0,<2.0a0 +- zlib-ng >=2.3.3,<2.4.0a0 +- python_abi 3.14.* *_cp314 +- lcms2 >=2.18,<3.0a0 +- tk >=8.6.13,<8.7.0a0 +- libtiff >=4.7.1,<4.8.0a0 +- libjpeg-turbo >=3.1.2,<4.0a0 +- libfreetype >=2.14.3 +- libfreetype6 >=2.14.3 +license: HPND +size: 1062080 +timestamp: 1775060067775 +- conda: https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda +sha256: c418d325359fc7a0074cea7f081ef1bce26e114d2da8a0154c5d27ecc87a08e7 +md5: 3e9427ee186846052e81fadde8ebe96a +depends: +- narwhals >=1.15.1 +- packaging +- python >=3.10 +constrains: +- ipywidgets >=7.6 +license: MIT +license_family: MIT +size: 5251872 +timestamp: 1772628857717 +- conda: https://conda.anaconda.org/conda-forge/noarch/polars-1.41.0-pyh58ad624_0.conda +sha256: 70fc56877c4a095ee658d61924d8019768fbae4a48437058d181fc94b0a7c4d8 +md5: 25a883fed9f1f3f21ff317a3e7c92ac4 +depends: +- polars-runtime-32 ==1.41.0 +- python >=3.10 +- python +constrains: +- numpy >=1.16.0 +- pyarrow >=7.0.0 +- fastexcel >=0.9 +- openpyxl >=3.0.0 +- xlsx2csv >=0.8.0 +- connectorx >=0.3.2 +- deltalake >=1.0.0 +- pyiceberg >=0.7.1 +- altair >=5.4.0 +- great_tables >=0.8.0 +- polars-runtime-32 ==1.41.0 +- polars-runtime-64 ==1.41.0 +- polars-runtime-compat ==1.41.0 +license: MIT +size: 539656 +timestamp: 1779630790562 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-32-1.41.0-py310h32c7c23_0.conda +noarch: python +sha256: d903b774ec09189e164207328aac157eee82fed8cc5c9ace46aeb5d1c15cb5b3 +md5: 8c08c506ed1ea8ce0ca37af5e918c58d +depends: +- python +- libgcc >=14 +- libstdcxx >=14 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +size: 38704429 +timestamp: 1779630794932 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/polars-runtime-compat-1.41.0-py310hc0e61be_0.conda +noarch: python +sha256: 101696adff43a654146376c62ef9611bf7946b95fa46f604fe247d77eefc6267 +md5: 65b73e4260677ee5162bdbb252e28e06 +depends: +- python +- libstdcxx >=14 +- libgcc >=14 +- _python_abi3_support 1.* +- cpython >=3.10 +constrains: +- __glibc >=2.17 +license: MIT +size: 38651498 +timestamp: 1779630714016 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/procps-ng-4.0.6-h1779866_0.conda +sha256: e9cbcbc94e151ada3d6dc365380aaaf591f65012c16d9a2abaea4b9b90adc402 +md5: ab7288cc39545556d1bc5e71ab2df9a9 +depends: +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-2.0-or-later AND LGPL-2.0-or-later +license_family: GPL +size: 636733 +timestamp: 1769712412683 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda +sha256: 977dfb0cb3935d748521dd80262fe7169ab82920afd38ed14b7fee2ea5ec01ba +md5: bb5a90c93e3bac3d5690acf76b4a6386 +depends: +- libgcc >=13 +license: MIT +license_family: MIT +size: 8342 +timestamp: 1726803319942 +- conda: https://conda.anaconda.org/conda-forge/noarch/pyaml-env-1.2.2-pyhd8ed1ab_0.conda +sha256: 58994e0d2ea8584cb399546e6f6896d771995e6121d1a7b6a2c9948388358932 +md5: e17be1016bcc3516827b836cd3e4d9dc +depends: +- python >=3.9 +- pyyaml >=5.0,<=7.0 +license: MIT +license_family: MIT +size: 14645 +timestamp: 1736766960536 +- conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.13.4-pyhcf101f3_0.conda +sha256: 69700e31165df070e9716315e042196aa92525dae5deb5107785847ab9f4189f +md5: 729843edafc0899b3348bd3f19525b9d +depends: +- typing-inspection >=0.4.2 +- typing_extensions >=4.14.1 +- python >=3.10 +- annotated-types >=0.6.0 +- pydantic-core ==2.46.4 +- python +license: MIT +license_family: MIT +size: 346511 +timestamp: 1778103405862 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pydantic-core-2.46.4-py314h451b6cc_0.conda +sha256: 1a7c6b18e404c13c4d959888ecb48a9ed9de0e41be2872932b83a35278088df0 +md5: 9c3ace6aba6df14b943256095ac1281e +depends: +- python +- typing-extensions >=4.6.0,!=4.7.0 +- libgcc >=14 +- python 3.14.* *_cp314 +- python_abi 3.14.* *_cp314 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 1780773 +timestamp: 1778084251775 +- conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda +sha256: cf70b2f5ad9ae472b71235e5c8a736c9316df3705746de419b59d442e8348e86 +md5: 16c18772b340887160c79a6acc022db0 +depends: +- python >=3.10 +license: BSD-2-Clause +license_family: BSD +size: 893031 +timestamp: 1774796815820 +- conda: https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda +sha256: ba3b032fa52709ce0d9fd388f63d330a026754587a2f461117cac9ab73d8d0d8 +md5: 461219d1a5bd61342293efa2c0c90eac +depends: +- __unix +- python >=3.9 +license: BSD-3-Clause +license_family: BSD +size: 21085 +timestamp: 1733217331982 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.14.5-hfd9ac0a_100_cp314.conda +build_number: 100 +sha256: d37bad5447365346166c72950ea8f49689aa49cecc1b0623d00458427627b8df +md5: d956e09feb806f5974675ce92ad81d45 +depends: +- bzip2 >=1.0.8,<2.0a0 +- ld_impl_linux-aarch64 >=2.36.1 +- libexpat >=2.8.0,<3.0a0 +- libffi >=3.5.2,<3.6.0a0 +- libgcc >=14 +- liblzma >=5.8.3,<6.0a0 +- libmpdec >=4.0.0,<5.0a0 +- libsqlite >=3.53.1,<4.0a0 +- libuuid >=2.42.1,<3.0a0 +- libzlib >=1.3.2,<2.0a0 +- ncurses >=6.6,<7.0a0 +- openssl >=3.5.6,<4.0a0 +- python_abi 3.14.* *_cp314 +- readline >=8.3,<9.0a0 +- tk >=8.6.13,<8.7.0a0 +- tzdata +- zstd >=1.5.7,<1.6.0a0 +license: Python-2.0 +size: 37510439 +timestamp: 1779236267040 +python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.2.2-pyhcf101f3_0.conda +sha256: 74e417a768f59f02a242c25e7db0aa796627b5bc8c818863b57786072aeb85e5 +md5: 130584ad9f3a513cdd71b1fdc1244e9c +depends: +- python >=3.10 +license: BSD-3-Clause +license_family: BSD +size: 27848 +timestamp: 1772388605021 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.5-h4df99d1_100.conda +sha256: 41dd7da285d71d519257fa7dacb1cae060d5ebfaa5f92cba5994899d2978e943 +md5: 41954747ba952ec4b01e16c2c9e8d8ff +depends: +- cpython 3.14.5.* +- python_abi * *_cp314 +license: Python-2.0 +size: 50212 +timestamp: 1779236703009 +- conda: https://conda.anaconda.org/conda-forge/noarch/python-kaleido-0.2.1-pyhd8ed1ab_0.tar.bz2 +sha256: e17bf63a30aec33432f1ead86e15e9febde9fc40a7f869c0e766be8d2db44170 +md5: 310259a5b03ff02289d7705f39e2b1d2 +depends: +- kaleido-core 0.2.1.* +- python >=3.5 +license: MIT +license_family: MIT +size: 18320 +timestamp: 1615204747600 +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda +build_number: 8 +sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 +md5: 0539938c55b6b1a59b560e843ad864a4 +constrains: +- python 3.14.* *_cp314 +license: BSD-3-Clause +license_family: BSD +size: 6989 +timestamp: 1752805904792 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/pyyaml-6.0.3-py314h807365f_1.conda +sha256: 496b5e65dfdd0aaaaa5de0dcaaf3bceea00fcb4398acf152f89e567c82ec1046 +md5: 9ae2c92975118058bd720e9ba2bb7c58 +depends: +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python >=3.14,<3.15.0a0 *_cp314 +- python_abi 3.14.* *_cp314 +- yaml >=0.2.5,<0.3.0a0 +license: MIT +license_family: MIT +size: 195678 +timestamp: 1770223441816 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda +sha256: fe695f9d215e9a2e3dd0ca7f56435ab4df24f5504b83865e3d295df36e88d216 +md5: 3d49cad61f829f4f0e0611547a9cda12 +depends: +- libgcc >=14 +- ncurses >=6.5,<7.0a0 +license: GPL-3.0-only +license_family: GPL +size: 357597 +timestamp: 1765815673644 +- conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda +sha256: 0577eedfb347ff94d0f2fa6c052c502989b028216996b45c7f21236f25864414 +md5: 870293df500ca7e18bedefa5838a22ab +depends: +- attrs >=22.2.0 +- python >=3.10 +- rpds-py >=0.7.0 +- typing_extensions >=4.4.0 +- python +license: MIT +license_family: MIT +size: 51788 +timestamp: 1760379115194 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/regex-2026.5.9-py314h51f160d_0.conda +sha256: 05ef55f09f31eabd0a205f6b065e13fc746675f41924620977692ef0ffe5aad8 +md5: 34ed7bc9febeca70f55b757ca09c354d +depends: +- libgcc >=14 +- python >=3.14,<3.15.0a0 +- python >=3.14,<3.15.0a0 *_cp314 +- python_abi 3.14.* *_cp314 +license: Apache-2.0 AND CNRI-Python +license_family: PSF +size: 409780 +timestamp: 1778374195988 +- conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.34.2-pyhcf101f3_0.conda +sha256: 1715246b19c9f85ee022933b4845f2fc14ac9184981b7b7d9b728bec8e9588da +md5: 4a85203c1d80c1059086ae860836ffb9 +depends: +- python >=3.10 +- certifi >=2023.5.7 +- charset-normalizer >=2,<4 +- idna >=2.5,<4 +- urllib3 >=1.26,<3 +- python +constrains: +- chardet >=3.0.2,<8 +license: Apache-2.0 +license_family: APACHE +size: 68709 +timestamp: 1778851103479 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-15.0.0-pyhcf101f3_0.conda +sha256: 3d6ba2c0fcdac3196ba2f0615b4104e532525ffa1335b50a2878be5ff488814a +md5: 0242025a3c804966bf71aa04eee82f66 +depends: +- markdown-it-py >=2.2.0 +- pygments >=2.13.0,<3.0.0 +- python >=3.10 +- typing_extensions >=4.0.0,<5.0.0 +- python +license: MIT +license_family: MIT +size: 208577 +timestamp: 1775991661559 +- conda: https://conda.anaconda.org/conda-forge/noarch/rich-click-1.9.7-pyh8f84b5b_0.conda +sha256: aa3fcb167321bae51998de2e94d199109c9024f25a5a063cb1c28d8f1af33436 +md5: 0c20a8ebcddb24a45da89d5e917e6cb9 +depends: +- python >=3.10 +- rich >=12 +- click >=8 +- typing-extensions >=4 +- __unix +- python +license: MIT +license_family: MIT +size: 64356 +timestamp: 1769850479089 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/rpds-py-0.30.0-py314h02b7a91_0.conda +sha256: a587240f16eac7c6a80f9585cef679cd1cb9a287b8dfcdd36dcef1f7e7db15dc +md5: e7f6ed9e60043bb5cbcc527764897f0d +depends: +- python +- libgcc >=14 +- python_abi 3.14.* *_cp314 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 376332 +timestamp: 1764543345455 +- conda: https://conda.anaconda.org/conda-forge/noarch/spectra-0.0.11-pyhd8ed1ab_2.conda +sha256: 7c65782d2511738e62c70462e89d65da4fa54d5a7e47c46667bcd27a59f81876 +md5: 472239e4eb7b5a84bb96b3ed7e3a596a +depends: +- colormath >=3.0.0 +- python >=3.9 +license: MIT +license_family: MIT +size: 22284 +timestamp: 1735770589188 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/sqlite-3.53.1-he8854b5_0.conda +sha256: 27467e4bfb0681546f149718c33b806fec078185fbaa6a4d17d440bc8f56185c +md5: 46009bdca2315a99e0a3a7d0ba1af3b9 +depends: +- libgcc >=14 +- libsqlite 3.53.1 h022381a_0 +- libzlib >=1.3.2,<2.0a0 +- ncurses >=6.6,<7.0a0 +- readline >=8.3,<9.0a0 +license: blessing +size: 209964 +timestamp: 1777986493350 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tiktoken-0.12.0-py314h6a36e60_3.conda +sha256: c1da41c79262b27efa168407cfecc47b20270e5fc071a8307f95a2c85fb94170 +md5: 55bf7b559202236157b14323b40f19e6 +depends: +- libgcc >=14 +- libstdcxx >=14 +- python >=3.14,<3.15.0a0 +- python_abi 3.14.* *_cp314 +- regex >=2022.1.18 +- requests >=2.26.0 +constrains: +- __glibc >=2.17 +license: MIT +license_family: MIT +size: 914402 +timestamp: 1764030357702 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda +sha256: e25c314b52764219f842b41aea2c98a059f06437392268f09b03561e4f6e5309 +md5: 7fc6affb9b01e567d2ef1d05b84aa6ed +depends: +- libgcc >=14 +- libzlib >=1.3.1,<2.0a0 +constrains: +- xorg-libx11 >=1.8.12,<2.0a0 +license: TCL +license_family: BSD +size: 3368666 +timestamp: 1769464148928 +- conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.67.3-pyh8f84b5b_0.conda +sha256: 9ef8e47cf00e4d6dcc114eb32a1504cc18206300572ef14d76634ba29dfe1eb6 +md5: e5ce43272193b38c2e9037446c1d9206 +depends: +- python >=3.10 +- __unix +- python +license: MPL-2.0 and MIT +size: 94132 +timestamp: 1770153424136 +- conda: https://conda.anaconda.org/conda-forge/noarch/typeguard-4.5.2-pyhcf101f3_0.conda +sha256: 59d7851d32fddb5b510272e6557aa982edeb927d349648dac27f5bf01d18bb26 +md5: 4460f039b7dedf15f7df086446ca75ae +depends: +- typing_extensions >=4.14.0 +- python >=3.10 +- importlib-metadata >=3.6 +- python +constrains: +- pytest >=7 +license: MIT +license_family: MIT +size: 38297 +timestamp: 1778779291237 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda +sha256: 7c2df5721c742c2a47b2c8f960e718c930031663ac1174da67c1ed5999f7938c +md5: edd329d7d3a4ab45dcf905899a7a6115 +depends: +- typing_extensions ==4.15.0 pyhcf101f3_0 +license: PSF-2.0 +license_family: PSF +size: 91383 +timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing-inspection-0.4.2-pyhcf101f3_2.conda +sha256: 8b90d2f19f9458b8c58a55e1fcdc1d90c1603a847a47654d8a454549413ba60a +md5: 53f5409c5cfd6c5a66417d68e3f0a864 +depends: +- python >=3.10 +- typing_extensions >=4.12.0 +- python +license: MIT +license_family: MIT +size: 20935 +timestamp: 1777105465795 +- conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda +sha256: 032271135bca55aeb156cee361c81350c6f3fb203f57d024d7e5a1fc9ef18731 +md5: 0caa1af407ecff61170c9437a808404d +depends: +- python >=3.10 +- python +license: PSF-2.0 +license_family: PSF +size: 51692 +timestamp: 1756220668932 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda +sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c +md5: ad659d0a2b3e47e38d829aa8cad2d610 +license: LicenseRef-Public-Domain +size: 119135 +timestamp: 1767016325805 +- conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda +sha256: feff959a816f7988a0893201aa9727bbb7ee1e9cec2c4f0428269b489eb93fb4 +md5: cbb88288f74dbe6ada1c6c7d0a97223e +depends: +- backports.zstd >=1.0.0 +- brotli-python >=1.2.0 +- h2 >=4,<5 +- pysocks >=1.5.6,<2.0,!=1.5.7 +- python >=3.10 +license: MIT +license_family: MIT +size: 103560 +timestamp: 1778188657149 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda +sha256: e9f6e931feeb2f40e1fdbafe41d3b665f1ab6cb39c5880a1fcf9f79a3f3c84a5 +md5: 1c246e1105000c3660558459e2fd6d43 +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 16317 +timestamp: 1762977521691 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda +sha256: 128d72f36bcc8d2b4cdbec07507542e437c7d67f677b7d77b71ed9eeac7d6df1 +md5: bff06dcde4a707339d66d45d96ceb2e2 +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 21039 +timestamp: 1762979038025 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/yaml-0.2.5-h80f16a2_3.conda +sha256: 66265e943f32ce02396ad214e27cb35f5b0490b3bd4f064446390f9d67fa5d88 +md5: 032d8030e4a24fe1f72c74423a46fb88 +depends: +- libgcc >=14 +license: MIT +license_family: MIT +size: 88088 +timestamp: 1753484092643 +- conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda +sha256: 210bd31c22bb88f5e2a167df24c95bb5f152b2ada7502f9b8c49d1f5366db423 +md5: ba3dcdc8584155c97c648ae9c044b7a3 +depends: +- python >=3.10 +- python +license: MIT +license_family: MIT +size: 24190 +timestamp: 1779159948016 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda +sha256: 638a3a41a4fbfed52d3c60c8ef5a3693b3f12a5b1a3f58fa29f5698d0a0702e2 +md5: f731af71c723065d91b4c01bb822641b +depends: +- libgcc >=14 +- libstdcxx >=14 +license: Zlib +license_family: Other +size: 121046 +timestamp: 1770167944449 +- conda: https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda +sha256: 569990cf12e46f9df540275146da567d9c618c1e9c7a0bc9d9cfefadaed20b75 +md5: c3655f82dcea2aa179b291e7099c1fcc +depends: +- libzlib >=1.3.1,<2.0a0 +license: BSD-3-Clause +license_family: BSD +size: 614429 +timestamp: 1764777145593 diff --git a/nf_core/pipeline-template/modules/nf-core/multiqc/environment.yml b/nf_core/pipeline-template/modules/nf-core/multiqc/environment.yml index 37e7612d4c..7a970e2bb5 100644 --- a/nf_core/pipeline-template/modules/nf-core/multiqc/environment.yml +++ b/nf_core/pipeline-template/modules/nf-core/multiqc/environment.yml @@ -4,4 +4,4 @@ channels: - conda-forge - bioconda dependencies: - - bioconda::multiqc=1.34 + - bioconda::multiqc=1.35 diff --git a/nf_core/pipeline-template/modules/nf-core/multiqc/main.nf b/nf_core/pipeline-template/modules/nf-core/multiqc/main.nf index e80e8cd8d1..c4bc715e22 100644 --- a/nf_core/pipeline-template/modules/nf-core/multiqc/main.nf +++ b/nf_core/pipeline-template/modules/nf-core/multiqc/main.nf @@ -4,8 +4,8 @@ process MULTIQC { conda "${moduleDir}/environment.yml" container "${workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container - ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/1b/1bef8af6be88c5733461959c46ac8ef73d18f65277f62a1695d0e1633054f9c2/data' - : 'community.wave.seqera.io/library/multiqc:1.34--db7c73dae76bc9e6'}" + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c8/c8e346f4f6080eadf1253505e6ff09ef004454fc18e8d672006fd7b222cc412e/data' + : 'community.wave.seqera.io/library/multiqc:1.35--c17fb751507e9dfc'}" input: tuple val(meta), path(multiqc_files, stageAs: "?/*"), path(multiqc_config, stageAs: "?/*"), path(multiqc_logo), path(replace_names), path(sample_names) diff --git a/nf_core/pipeline-template/modules/nf-core/multiqc/meta.yml b/nf_core/pipeline-template/modules/nf-core/multiqc/meta.yml index 2facc627ba..27ce18d8d8 100644 --- a/nf_core/pipeline-template/modules/nf-core/multiqc/meta.yml +++ b/nf_core/pipeline-template/modules/nf-core/multiqc/meta.yml @@ -110,24 +110,24 @@ maintainers: containers: conda: linux/amd64: - lock_file: modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-db7c73dae76bc9e6_1.txt + lock_file: modules/nf-core/multiqc/.conda-lock/linux_amd64-bd-c17fb751507e9dfc_1.txt linux/arm64: - lock_file: modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-d167b8012595a136_1.txt + lock_file: modules/nf-core/multiqc/.conda-lock/linux_arm64-bd-5c84a5000a226ab5_1.txt docker: linux/amd64: - name: community.wave.seqera.io/library/multiqc:1.34--db7c73dae76bc9e6 - build_id: bd-db7c73dae76bc9e6_1 - scan_id: sc-66fc7138dbf1cf48_1 + name: community.wave.seqera.io/library/multiqc:1.35--c17fb751507e9dfc + build_id: bd-c17fb751507e9dfc_1 + scan_id: sc-3b1b3932f9846892_1 linux/arm64: - name: community.wave.seqera.io/library/multiqc:1.34--d167b8012595a136 - build_id: bd-d167b8012595a136_1 - scan_id: sc-ac701dfa631a2af9_1 + name: community.wave.seqera.io/library/multiqc:1.35--5c84a5000a226ab5 + build_id: bd-5c84a5000a226ab5_1 + scan_id: sc-0d39df41e9737bbd_1 singularity: linux/amd64: - name: oras://community.wave.seqera.io/library/multiqc:1.34--4fc8657c816047c0 - build_id: bd-4fc8657c816047c0_1 - https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/1b/1bef8af6be88c5733461959c46ac8ef73d18f65277f62a1695d0e1633054f9c2/data + name: oras://community.wave.seqera.io/library/multiqc:1.35--c680f2aea25ccec2 + build_id: bd-c680f2aea25ccec2_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/c8/c8e346f4f6080eadf1253505e6ff09ef004454fc18e8d672006fd7b222cc412e/data linux/arm64: - name: oras://community.wave.seqera.io/library/multiqc:1.34--7fbd82d945c06726 - build_id: bd-7fbd82d945c06726_1 - https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/9a/9a1fec9662a152683e6fcae440d0ce20920b3b89dc62d1e3a52e73f92eba0969/data + name: oras://community.wave.seqera.io/library/multiqc:1.35--c0468833d65b2f81 + build_id: bd-c0468833d65b2f81_1 + https: https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/e4/e48aa28aebc881254a499b24c3e1ce77b8df1b85a5432699ed6f72eb17ac7fb5/data diff --git a/nf_core/pipeline-template/modules/nf-core/multiqc/tests/main.nf.test.snap b/nf_core/pipeline-template/modules/nf-core/multiqc/tests/main.nf.test.snap index 7c2f370f39..4489921603 100644 --- a/nf_core/pipeline-template/modules/nf-core/multiqc/tests/main.nf.test.snap +++ b/nf_core/pipeline-template/modules/nf-core/multiqc/tests/main.nf.test.snap @@ -81,7 +81,7 @@ [ "MULTIQC", "multiqc", - "1.34" + "1.35" ] ] } @@ -175,7 +175,7 @@ [ "MULTIQC", "multiqc", - "1.34" + "1.35" ] ] } @@ -221,7 +221,7 @@ [ "MULTIQC", "multiqc", - "1.34" + "1.35" ] ] } @@ -314,7 +314,7 @@ [ "MULTIQC", "multiqc", - "1.34" + "1.35" ] ] } @@ -408,7 +408,7 @@ [ "MULTIQC", "multiqc", - "1.34" + "1.35" ] ] } diff --git a/nf_core/pipeline-template/subworkflows/local/utils_nfcore_pipeline_pipeline/main.nf b/nf_core/pipeline-template/subworkflows/local/utils_nfcore_pipeline_pipeline/main.nf index 85c7c0ca5d..f78936db97 100644 --- a/nf_core/pipeline-template/subworkflows/local/utils_nfcore_pipeline_pipeline/main.nf +++ b/nf_core/pipeline-template/subworkflows/local/utils_nfcore_pipeline_pipeline/main.nf @@ -98,7 +98,8 @@ workflow PIPELINE_INITIALISATION { show_hidden, before_text, after_text, - command + command, + false ) {%- endif %} diff --git a/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/main.nf b/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/main.nf index 1df8b76fba..9ff0681f15 100644 --- a/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/main.nf +++ b/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/main.nf @@ -22,6 +22,7 @@ workflow UTILS_NFSCHEMA_PLUGIN { before_text // string: text to show before the help message and parameters summary after_text // string: text to show after the help message and parameters summary command // string: an example command of the pipeline + cli_typecast // boolean: whether to perform typecasting of CLI parameters. Set this to `null` to use the default behaviour main: @@ -34,11 +35,11 @@ workflow UTILS_NFSCHEMA_PLUGIN { fullHelp: help_full, ] if(parameters_schema) { - help_options << [parametersSchema: parameters_schema] + help_options << [parameters_schema: parameters_schema] } log.info paramsHelp( help_options, - (params.help instanceof String && params.help != "true") ? params.help : "", + (help instanceof String && help != "true") ? help : "", ) exit 0 } @@ -50,7 +51,7 @@ workflow UTILS_NFSCHEMA_PLUGIN { summary_options = [:] if(parameters_schema) { - summary_options << [parametersSchema: parameters_schema] + summary_options << [parameters_schema: parameters_schema] } log.info before_text log.info paramsSummaryLog(summary_options, input_workflow) @@ -63,7 +64,10 @@ workflow UTILS_NFSCHEMA_PLUGIN { if(validate_params) { validateOptions = [:] if(parameters_schema) { - validateOptions << [parametersSchema: parameters_schema] + validateOptions << [parameters_schema: parameters_schema] + } + if(cli_typecast != null) { + validateOptions << [cast_cli_params: cli_typecast] } validateParameters(validateOptions) } diff --git a/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/meta.yml b/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/meta.yml index f7d9f02885..1d8c75a952 100644 --- a/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/meta.yml +++ b/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/meta.yml @@ -25,6 +25,30 @@ input: option. When this input is empty it will automatically use the configured schema or "${projectDir}/nextflow_schema.json" as default. The schema should not be given in this way for meta pipelines. + - help: + type: boolean, string + description: | + Show the help message and exit. When a parameter name is given, show the help message for that parameter instead of the general help message. + - help_full: + type: boolean + description: Show the full help message and exit. + - show_hidden: + type: boolean + description: Show hidden parameters in the help message. + - before_text: + type: string + description: Text to show before the parameters summary and help message. + - after_text: + type: string + description: Text to show after the parameters summary and help message. + - command: + type: string + description: An example command to run the pipeline, to show in the help message and the summary. + - cli_typecast: + type: boolean + description: | + Whether to apply typecasting to the parameters given via the CLI before validation. + Set this to `null` to use the default behavior. output: - dummy_emit: type: boolean diff --git a/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test b/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test index c977917aac..1fd1eac1f4 100644 --- a/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test +++ b/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/tests/main.nf.test @@ -31,6 +31,7 @@ nextflow_workflow { input[6] = "" input[7] = "" input[8] = "" + input[9] = null """ } } @@ -63,6 +64,7 @@ nextflow_workflow { input[6] = "" input[7] = "" input[8] = "" + input[9] = null """ } } @@ -95,6 +97,7 @@ nextflow_workflow { input[6] = "" input[7] = "" input[8] = "" + input[9] = null """ } } @@ -127,6 +130,7 @@ nextflow_workflow { input[6] = "" input[7] = "" input[8] = "" + input[9] = null """ } } @@ -160,6 +164,7 @@ nextflow_workflow { input[6] = "Before" input[7] = "After" input[8] = "nextflow run test/test" + input[9] = null """ } } diff --git a/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config b/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config index f6537cc330..fd71cb8f85 100644 --- a/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config +++ b/nf_core/pipeline-template/subworkflows/nf-core/utils_nfschema_plugin/tests/nextflow.config @@ -1,5 +1,5 @@ plugins { - id "nf-schema@2.6.1" + id "nf-schema@2.7.2" } validation { diff --git a/pyproject.toml b/pyproject.toml index 74f20613f4..c4581108b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ nf_core = ["**/*"] [project] name = "nf-core" -version = "4.1.0dev" +version = "4.1.0" description = "Helper tools for use with nf-core Nextflow pipelines." readme = "README.md" license = "MIT" diff --git a/tests/pipelines/test_sync.py b/tests/pipelines/test_sync.py index ffcf9bb9c1..5d21b7a086 100644 --- a/tests/pipelines/test_sync.py +++ b/tests/pipelines/test_sync.py @@ -403,7 +403,7 @@ def test_push_merge_branch(self): psync = nf_core.pipelines.sync.PipelineSync(self.pipeline_dir) psync.inspect_sync_dir() psync.get_wf_config() - psync.repo.create_remote("origin", self.remote_path) + psync.repo.create_remote("origin", str(self.remote_path)) psync.create_merge_base_branch() psync.push_merge_branch() @@ -415,7 +415,7 @@ def test_push_merge_branch_without_create_branch(self): psync = nf_core.pipelines.sync.PipelineSync(self.pipeline_dir) psync.inspect_sync_dir() psync.get_wf_config() - psync.repo.create_remote("origin", self.remote_path) + psync.repo.create_remote("origin", str(self.remote_path)) with pytest.raises(nf_core.pipelines.sync.PullRequestExceptionError) as exc_info: psync.push_merge_branch() diff --git a/uv.lock b/uv.lock index 274bdb5bfd..d36e7988cd 100644 --- a/uv.lock +++ b/uv.lock @@ -2,9 +2,18 @@ version = 1 revision = 3 requires-python = ">=3.10, <4" resolution-markers = [ - "python_full_version >= '3.15'", - "python_full_version >= '3.12' and python_full_version < '3.15'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.11'", ] @@ -19,7 +28,7 @@ wheels = [ [[package]] name = "aiohttp" -version = "3.14.2" +version = "3.14.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -32,126 +41,126 @@ dependencies = [ { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1d/cc/58f26f118d8099f84e009ce560b9148a3f803e63fa8473b57feb67241875/aiohttp-3.14.2.tar.gz", hash = "sha256:f96821eb2ae2f12b0dfa799eafbf221f5621a9220b457b4744a269a63a5f3a6c", size = 7969860, upload-time = "2026-07-20T19:53:26.881Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/86/37/6a24e23d559bc2d042287cee15b4a6e61b46f844d2b3c96832483f854a4a/aiohttp-3.14.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ceb77c159b2b4c1a179b96a26af36bcaa68eb79c393ec4f569386a69d013cbe9", size = 765793, upload-time = "2026-07-20T19:49:37.707Z" }, - { url = "https://files.pythonhosted.org/packages/dc/14/23aa28408805efe6adc0e97048f5cd6028a2a3036d237038f45d10dc05a6/aiohttp-3.14.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3f3381f81bc1c6cbe160b2a3708d39d05014329118e6b648b95edc841eeeebd4", size = 517440, upload-time = "2026-07-20T19:49:40.182Z" }, - { url = "https://files.pythonhosted.org/packages/24/2d/7fc2d359d6702ce5299cd865ec2c70dad2fd8c1b3901bc79f83e3c61c395/aiohttp-3.14.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:483b6f964bbbdaa99a0cd7def631208c44e39d243b95cff23ebc812db8a80e03", size = 515306, upload-time = "2026-07-20T19:49:41.818Z" }, - { url = "https://files.pythonhosted.org/packages/dc/f0/fd9c7019bdfba5529c9a697621a757f0cfd92787595a04a9252923b097fc/aiohttp-3.14.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc056948b7a8a40484b4bbc69923fa25cddd80cbc5f236a3a22ad2f836baeed2", size = 1708602, upload-time = "2026-07-20T19:49:43.351Z" }, - { url = "https://files.pythonhosted.org/packages/3d/6d/8de300d792a3b91a94533a626a835c32cda69189209ae539bebaadba88ad/aiohttp-3.14.2-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:135570f5b470c72c4988a58986f1f847ad336721f77fcc18fda8472bd3bbe3db", size = 1673881, upload-time = "2026-07-20T19:49:44.753Z" }, - { url = "https://files.pythonhosted.org/packages/65/27/37559302e4f03e343f549ff1628295c20fb0298d603e40193db2f25f5153/aiohttp-3.14.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ee5bdd7933c653e43ef8d720704a4e228e4927121f2f5f598b7efe6a4c18633a", size = 1766985, upload-time = "2026-07-20T19:49:46.464Z" }, - { url = "https://files.pythonhosted.org/packages/df/55/29cc3691fa0bb1334352bcb61ba5f256396fd6a0603cf321b8c29bb7e1fe/aiohttp-3.14.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0baed2a2367a28456b612f4c3fd28bb86b00fadfb6454e706d8f65c21636bfd7", size = 1858788, upload-time = "2026-07-20T19:49:48.015Z" }, - { url = "https://files.pythonhosted.org/packages/71/63/36a34c0139d0b1a830e8ee130a75312e9eddccb5b234a7f56e9de5e6edd2/aiohttp-3.14.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecdd6b8cab5b7c0ff2988378c11ba7192f076a1864e64dc3ff72f7ba05c71796", size = 1714003, upload-time = "2026-07-20T19:49:49.714Z" }, - { url = "https://files.pythonhosted.org/packages/ac/d8/c3a37079d503967a4072f8fc187c9d46c62b1eb72b25ae57dc0f2d0ddb11/aiohttp-3.14.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a3177e51e26e0158fb3376aebac97e0546c6f175c510f331f585e514a00a302b", size = 1588046, upload-time = "2026-07-20T19:49:51.209Z" }, - { url = "https://files.pythonhosted.org/packages/ba/0c/c42b45bb275983cde529a4bc0e94f23ca6cdfe2a3c97285e73a4a6b81c23/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:86861a430657bc71e0f89b195de5f8fa495c0b9b5864cf2f89bd5ec1dbb6b77a", size = 1677219, upload-time = "2026-07-20T19:49:52.89Z" }, - { url = "https://files.pythonhosted.org/packages/75/a1/bdcd55b54d6335bc33e5f1b9f8613501c7f35cd99f44bf462d540d6b30d8/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:aac1b05fc5e2ef188b6d74cf151e977db75ab281238f30c3163bbd6f797788e3", size = 1691747, upload-time = "2026-07-20T19:49:54.495Z" }, - { url = "https://files.pythonhosted.org/packages/f1/98/a0d751d3787f2ca457beb16de5774a24e53fab840a8c7cb727cf900ed301/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:89120e926c68c4e60c78514d76e16fc15689d8df35843b2a6bf6c4cc0d64b11a", size = 1735039, upload-time = "2026-07-20T19:49:56.269Z" }, - { url = "https://files.pythonhosted.org/packages/ea/7a/33b8a5d348abc7335de33f4332ec0dcedfc7d45db28fd2162802d306345d/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:82d14d66d6147441b6571833405c828980efc17bda98075a248104ffdd330c30", size = 1577209, upload-time = "2026-07-20T19:49:57.926Z" }, - { url = "https://files.pythonhosted.org/packages/a9/03/09d41c3866e2102e6679e49fd78cd928926326fd304fa4e6f1d155f8ba04/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6cde463b9dd9ce4343785c5a39127b40fce059ae6fbd320f5a045a38c3d25cd0", size = 1751303, upload-time = "2026-07-20T19:49:59.472Z" }, - { url = "https://files.pythonhosted.org/packages/eb/53/72115db0f3e4490b6c0cb063709d7553a1661ec03532b1b2f891e841af1b/aiohttp-3.14.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2280d165ab38355144d9984cdce77ce506cee019a07390bab7fd13682248ce91", size = 1699526, upload-time = "2026-07-20T19:50:01.328Z" }, - { url = "https://files.pythonhosted.org/packages/0c/c6/9b8964be6d8d67dcf4bf32ff2380c203380322b1e23b5c1aa122c9b5a740/aiohttp-3.14.2-cp310-cp310-win32.whl", hash = "sha256:5e94a8c4445bfdaa30773c81f2be7f129673e0f528945e542b8bd024b2979134", size = 456626, upload-time = "2026-07-20T19:50:02.79Z" }, - { url = "https://files.pythonhosted.org/packages/bf/10/8dcdbbd9d83103db95ff74b255105113c1f6983865446f4facef81f0a1eb/aiohttp-3.14.2-cp310-cp310-win_amd64.whl", hash = "sha256:65cd3bb118f42fceceb9e8a615c735a01453d019c673f35c57b420601cc1a83a", size = 480367, upload-time = "2026-07-20T19:50:04.284Z" }, - { url = "https://files.pythonhosted.org/packages/14/08/b6eb0532f5ec2b202980c2d9658dd8ee3a1e21cdd0cb9d01debc0ba40045/aiohttp-3.14.2-cp310-cp310-win_arm64.whl", hash = "sha256:2a382aa6bb85347515ead043257445baeec0885d42bfedb962093b134c3b4816", size = 453374, upload-time = "2026-07-20T19:50:05.953Z" }, - { url = "https://files.pythonhosted.org/packages/f6/4a/a6c1426d2fb3cddd901575436803733caaaeb7ac0a49aa72d1930d2e3ab6/aiohttp-3.14.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:56432ee8f7abe47c97717cfbf5c32430463ea8a7138e12a87b7891fa6084c8ff", size = 764168, upload-time = "2026-07-20T19:50:07.389Z" }, - { url = "https://files.pythonhosted.org/packages/0c/62/88ae65afc3590719788cbff3b2e0f56e6850f53ca34114cbb371e677c543/aiohttp-3.14.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c244f7a65cbec04c830a301aae443c529d4dbca5fddfd4b19e5a179d896adfd", size = 516255, upload-time = "2026-07-20T19:50:08.84Z" }, - { url = "https://files.pythonhosted.org/packages/8f/bc/ad9b767785b014f2f57497a2ccf67e3d4316d153f7ed1c7715fbbd7573fe/aiohttp-3.14.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c05afdd28ecacce5a1f63275a2e3dce09efddd3a63d143ee9799fda83989c8d", size = 514670, upload-time = "2026-07-20T19:50:10.325Z" }, - { url = "https://files.pythonhosted.org/packages/48/94/697aef63f15ef354f64723eaac6ccfb289d59b99699b3b7cb1ff663b2045/aiohttp-3.14.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a57f39d6ec155932853b6b0f130cbbafab3208240fa807f29a2c96ea52b77ae1", size = 1780650, upload-time = "2026-07-20T19:50:11.676Z" }, - { url = "https://files.pythonhosted.org/packages/99/f9/6a1994c1bf138403cf10171cb618571a330ae5683a5803b1ef29b5723d7f/aiohttp-3.14.2-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1fc31339824ec922cb7424d624b5b6c11d8942d077b2585e5bd602ca1a1e27ed", size = 1737710, upload-time = "2026-07-20T19:50:13.401Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ba/abe8d5015148b2cd7189473789461058dcf88ae202d4cf1cbecaf291a7ef/aiohttp-3.14.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d93854e215dcc7c88e4f530827193c1a594e2662931d8dbe7cca3abf52a7082d", size = 1845568, upload-time = "2026-07-20T19:50:15.168Z" }, - { url = "https://files.pythonhosted.org/packages/c2/89/98a2688810f469f19f2d02a298426a37b6e1cc420230a8cc7d6c85af7a01/aiohttp-3.14.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87c9b03be0c18c3b3587be979149830381e37ac4a6ca8557dbe72e44fcad66c3", size = 1928485, upload-time = "2026-07-20T19:50:16.922Z" }, - { url = "https://files.pythonhosted.org/packages/5a/fd/c980f64f5e5bff22f07968bcc6af1b64167dfd21dbbffda86f2d153fc802/aiohttp-3.14.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bc1a0793dce8fa9bb6906411e57fb18a2f1c31357b04172541b92b30337362a7", size = 1786216, upload-time = "2026-07-20T19:50:18.598Z" }, - { url = "https://files.pythonhosted.org/packages/da/80/c710ce9c7f22fcbb83366aa64a5ccf03dced35ab09a6e37545656a6df01e/aiohttp-3.14.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2f1b9540d2d0f2f95590528a1effd0ba5370f6ec189ac925e70b5eecae02dc77", size = 1636921, upload-time = "2026-07-20T19:50:20.201Z" }, - { url = "https://files.pythonhosted.org/packages/e1/b2/56ce1b0c535d188ef94c05bccbf3f5b1aaea1231fcb073318977bdd917e9/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c0a968b04fecf7c94e502015860ad1e2e112c6b761e97b6fdf65fbb374e22b73", size = 1753040, upload-time = "2026-07-20T19:50:21.857Z" }, - { url = "https://files.pythonhosted.org/packages/86/61/4318a947139a21d4e1a40e7f5a92799d0fe28feffaca6640a4a165e62b0e/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:2d2eedae227cd5cbd0bccc5e759f71e1af2cd77b7f74ce413bb9a2b87f94a272", size = 1760811, upload-time = "2026-07-20T19:50:23.623Z" }, - { url = "https://files.pythonhosted.org/packages/81/b0/2012165377d029ceb925c9e5f42b0b30a39d89cf7e494c4100f3ab8d27c6/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9d3f4c68b2c2cd282b65e558cebf4b27c8b440ab511f2b938a643d3598df2ddb", size = 1819760, upload-time = "2026-07-20T19:50:25.34Z" }, - { url = "https://files.pythonhosted.org/packages/16/e5/1de93ba3bc18edb87f71594326bedafdc38fe725da8118b7d36fd56610f8/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:d32a70b8bf8836fd80d4169d9e34eb032cd2a7cbccb0b9cf00eac1f40732467c", size = 1628145, upload-time = "2026-07-20T19:50:26.992Z" }, - { url = "https://files.pythonhosted.org/packages/66/8f/adc9e8592449ee08f72fcce94b7f3f1a9bbf0591a46026e4d322e5a70d7a/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:386ce4e709b4cc40f9ef9a132ad8e672d2d164a65451305672df656e7794c68e", size = 1832577, upload-time = "2026-07-20T19:50:28.546Z" }, - { url = "https://files.pythonhosted.org/packages/9b/7f/700500700513b1b63967a24c4e189aad377e18f9d67b7387b3418d6213cb/aiohttp-3.14.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc0ed30b942c3bd755583d74bb00b90248c067d20b1f8301e4489a53a33aa65f", size = 1774814, upload-time = "2026-07-20T19:50:30.144Z" }, - { url = "https://files.pythonhosted.org/packages/a5/d6/580f9b2ab4c78d9fbf9d56c85fb7f7d4d22d667b27df8032ab9bf7140e37/aiohttp-3.14.2-cp311-cp311-win32.whl", hash = "sha256:b5ed2c7dacebf4950d6b4a1b22548e4d709bb15e0287e064a7cdb32ada65893a", size = 455968, upload-time = "2026-07-20T19:50:31.722Z" }, - { url = "https://files.pythonhosted.org/packages/96/76/33665ae48e24e01c6dfa15ed14d9d9eec1349577cef497f3b26210621f0a/aiohttp-3.14.2-cp311-cp311-win_amd64.whl", hash = "sha256:bf7951959a8e89f2d4a1e719e60d3ea4e8fc26f011ee3aed09598ad786b112f7", size = 480978, upload-time = "2026-07-20T19:50:33.299Z" }, - { url = "https://files.pythonhosted.org/packages/5e/19/00963031da42bd23716032f57b2a8414c5355eb1abc41805b2b41173040c/aiohttp-3.14.2-cp311-cp311-win_arm64.whl", hash = "sha256:c167127a3b6089ef78ac2e33582c38040d51688ee28474b5053acf55f192187b", size = 452900, upload-time = "2026-07-20T19:50:35.049Z" }, - { url = "https://files.pythonhosted.org/packages/e0/99/8737b10b6fa447371541a3b2cdbf9703c31ecf3afff4998f2f0633646a57/aiohttp-3.14.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:30e41662123806e4590a0440585122ac33c89a2465a8be81cc1b50656ca0e432", size = 754562, upload-time = "2026-07-20T19:50:36.672Z" }, - { url = "https://files.pythonhosted.org/packages/7c/e5/fd624b8b46d99dfd8f7f75111569b5ee21850539e914eed04ce39e4455ea/aiohttp-3.14.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dbc45e2773c66d14fbd337754e9bf23932beef539bd539716a721f5b5f372034", size = 509386, upload-time = "2026-07-20T19:50:38.268Z" }, - { url = "https://files.pythonhosted.org/packages/6d/a8/473db85d08b862724c506b51af2b9c6327e9e95cbd297c4c6f33968be1a8/aiohttp-3.14.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:476cf7fac10619ad6d08e1df0225d07b5a8d57c04963a171ad845d5a349d47ef", size = 511905, upload-time = "2026-07-20T19:50:39.862Z" }, - { url = "https://files.pythonhosted.org/packages/c1/e8/aa5ebff13ac5e39ffae8add143757e936d1c2ceb726b82786e5f5cb9912c/aiohttp-3.14.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40bedff39ea83185f3f98a41155dd9da28b365c432e5bd90e7be140bcef0b7f3", size = 1764968, upload-time = "2026-07-20T19:50:41.559Z" }, - { url = "https://files.pythonhosted.org/packages/f4/22/23ec6d3d3f24f5961c7be73d5127481c992d6c92ca213f336ed8f0ff1453/aiohttp-3.14.2-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a26f14006883fc7662e21041b4311eac1acbc977a5c43aacb27ff17f8a4c28b2", size = 1740635, upload-time = "2026-07-20T19:50:43.363Z" }, - { url = "https://files.pythonhosted.org/packages/a0/7b/f8966d2d08f0582525ef02d5af007d2d2467cb733abf1d1f7849a02a6b98/aiohttp-3.14.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:673217cbc9370ebf8cd048b0889d7cbe922b7bb48f4e4c02d31cfefa140bd946", size = 1810447, upload-time = "2026-07-20T19:50:45.258Z" }, - { url = "https://files.pythonhosted.org/packages/39/f5/239f2a828b033ac244237074db7b560ad3279bb1e934bb462dbde19f3877/aiohttp-3.14.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b39dbdbe30a44958d63f3f8baa2af68f24ec8a631dcd18a33dd76dfa2a0eb917", size = 1905896, upload-time = "2026-07-20T19:50:47.022Z" }, - { url = "https://files.pythonhosted.org/packages/6c/6e/fb84b8dafc521026355aadbeed484fc1ec44a05aae927de309f204c1f0af/aiohttp-3.14.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d15f618255fcbe5f54689403aa4c2a90b6f2e6ebc96b295b1cb0e868c1c12384", size = 1792052, upload-time = "2026-07-20T19:50:48.683Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c4/25b199009f164ee02599b9b0962d22e6533d212418e49df9f4fdb37fe2eb/aiohttp-3.14.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ae767b7dffd316cc2d0abf3e1f90132b4c1a2819a32d8bcb1ba749800ea6273", size = 1590939, upload-time = "2026-07-20T19:50:50.702Z" }, - { url = "https://files.pythonhosted.org/packages/ad/f5/96d7540a52620433db3822267008a1697fc816979c109a4f535855ac893c/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3ec4b6501a076b2f73844256da17d6b7acb15bb74ee0e908a67feb9412371166", size = 1725039, upload-time = "2026-07-20T19:50:52.506Z" }, - { url = "https://files.pythonhosted.org/packages/f6/50/1a06abbeec14a2bcb46124ca6e281ed4ccb3e9006542ded6bc89a0ce5224/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7e328d02fb46b9a8dbfa070d98967e8b7eaa1d9ee10ae03fb664bdf30d58ccf0", size = 1764748, upload-time = "2026-07-20T19:50:54.336Z" }, - { url = "https://files.pythonhosted.org/packages/70/5d/b8821b362306627ea8ca11fe49ec47cba18e7c75d975fa5f6710ad93845c/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c0c7f2e5fe10910d5ab76438f269cc41bb7e499fd48ded978e926360ab1790c8", size = 1777119, upload-time = "2026-07-20T19:50:56.306Z" }, - { url = "https://files.pythonhosted.org/packages/81/e5/805d9d49e66c6358574ad70dd731031585d18fe95ae65b857bc378bccc9a/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:66de80888db2176655f8df0b705b817f5ae3834e6566cc2caa89360871d90195", size = 1580047, upload-time = "2026-07-20T19:50:58.316Z" }, - { url = "https://files.pythonhosted.org/packages/c6/fa/1536f272d5ad93bf8b75043b02b94c24bf4e6b55a849d3287553ad6da97e/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f2f9950b2dd0fc896ab520ea2366b7df6484d3d164a65d5e9f28f7b0e5742d8a", size = 1796861, upload-time = "2026-07-20T19:51:00.373Z" }, - { url = "https://files.pythonhosted.org/packages/e6/f3/86dfd6152bb706351cf5c6b45f0f6a1818a4e559d1e88d899c4c673c23a8/aiohttp-3.14.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cc4435b16dc246c5dfa7f2f8ee71b10a30765018a090ee36e99f356b1e9b75cc", size = 1768687, upload-time = "2026-07-20T19:51:02.214Z" }, - { url = "https://files.pythonhosted.org/packages/57/af/14b98e07fcd1a2b37ebb2f950309821eaa56e0eac3d32fc23dc55227e49b/aiohttp-3.14.2-cp312-cp312-win32.whl", hash = "sha256:4ca802547f1128008addfc21b24959f5cbf30a8952d365e7daa078a0d884b242", size = 451437, upload-time = "2026-07-20T19:51:03.954Z" }, - { url = "https://files.pythonhosted.org/packages/38/20/8478c05702a369b6d0800e40e0c5f9a289ff482d0921faec1eb17727339d/aiohttp-3.14.2-cp312-cp312-win_amd64.whl", hash = "sha256:e5efff8bfd27c44ce1bfdf92ce838362d9316ed8b2ed2f89f581dbe0bbe05acf", size = 476776, upload-time = "2026-07-20T19:51:05.705Z" }, - { url = "https://files.pythonhosted.org/packages/d0/d0/e550bb1cb4fc82de3bdbe2add061cc0cedb34f2e7f01ada78fba94493ca1/aiohttp-3.14.2-cp312-cp312-win_arm64.whl", hash = "sha256:0eb1c9fd51f231ac8dc9d5824d5c2efc45337d429db0123fa9d4c20f570fdfc3", size = 447928, upload-time = "2026-07-20T19:51:07.523Z" }, - { url = "https://files.pythonhosted.org/packages/96/3a/8b8779f8e813d3a33cf16bc836a7ea7bf3c27b6588d42efa36b0c32fcb58/aiohttp-3.14.2-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:17eecd6ee9bfc8e31b6003137d74f349f0ac3797111a2df87e23acb4a7a912ea", size = 506205, upload-time = "2026-07-20T19:51:09.215Z" }, - { url = "https://files.pythonhosted.org/packages/d1/73/2f45204b37ecc4ce2c54b8b67254d70a8ea3b629c4083d58f3e2d27991cb/aiohttp-3.14.2-cp313-cp313-android_21_x86_64.whl", hash = "sha256:ce8dfb58f012f76258f29951d38935ac928b32ae24a480f30761f2ed5036fa78", size = 515116, upload-time = "2026-07-20T19:51:10.914Z" }, - { url = "https://files.pythonhosted.org/packages/f0/22/8f4424de1f50df4fbb74ea32006f9cff798ae0d346ffa6be7b6f0caca719/aiohttp-3.14.2-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:4181d72e0e6d1735c1fae56381193c6ae211d584d06413980c00775b9b2a176a", size = 486244, upload-time = "2026-07-20T19:51:12.878Z" }, - { url = "https://files.pythonhosted.org/packages/c2/53/60de022260f5d2d31976bc5f50db708e10671f0ac5da515402adcc6b4d4d/aiohttp-3.14.2-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:0e56babe35076f69ec9327833b71439eeccd10f51fe56c1a533da8f24923f014", size = 492260, upload-time = "2026-07-20T19:51:14.555Z" }, - { url = "https://files.pythonhosted.org/packages/b2/6f/d3ccc31c15cd33888670b8f1bf1dc06f3239b4edd156fc818078e87ae628/aiohttp-3.14.2-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6b63709e259e3b3d7922b235606564e91ed4c224e777cc0ca4cae04f5f559206", size = 502174, upload-time = "2026-07-20T19:51:16.3Z" }, - { url = "https://files.pythonhosted.org/packages/40/20/52d21e485652f4708015ce27dd3029e63140e0bdb0dcc7bf72dc0bc3f4ad/aiohttp-3.14.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f7c10c4d0b33888a68c192d883d1390d4596c116a59bf689e6d352c6739b7940", size = 750878, upload-time = "2026-07-20T19:51:18.013Z" }, - { url = "https://files.pythonhosted.org/packages/2e/49/1220bdc73d568431cc3856667405d78c2e95eb57fed2b9ffa5e825932ab2/aiohttp-3.14.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f7b19e27b78a3a927b1932af93af7645806153e8f541cee8fe856426142503f", size = 508459, upload-time = "2026-07-20T19:51:19.876Z" }, - { url = "https://files.pythonhosted.org/packages/ed/f1/39177406ce0ae5cb2782b35e848c0edf6e09d6e082df636eeacdbdfa70bd/aiohttp-3.14.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:18fcc3a5cc7dde1d8f7903e309055294c28894c9434588645817e374f3b83d03", size = 509179, upload-time = "2026-07-20T19:51:21.719Z" }, - { url = "https://files.pythonhosted.org/packages/87/f7/6d081c2ee838458492c7ae1062399bdd68f149811d257d4502e79a25b306/aiohttp-3.14.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09d1b0deec698d1198eb0b8f910dd9432d856985abbfea3f06be8b296a6619b4", size = 1761346, upload-time = "2026-07-20T19:51:23.437Z" }, - { url = "https://files.pythonhosted.org/packages/1d/ed/0befea4ae533f09c3a60f0d10b923cd4a90027a1bf49dfafaa24eeee08b8/aiohttp-3.14.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cabaaecb4c6888bd9abafac151051377534dad4c3859a386b6325f39d3732f99", size = 1735057, upload-time = "2026-07-20T19:51:25.512Z" }, - { url = "https://files.pythonhosted.org/packages/de/03/c1d89fcd94907f93a08d4aadbb4e1d9bd3d7d6c9f94bc9c17689de38107b/aiohttp-3.14.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:114299c08cce8ad4ebb21fafe766378864109e88ad8cf63cf6acb384ff844a57", size = 1800389, upload-time = "2026-07-20T19:51:27.585Z" }, - { url = "https://files.pythonhosted.org/packages/3a/8b/edbac4d1a1cde3571588a1e5b40637df5acee43158efdf3ae9a161fde8ab/aiohttp-3.14.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6bea8451e26cd67645d9b2ee18232e438ddfc36cea35feecb4537f2359fc7030", size = 1895342, upload-time = "2026-07-20T19:51:29.794Z" }, - { url = "https://files.pythonhosted.org/packages/0c/31/2e9ca3b21c07ea8a001e2b142cb01401fd34fd07b248a0b95a04c3ebc4ec/aiohttp-3.14.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:46b8887aa303075c1e5b24123f314a1a7bbfa03d0213dff8bb70503b2148c853", size = 1789175, upload-time = "2026-07-20T19:51:31.744Z" }, - { url = "https://files.pythonhosted.org/packages/6f/91/b57d3d13a80fbf765b19ae0c38d783a3a23f35b1cb82ae3b22f91abe6c24/aiohttp-3.14.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:de3b04a3f7b40ad7f1bcd3540dd447cf9bd93d57a49969bca522cbcf01290f08", size = 1586845, upload-time = "2026-07-20T19:51:33.571Z" }, - { url = "https://files.pythonhosted.org/packages/69/e8/a2f5f9f6219cd21190e9b50e2cbc978d12a2aab748d0aa7c6ee930db15c3/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:42372e1f1a8dca0dcd5daf922849004ec1120042d0e24f14c926f97d2275ca79", size = 1724839, upload-time = "2026-07-20T19:51:35.518Z" }, - { url = "https://files.pythonhosted.org/packages/de/d4/a2b9442336051714dd8dbd419b9f4a1003c45bb850ee0f3af87f2743e867/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7871c94f3400358530ac4906dd7a526c5a24099cd5c48f53ffc4b1cb5037d7d7", size = 1756306, upload-time = "2026-07-20T19:51:37.459Z" }, - { url = "https://files.pythonhosted.org/packages/ab/93/22c94a599b2c4ea6ab88f1b912d90883f1fba5235b587ea9f13b148e9a0f/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f8f371794319a8185e61e15ba5e1be8407b986ebce1ade11856c02d24e090577", size = 1769133, upload-time = "2026-07-20T19:51:39.9Z" }, - { url = "https://files.pythonhosted.org/packages/fe/db/a4e4c207f7023e83c281a7cf3579f227bade48f1899cb6588c0ed6ae54de/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:af63ac06bad85191e6a0c4a733cb3c55adb99f8105bc7ce9913391561159a49a", size = 1578671, upload-time = "2026-07-20T19:51:42.418Z" }, - { url = "https://files.pythonhosted.org/packages/8d/6f/33746ba4947b8193652fc7ed0533e09f93b118e39777228f3029e5677c17/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:8c2cdb684c153f377157e856257ee8535c75d8478343e4bb1e83ca73bdfa3d31", size = 1791778, upload-time = "2026-07-20T19:51:44.298Z" }, - { url = "https://files.pythonhosted.org/packages/06/41/323856cb0ec9076b1f9a135eb0684f5f984dd97989a087873768aa34ca2f/aiohttp-3.14.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ceff4f84c1d928654faa6bcb0437ed095b279baae2a35fcfe5a3cbe0d8b9725d", size = 1768490, upload-time = "2026-07-20T19:51:46.279Z" }, - { url = "https://files.pythonhosted.org/packages/39/f0/09e29e457b6fb49253cbb61354ed2541fdf23ac192bddbb57bb34bc93d9c/aiohttp-3.14.2-cp313-cp313-win32.whl", hash = "sha256:15292b08ce7dd45e268fce542228894b4735102e8ee77163bd665b35fc2b5598", size = 451064, upload-time = "2026-07-20T19:51:48.194Z" }, - { url = "https://files.pythonhosted.org/packages/0b/76/b44703eafcfe1446f4f975be1ef2406042955425eaf56450e71b50506c49/aiohttp-3.14.2-cp313-cp313-win_amd64.whl", hash = "sha256:fc2d8e7373ceba7e1c7e9dc00adac854c2701a6d443fd21d4af2e49342d727bd", size = 476140, upload-time = "2026-07-20T19:51:50.285Z" }, - { url = "https://files.pythonhosted.org/packages/72/48/b095935c9e72a253439f80ec757b91d4733e0a9a98b63e108d84aaf39b08/aiohttp-3.14.2-cp313-cp313-win_arm64.whl", hash = "sha256:70570f50bda5037b416db8fcba595cf808ecf0fdce12d64e850b5ae1db7f64d4", size = 447585, upload-time = "2026-07-20T19:51:52.333Z" }, - { url = "https://files.pythonhosted.org/packages/4f/ca/716f720dccc3032e40dc80d0ab2d87a7365270a714976a85bdff73bc7254/aiohttp-3.14.2-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:7719cef2a9dc5e10cd5f476ec1744b25c5ac4da733a9a687d91c42de7d4afe30", size = 508899, upload-time = "2026-07-20T19:51:54.165Z" }, - { url = "https://files.pythonhosted.org/packages/f5/80/786166589e71b3f3cfce56b414170fe5008462d0bff100bd8837285632f6/aiohttp-3.14.2-cp314-cp314-android_24_x86_64.whl", hash = "sha256:3523ec0cc524a413699f25ec8340f3da368484bc9d5f2a1bf87f233ac20599bf", size = 514722, upload-time = "2026-07-20T19:51:56.208Z" }, - { url = "https://files.pythonhosted.org/packages/eb/b7/539961cf3e3d3f179ea4b20d456cbdb67d1163c68f2e95bf220438a5afd5/aiohttp-3.14.2-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:c8ab295ee58332ef8fbd62727df90540836dfcf7a61f545d0f2771223b80bf25", size = 488082, upload-time = "2026-07-20T19:51:58.293Z" }, - { url = "https://files.pythonhosted.org/packages/60/34/c7708eac8edacca9c049a0d6f5fa610005ac3c5634c9ea4751134263bf4e/aiohttp-3.14.2-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:71501bc03ede681401269c569e6f9306c761c1c7d4296675e8e78dd07147070f", size = 494140, upload-time = "2026-07-20T19:52:00.158Z" }, - { url = "https://files.pythonhosted.org/packages/d8/e1/076b88de36b4ebea62d1c0b225e32bc8a452ee71b2aded82878fa5fa7c9e/aiohttp-3.14.2-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:052478c7d01035d805302db50c2ef626b1c1ba0fe2f6d4a22ae6eaeb43bf2316", size = 502670, upload-time = "2026-07-20T19:52:02.097Z" }, - { url = "https://files.pythonhosted.org/packages/a9/71/7b7720ffe7e521aaa79a853ebff4c17937f4b5a3a586e9d13b0f38050b35/aiohttp-3.14.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:b0d49be9d9a210b2c993bf32b1eda03f949f7bcda68fc4f718ae8085ae3fb4b8", size = 756406, upload-time = "2026-07-20T19:52:04.082Z" }, - { url = "https://files.pythonhosted.org/packages/b9/9a/c67c7e22fff7d7b17387e718451b30eb89f55df6b8d13d2d7f91daba6505/aiohttp-3.14.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:5fe25c4c44ea5b56fd4512e2065e09384987fc8cc98e41bc8749efe12f653abb", size = 510106, upload-time = "2026-07-20T19:52:06.001Z" }, - { url = "https://files.pythonhosted.org/packages/27/2a/3caebd640229663263585d4d31898331a3937752f2e1f5ec0af509fa31be/aiohttp-3.14.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7e254b0d636957174a03ca210289e867a62bb9502081e1b44a8c2bb1f6266ecd", size = 512876, upload-time = "2026-07-20T19:52:08.036Z" }, - { url = "https://files.pythonhosted.org/packages/27/04/86945210e491493f5cd025efe5e6d8fc8a9e8aaf36f943c40f52c34eda7e/aiohttp-3.14.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a6b0ce033d49dd3c6a2566b387e322a9f9029110d67902f0d64571c0fd4b73d8", size = 1750050, upload-time = "2026-07-20T19:52:09.998Z" }, - { url = "https://files.pythonhosted.org/packages/11/d8/356c62552b4db60af5ad8cddeafa6f837788918201f1b5f2466565c986b5/aiohttp-3.14.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41b5b66b1ac2c48b61e420691eb9741d17d9068f2bc23b5ee3e750faa564bc8f", size = 1707177, upload-time = "2026-07-20T19:52:12.39Z" }, - { url = "https://files.pythonhosted.org/packages/77/2d/41bb20bed3df1d6dc7fc231ca4ffb72177fd151bf4205a4ade7a93e03501/aiohttp-3.14.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:30a5ed81f752f182961237414a3cd0af209c0f74f06d66f66f9fcb8964f4978d", size = 1803795, upload-time = "2026-07-20T19:52:14.705Z" }, - { url = "https://files.pythonhosted.org/packages/63/21/ad9fe6786a1d2758bcfdae4dbc1d6869ffc7b1e0571530a508de3cdde09b/aiohttp-3.14.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1b9251f43d78ff675c0ddfcd53ba61abecc1f74eedc6287bb6657f6c6a033fe7", size = 1876539, upload-time = "2026-07-20T19:52:16.965Z" }, - { url = "https://files.pythonhosted.org/packages/0e/cb/d213f4fd7af279d82c4b46d30de22db93a01296d77a8d8e535289637da54/aiohttp-3.14.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf7930e83a12801b2e253d41cc8bf5553f61c0cfabef182a72ae13472cc81803", size = 1761130, upload-time = "2026-07-20T19:52:19.127Z" }, - { url = "https://files.pythonhosted.org/packages/46/4f/0792fe1a24c2b4b506d07350e980b0626c149fe73e68dd37dfb30ed89813/aiohttp-3.14.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:abb33120daba5e5643a757790ece44d638a5a11eb0598312e6e7ec2f1bd1a5a3", size = 1583576, upload-time = "2026-07-20T19:52:21.465Z" }, - { url = "https://files.pythonhosted.org/packages/46/ad/551c302f534f9cd6105bd16902e69dc64c726aa729127203f47ed4bddb2a/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:983a68048a48f35ed08aadfcc1ba55de9a121aa91be48a764965c9ec532b94b5", size = 1714139, upload-time = "2026-07-20T19:52:23.636Z" }, - { url = "https://files.pythonhosted.org/packages/e3/cf/a3be8601d2e80ccf7bd4f79807629cede5425d72c02636f06b1ad6a8290a/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:fef094bfc2f4e991a998af066fc6e3956a409ef799f5cbad2365175357181f2e", size = 1724352, upload-time = "2026-07-20T19:52:26.043Z" }, - { url = "https://files.pythonhosted.org/packages/c8/b1/6b55f6448b43a3338749f37fc6a14e7ac7dad121d2d585f22c1dd3d324fe/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2f7ca81d936d820ae479971a6b6214b1b867420b5b58e54a1e7157716a943754", size = 1770749, upload-time = "2026-07-20T19:52:28.467Z" }, - { url = "https://files.pythonhosted.org/packages/39/58/b3f1cf6af47fa0b0d51c6e2b98b2bf0326b44a932d74915f3c0874413ea8/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:da4f142fa078fedbdb3f88d0542ad9315656224e167502ae274cbba818b90c90", size = 1577547, upload-time = "2026-07-20T19:52:30.658Z" }, - { url = "https://files.pythonhosted.org/packages/d4/e2/1d79f1ab35593d70dabed98936ae842ac90d12847c9a62bba4a19d6005a4/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:3d4238e50a378f5ac69a1e0162715c676bd082dede2e5c4f67ca7fd0014cb09d", size = 1781840, upload-time = "2026-07-20T19:52:33.021Z" }, - { url = "https://files.pythonhosted.org/packages/01/73/770be856c6fc861563999081a5fe2d44e16b4255f5fd94b2217a2349ca65/aiohttp-3.14.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:03330676d8caa28bb33fa7104b0d542d9aac93350abcd91bf68e64abd531c320", size = 1745757, upload-time = "2026-07-20T19:52:35.541Z" }, - { url = "https://files.pythonhosted.org/packages/bc/0b/861fdbe3ff90b503a4d0a12276623f4afbe54c237ca876fc560125c270a3/aiohttp-3.14.2-cp314-cp314-win32.whl", hash = "sha256:43387429e4f2ec4047aaf9f935db003d4aa1268ea9021164877fd6b012b6396a", size = 455863, upload-time = "2026-07-20T19:52:37.634Z" }, - { url = "https://files.pythonhosted.org/packages/f7/03/cc8234d0f06fe4b0e1777c7ed313cc9014f078f72a9a0cbdc144965d1bd7/aiohttp-3.14.2-cp314-cp314-win_amd64.whl", hash = "sha256:e3a6302f47518dbf2ffd3cd518f02a1fbf53f85ffeed41a224fa4a6f6a62673b", size = 480986, upload-time = "2026-07-20T19:52:39.665Z" }, - { url = "https://files.pythonhosted.org/packages/2e/b0/ae17dd629e22160f453b9041a4aee80a8a917ba2f44d5b3e252cc501ed2c/aiohttp-3.14.2-cp314-cp314-win_arm64.whl", hash = "sha256:8d1f3802887f0e0dc07387a081dca3ad0b5758e32bdf5fb619b12ac22b8e9b56", size = 453588, upload-time = "2026-07-20T19:52:41.634Z" }, - { url = "https://files.pythonhosted.org/packages/30/54/4bbcc00f04dbc380103ee669a56df30dea127c3686c8dc2ab86b05a1387b/aiohttp-3.14.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:9094262ae4f2902c7291c14ba915960db5567276690ef9195cdefe8b7cbb3acb", size = 791337, upload-time = "2026-07-20T19:52:43.821Z" }, - { url = "https://files.pythonhosted.org/packages/e7/37/4f95edc1488580c63c0b5baaef429afbacadc7ccd9c47431cdcce90d9e5a/aiohttp-3.14.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:165b0dcc65960ffc9c99aa4ba1c3c76dbc7a34845c3c23a0bd3fbf33b3d12569", size = 526335, upload-time = "2026-07-20T19:52:45.903Z" }, - { url = "https://files.pythonhosted.org/packages/c3/ed/1d7ae73764d135638797a427cb637ae3d98f1fd61208c25891a9f26cdd67/aiohttp-3.14.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f518d75c03cd3f7f125eca1baadb56f8b94db94602278d2d0d19af6e177650a7", size = 532102, upload-time = "2026-07-20T19:52:47.994Z" }, - { url = "https://files.pythonhosted.org/packages/e3/12/da9816eee0d81506560259e7c0af93a4aa7df98acd0fe276958abd42d7c3/aiohttp-3.14.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b937d7864ca68f1e8a1c3a4eb2bac1de86a992f86d36492da10a135a482fab6", size = 1922727, upload-time = "2026-07-20T19:52:50.224Z" }, - { url = "https://files.pythonhosted.org/packages/2f/b9/d7ccbcde223a72c7b8f3458bdb08c2bacf5fc268a1fdd5cc29861eb0e4e2/aiohttp-3.14.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b155df7f572c73c6c4108b67be302c8639b96ae56fb02787eeae8cad0a1baf26", size = 1787202, upload-time = "2026-07-20T19:52:52.825Z" }, - { url = "https://files.pythonhosted.org/packages/c2/7c/39174069b7df18ea22b23a0fa9abffe4c091f0f86d53af83ddcbb5f44c8f/aiohttp-3.14.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0bfea68a48c8071d49aabdf5cd9a6939dcb246db65730e8dc76295fe02f7c73c", size = 1912574, upload-time = "2026-07-20T19:52:55.007Z" }, - { url = "https://files.pythonhosted.org/packages/21/ff/bd2b7473510caf352aef3f52a3d4fe10184ec22747df74ab658b4402020f/aiohttp-3.14.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8241ee6c7fff3ebb1e6b237bccc1d90b46d07c06cf978e9f2ecad43e29dac67a", size = 2005478, upload-time = "2026-07-20T19:52:57.401Z" }, - { url = "https://files.pythonhosted.org/packages/c8/ee/db26af0acc994350b653b3a73dddf9ee9886bf2fdb68b23fc98705e76442/aiohttp-3.14.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ec64d1c4605d689ed537ba1e572138e2d4ff603a0cb2bbbfe61d4552c73d19e1", size = 1879709, upload-time = "2026-07-20T19:52:59.778Z" }, - { url = "https://files.pythonhosted.org/packages/6a/4d/592451fd40edca73fcb099d8718668cea36dc1dde873dd0f8e91a4081051/aiohttp-3.14.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0fb26fcc5ebf765095fe0c6ab7501574d3108c57fca9a0d462be15a65c9deb8d", size = 1675699, upload-time = "2026-07-20T19:53:02.11Z" }, - { url = "https://files.pythonhosted.org/packages/2a/3e/c1ce4aa13fd1f910e437684843ea6cf6e0041f91d89a1b0389dce247ee59/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ef710fbb770aefa4def5484eeddb606e70ab3492aa37390def61b35652f6820a", size = 1843542, upload-time = "2026-07-20T19:53:04.385Z" }, - { url = "https://files.pythonhosted.org/packages/aa/a4/3f9e22fda714cc38ef558166ff3326cd2f6f65c33da92ba00e3641cbea54/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:d813f54560b9e5bce170fff7b0adde54d88253928e4add447c36792f27f92125", size = 1827505, upload-time = "2026-07-20T19:53:07.072Z" }, - { url = "https://files.pythonhosted.org/packages/37/9d/260c7b8a25c7cd74bee63ce957556a2d25839a321e9107a089d4da3a51af/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:1aa4f3b44563a88da4407cef8a13438e9e386967720a826a10a633493f69208f", size = 1853751, upload-time = "2026-07-20T19:53:10.012Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d6/7c3cfa191e666bf7b48b4346815900b35b85b43ffff783fd0be52e45fe09/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4610638d3135afaefadf179bffd1bbf3434d3dc7a5d0a4c4219b99fa976e944d", size = 1668850, upload-time = "2026-07-20T19:53:12.362Z" }, - { url = "https://files.pythonhosted.org/packages/c4/af/d9b8353aee9506dace04ca22c3c4e93b7375d9343c4780c8b512972fc6f9/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:6e30743bd3ab6ad98e9abbad6ccb39c52bcf6f11f9e3d4b6df97afffe8df53f3", size = 1883642, upload-time = "2026-07-20T19:53:14.664Z" }, - { url = "https://files.pythonhosted.org/packages/ed/29/ed64c0a013322570a02e5b0e359df2cfd30ae58ba045748dc78175f15826/aiohttp-3.14.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:68a6f7cd8d2c70869a2a5fe97a16e86a4e13a6ed6f0d9e6029aef7573e344cd6", size = 1844092, upload-time = "2026-07-20T19:53:16.995Z" }, - { url = "https://files.pythonhosted.org/packages/3c/74/ce6f229510fdd46ee7365fbb759ffaa3004e0bcc59fbd0ec51d8a8efc775/aiohttp-3.14.2-cp314-cp314t-win32.whl", hash = "sha256:205181d896f73436ac60cf6644e545544c759ab1c3ec8c34cc1e044689611361", size = 474098, upload-time = "2026-07-20T19:53:19.645Z" }, - { url = "https://files.pythonhosted.org/packages/72/4c/877c07a6d97a1a0e5e25a06bab76dd7449b533ff8bb6c281c5af8b09c8d9/aiohttp-3.14.2-cp314-cp314t-win_amd64.whl", hash = "sha256:312d414c294a1e26aa12888e8fd37cd2e1131e9c48ddcf2a4c6b590290d52a49", size = 500480, upload-time = "2026-07-20T19:53:22.227Z" }, - { url = "https://files.pythonhosted.org/packages/42/d8/d4c74bb7990da2ee6116fe262ace41cf376ebc6b0bda694c77eeaab5a509/aiohttp-3.14.2-cp314-cp314t-win_arm64.whl", hash = "sha256:63b840c03979732ec92e570f0bd6beb6311e2b5d19cacbfcd8cc7f6dd2693900", size = 469248, upload-time = "2026-07-20T19:53:24.622Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", size = 765848, upload-time = "2026-07-23T01:52:08.217Z" }, + { url = "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", size = 517476, upload-time = "2026-07-23T01:52:10.846Z" }, + { url = "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", size = 515334, upload-time = "2026-07-23T01:52:12.636Z" }, + { url = "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", size = 1708830, upload-time = "2026-07-23T01:52:14.538Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", size = 1674012, upload-time = "2026-07-23T01:52:16.486Z" }, + { url = "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", size = 1767015, upload-time = "2026-07-23T01:52:18.28Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", size = 1858700, upload-time = "2026-07-23T01:52:20.08Z" }, + { url = "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", size = 1714075, upload-time = "2026-07-23T01:52:22.071Z" }, + { url = "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", size = 1588234, upload-time = "2026-07-23T01:52:23.757Z" }, + { url = "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", size = 1677300, upload-time = "2026-07-23T01:52:25.861Z" }, + { url = "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", size = 1691501, upload-time = "2026-07-23T01:52:28Z" }, + { url = "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", size = 1735113, upload-time = "2026-07-23T01:52:29.995Z" }, + { url = "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", size = 1577486, upload-time = "2026-07-23T01:52:31.937Z" }, + { url = "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", size = 1751353, upload-time = "2026-07-23T01:52:33.688Z" }, + { url = "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", size = 1698681, upload-time = "2026-07-23T01:52:38.167Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", size = 456733, upload-time = "2026-07-23T01:52:41.823Z" }, + { url = "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", size = 480460, upload-time = "2026-07-23T01:52:43.905Z" }, + { url = "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", size = 453479, upload-time = "2026-07-23T01:52:46.075Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, + { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, + { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, + { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, + { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, + { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, + { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, + { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, + { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, + { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, + { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, + { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, + { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, + { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, + { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, + { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, + { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, + { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, + { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, + { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, + { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, + { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, + { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, + { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, + { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, + { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, + { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, + { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, + { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, + { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, + { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, + { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, + { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, + { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, + { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, + { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, + { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, + { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, + { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, + { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, + { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, + { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, + { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, + { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, + { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, + { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, + { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, + { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, + { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, + { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, + { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, + { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, + { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, + { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, + { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, + { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, + { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, + { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, + { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, + { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, + { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, + { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, + { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, + { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, + { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, + { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, + { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, + { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, + { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, + { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, + { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, + { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, + { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, + { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, + { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, + { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, + { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, + { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, + { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, + { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, + { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, + { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, + { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, + { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, ] [[package]] @@ -191,20 +200,20 @@ wheels = [ [[package]] name = "annotated-doc" -version = "0.0.4" +version = "0.0.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/8e/38aa427ed5402449e226975b649c5dc73ccadfefeb95e6aecb8f8ea4b6b6/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb", size = 10758, upload-time = "2026-07-28T13:50:58.129Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, + { url = "https://files.pythonhosted.org/packages/3e/30/e900b21425a860e195f32e37657aa1f7c7f2b1bfb26f03ca209b90933c06/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101", size = 5302, upload-time = "2026-07-28T13:50:57.239Z" }, ] [[package]] name = "annotated-types" -version = "0.7.0" +version = "0.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5f/56/a8120250d128bed162cd73c76d45f6ef9991f3e068f62a8ee060afa3104a/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7", size = 15893, upload-time = "2026-07-23T20:16:13.995Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, + { url = "https://files.pythonhosted.org/packages/99/91/8acff4f5e50511b911bbccb72b8628a49c68ce14148cd9f6431094859a90/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0", size = 13427, upload-time = "2026-07-23T20:16:12.938Z" }, ] [[package]] @@ -402,11 +411,11 @@ wheels = [ [[package]] name = "certifi" -version = "2026.6.17" +version = "2026.7.22" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", size = 138112, upload-time = "2026-07-22T03:35:12.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" }, + { url = "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", size = 136983, upload-time = "2026-07-22T03:35:11.276Z" }, ] [[package]] @@ -816,9 +825,18 @@ name = "docutils" version = "0.22.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15'", - "python_full_version >= '3.12' and python_full_version < '3.15'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } wheels = [ @@ -827,18 +845,19 @@ wheels = [ [[package]] name = "eido" -version = "0.2.5" +version = "0.2.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonschema" }, { name = "logmuse" }, - { name = "pandas" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "peppy" }, { name = "ubiquerg" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/4a/97c650e694b8a1571d749eb809d4b1850d73524a2148b71ef09b636783cd/eido-0.2.5.tar.gz", hash = "sha256:38c21e8678a4e37e2b0680225dd4cabe68482b5156c252199838faa06d7adf47", size = 16603, upload-time = "2026-02-03T21:05:49.598Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/23/f1e0460ef91c15435e2f41dcd8642d3c17715a8b4ecdd85fc81cce8a4386/eido-0.2.6.tar.gz", hash = "sha256:068a548adc07c9e244a7768fcb06940e484075f89ce0dd06e1167f2b8f9c44f4", size = 16974, upload-time = "2026-07-23T02:09:21.433Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/f6/54de5d115447a5c2d98a12c9adcf43452a58efe076003bdac459fce76f07/eido-0.2.5-py3-none-any.whl", hash = "sha256:2d14b4923c52bc3554c7d016c0f638fdd61a8e083c3917f44988e2e598c58491", size = 16910, upload-time = "2026-02-03T21:05:47.516Z" }, + { url = "https://files.pythonhosted.org/packages/99/2a/32b5bee9a4a521e6571cbc7bec028809ce3e2151c62f28d51fcf060ded5c/eido-0.2.6-py3-none-any.whl", hash = "sha256:2cafb1896a2cb234a9c2cb0a4332622a5c814901651c64ca5d2473f6ea7d44c3", size = 17003, upload-time = "2026-07-23T02:09:20.193Z" }, ] [[package]] @@ -1006,14 +1025,14 @@ wheels = [ [[package]] name = "gitpython" -version = "3.1.53" +version = "3.1.57" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gitdb" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/24/0e0c12cb6f7cb864779a9d2fefee9ca91838f6db402c8780c9d28a8d7ebe/gitpython-3.1.53.tar.gz", hash = "sha256:06ae8d9623b0ed0d67b8adeac5c7008d0a5a404b087a9e0d0c7163bdd3a6b497", size = 224597, upload-time = "2026-07-20T13:41:52.839Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/0d/132ed135c871b6bf91adf16a0e43797cd535b81d4973b5d09291c54fc5ee/gitpython-3.1.57.tar.gz", hash = "sha256:c493ec57c0ef6b19743798b6a5af859c71814b524e7e6f97baa2f8e658961488", size = 225898, upload-time = "2026-07-26T07:33:26.351Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/a6/bff12b3238885eeef7d28ef908b24e0cba91c476c31cb876a00a0986ce2c/gitpython-3.1.53-py3-none-any.whl", hash = "sha256:187885556b64ab357bd4ea84e2c4cce2861a613a7f4268b3f7f7ba05f2ce4ab0", size = 216237, upload-time = "2026-07-20T13:41:51.473Z" }, + { url = "https://files.pythonhosted.org/packages/41/6e/2139de986d9c7c3ac86f1f8be43858ce90bdfe2f7175e6c80c650ba15242/gitpython-3.1.57-py3-none-any.whl", hash = "sha256:4ccf7d73c10f5c9e76043fbb2675ac5a1b3ff5b41e648f56bcbed5f63792ecaf", size = 217151, upload-time = "2026-07-26T07:33:24.838Z" }, ] [[package]] @@ -1287,9 +1306,18 @@ name = "markdown-it-py" version = "4.2.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15'", - "python_full_version >= '3.12' and python_full_version < '3.15'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "mdurl" }, @@ -1716,9 +1744,18 @@ name = "myst-parser" version = "5.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15'", - "python_full_version >= '3.12' and python_full_version < '3.15'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } }, @@ -1736,7 +1773,7 @@ wheels = [ [[package]] name = "nf-core" -version = "4.1.0.dev0" +version = "4.1.0" source = { editable = "." } dependencies = [ { name = "click" }, @@ -1926,7 +1963,9 @@ name = "numpy" version = "2.4.6" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version == '3.11.*'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } wheels = [ @@ -2008,8 +2047,15 @@ name = "numpy" version = "2.5.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15'", - "python_full_version >= '3.12' and python_full_version < '3.15'", + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] sdist = { url = "https://files.pythonhosted.org/packages/22/fd/89965aa4ac08c74998539fcbf24fa3540f3e15237fbeb6bcf9c908f4aade/numpy-2.5.1.tar.gz", hash = "sha256:a48a113e6afea91f5608793bafa7ef2ad481fefbda87ec5069f483de61cb9fa3", size = 20755553, upload-time = "2026-07-04T17:08:00.933Z" } wheels = [ @@ -2071,10 +2117,11 @@ wheels = [ name = "pandas" version = "2.3.3" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] dependencies = [ - { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, - { name = "numpy", version = "2.5.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" } }, { name = "python-dateutil" }, { name = "pytz" }, { name = "tzdata" }, @@ -2130,6 +2177,75 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, ] +[[package]] +name = "pandas" +version = "3.0.5" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, + { name = "numpy", version = "2.5.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "python-dateutil" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/4f/5f3422a2afec5ffc46308b79e53291365a93748b498ac2e58bead0197916/pandas-3.0.5.tar.gz", hash = "sha256:dca3734d6ab7c906e6730f0788b0a1dbb9f2467731f9711f77995c8e9d62d712", size = 4658219, upload-time = "2026-07-22T22:19:28.819Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/ef/f1fd7431d635bf20015489bf0bd69c17fff1018de773540f651455a3916b/pandas-3.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2946e77e4a53cd248cbde631a12f0e51c8324ce354c3eba4d20147c1ad6f4282", size = 10397178, upload-time = "2026-07-22T22:17:48.274Z" }, + { url = "https://files.pythonhosted.org/packages/31/b4/0eafac990a431561187694126de01f9b12559549b4d86360c0c4bd870fde/pandas-3.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71ecc8fb7ed1a7aa4392316b5309a6347e8e7f832f38fd897846b3a1457a9298", size = 9990736, upload-time = "2026-07-22T22:17:52.388Z" }, + { url = "https://files.pythonhosted.org/packages/de/21/359880af3ea9b7cb23bea5b51e8e70ef3866c03be09da9a2787e18e330a8/pandas-3.0.5-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b173f5951ff6b8b0ec7675e20dff3c97b7e7a57dfcce387c2d7c5afe87cb7899", size = 10814438, upload-time = "2026-07-22T22:17:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/d1/50/d6cc4d7e508bbccf5d6027314a8312bc7ac73d0ec7f195f53838daafab40/pandas-3.0.5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c0cf1dd9b55a22d105fc46c1b489af3bd42264fcba7c66297bf47a9a1d9c78a", size = 11323634, upload-time = "2026-07-22T22:17:56.858Z" }, + { url = "https://files.pythonhosted.org/packages/70/2b/d5f0a8c90dd0ae04e64ba53b871afb796ec026b615086d382ddc2ade729b/pandas-3.0.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0fac0010c75e4efb6b99e249c183a8993ce0dc95c240f9b120a5e67c727b7928", size = 11850860, upload-time = "2026-07-22T22:17:59.1Z" }, + { url = "https://files.pythonhosted.org/packages/5c/30/183aec2e19adf778a98d29b5729a0a68f4cc4ebf9b9c3b70d0297355bcb1/pandas-3.0.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:08d24fe11a17dc33bd6e937dc9c665f9cba08fbdc9f657f405713515febe300d", size = 12411100, upload-time = "2026-07-22T22:18:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/fa/9a/31f4983f191af51ab2a8f2d0c7b33dff3a84da26533f982fff02c2f9e28b/pandas-3.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b1261758dfb6cf12c3cff8300e21cefad30e7ec709abb4c24ac7318e6a52462a", size = 9968804, upload-time = "2026-07-22T22:18:03.903Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/7886c89a39045c69ad82cbceaf3343810480c8ef49a216319ce8183860a6/pandas-3.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:679f4e85b30ddb1515458ab1e788d3e260eae369b1f78da7a3aa4cac8ebf4a2a", size = 9205447, upload-time = "2026-07-22T22:18:06.134Z" }, + { url = "https://files.pythonhosted.org/packages/1c/54/1dc810ea558d1320b597aa140a514f2fdf1d2ea09c38cf556f13ea712ec9/pandas-3.0.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa290c16964d4963fbfbc358928239cf3bd755b20e988ce944877def2f44471d", size = 10411717, upload-time = "2026-07-22T22:18:08.307Z" }, + { url = "https://files.pythonhosted.org/packages/68/56/fbe81c09195924d8b7b8d4461a20458fe80a6a5ed6b24f0314da684277e1/pandas-3.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2e26bb46934b8a2ca0c3de1d3d606fc5f6746584791b2db264d58cf370e08dc", size = 9957095, upload-time = "2026-07-22T22:18:10.6Z" }, + { url = "https://files.pythonhosted.org/packages/e0/51/fac252f4a913ed5eabf3c11b880a9e8d5a6c10f0b2129d0462212d238b4d/pandas-3.0.5-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73fa87b08a7ef706f8aafda39ddaccf2a99047bea62d8c88a0361bcafb2237bc", size = 10485458, upload-time = "2026-07-22T22:18:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/12/98/e976540c1addf70442be7842a18cf70884a964abbf69442504f4d2939989/pandas-3.0.5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d373ce03ffd84010ed9839fa73672a9c8256990532e158440c0085db7d914b34", size = 10998091, upload-time = "2026-07-22T22:18:15.209Z" }, + { url = "https://files.pythonhosted.org/packages/a4/8c/1f29b5be8d3fc47dd7567eb167fabba2085879b31e0287ce7cba6d3d2ff4/pandas-3.0.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2a29c53d85ea98c5e792c59ef82ee9fbe6ca902c0d0adb6b23f45ef894cd7bf6", size = 11499501, upload-time = "2026-07-22T22:18:17.689Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e2/bd9c98ad2df7b38bde002adde4cdf353519da51881634323b126c55997f9/pandas-3.0.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5ad3b02ed6bc7d7ae9b70804b2c6aa31827489d150f8e623ce82491b82085d7", size = 12060559, upload-time = "2026-07-22T22:18:20.147Z" }, + { url = "https://files.pythonhosted.org/packages/f3/9a/ffbd852d58bd74a617fe2f8ee6a58a96982271ce41cf981eab22190b4a4b/pandas-3.0.5-cp312-cp312-pyemscripten_2024_0_wasm32.whl", hash = "sha256:b2acb4650527eec6822c3dadb2b771277b65e7dae7a267d4bccf65fd1bb3fbce", size = 7197652, upload-time = "2026-07-22T22:18:22.502Z" }, + { url = "https://files.pythonhosted.org/packages/70/b5/d2d3e9ae73362ba4229651b0ee1455cf78073a1ce585f6ff693782ce263e/pandas-3.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:80a611068e8a3ac23f7398c6c14eb46dc974e5cc9997f653e2dcfd1da74edd41", size = 9831691, upload-time = "2026-07-22T22:18:24.534Z" }, + { url = "https://files.pythonhosted.org/packages/52/51/dea1e89d6a6796b9c43f85a09b484ee03edb8a4c4842e73e200a8c11301c/pandas-3.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:25ff585b972a18ef1fe9ffa3ac6544d9950508aa76832e5147640b6022821e49", size = 9105796, upload-time = "2026-07-22T22:18:27.064Z" }, + { url = "https://files.pythonhosted.org/packages/bf/09/7b95c4a0025227d6f118c4039b423412ac6a982db02864166185d812fbc7/pandas-3.0.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c1c05a767fe8e5b4fe9e1c29806829c582052eaedb9120a3da83ba3f69e24a5b", size = 10385742, upload-time = "2026-07-22T22:18:29.346Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0c/dc78fd8c4da477b4b5e8ad37295af352190d21ef63a9ee1bc071753074cc/pandas-3.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b86765f268b56f7e665b93bce9d5df69dee7f99e595cf8fb839483ab315942a3", size = 9932067, upload-time = "2026-07-22T22:18:31.833Z" }, + { url = "https://files.pythonhosted.org/packages/3e/71/3592c055cf44df9808550f9368ceda80ff2b224d355ef73fe251dcda1802/pandas-3.0.5-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c597ecf5616b5c420372c1d4d4c00dbbfba7398bea857dcc984347e1ea48417b", size = 10466756, upload-time = "2026-07-22T22:18:34.195Z" }, + { url = "https://files.pythonhosted.org/packages/e3/70/4363150359f95b4cb4bcbb34ca23572bb5495749a621a8f3d5a1ddfd293c/pandas-3.0.5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b11c36e218331d0387cbe3a0a5f75162357a1d92d57b2b08a336ff94b19b2be", size = 10938525, upload-time = "2026-07-22T22:18:36.81Z" }, + { url = "https://files.pythonhosted.org/packages/f7/d0/317e7a0c67c0e69fa905a0161409397a7dc2d46ff611f6ca4803352c042b/pandas-3.0.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cf52e1f61d229496da17dc7ab54acdee627357e7008fd4fecba3d0ba2937fa58", size = 11489303, upload-time = "2026-07-22T22:18:39.287Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8d/36dade89b49e4f9d5cbdbe863772581f98c0c6d78fc39ad4c557f6f2e17e/pandas-3.0.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:db172144bb56422bd157812f3b021eacc255451470b31e2c633c349490a1cfee", size = 11989004, upload-time = "2026-07-22T22:18:42.208Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ba/18c4ec8a746e177da05a9e7a7963781d8ea195780724f854601b6ebd6b78/pandas-3.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:0d298e951f23016ce4699951d044ae6418dbc91bf68cefca0f77666fcbb4e5c6", size = 9826896, upload-time = "2026-07-22T22:18:44.539Z" }, + { url = "https://files.pythonhosted.org/packages/de/ec/28a57266b753799a87b8bc79e7887ac6fd981b8c6d2978a0b7e7b6bd708c/pandas-3.0.5-cp313-cp313-win_arm64.whl", hash = "sha256:66266d3442a5e8b3c90274c2b8b230bee42dd1c286bc822cc2f9f2c7e12b883e", size = 9094790, upload-time = "2026-07-22T22:18:47.468Z" }, + { url = "https://files.pythonhosted.org/packages/51/2f/cf6aae281264f4463f0875bcbb15fd2bb6d291cc535187dad1732475e4a9/pandas-3.0.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2f264fc46911cc8131a7322a16199bbf8e353d27c10bb211f5bd0c814324dc36", size = 10390034, upload-time = "2026-07-22T22:18:49.818Z" }, + { url = "https://files.pythonhosted.org/packages/06/ec/5189518c7a7659c4bdcc6b1eb32c46c6f3c86b0661ffd84143d1112c7732/pandas-3.0.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:53730687fcd161883b24e10411c06d6a4c0f2275d2faf3bb2bc25deb4ba8007c", size = 9980065, upload-time = "2026-07-22T22:18:52.249Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f1/598503ce8d7e3c35601e0747ba288c7864baae66380725bc12f13f884dfe/pandas-3.0.5-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:960d3ebcf249f75206899fcd2c6de53f736b7265759ced0d3e559df0b8b709b0", size = 10545532, upload-time = "2026-07-22T22:18:54.813Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/ceae2adf7034e07e9910299fe412e1819c4f0dd520700a888bcb03625448/pandas-3.0.5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e94c2c5ca43bd3ca32bf64d32308887b65e5f9bfd8023ea52755107a999f93b", size = 10963120, upload-time = "2026-07-22T22:18:57.42Z" }, + { url = "https://files.pythonhosted.org/packages/66/25/86e0f4451874eb79e688deeebe3c451fec4557f8952005818d800ee8ac7e/pandas-3.0.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e819dd5f62966b481a8cb649d3299ebd886a1ea91ed5a99bf7ce77c98d18ab94", size = 11563178, upload-time = "2026-07-22T22:18:59.729Z" }, + { url = "https://files.pythonhosted.org/packages/f3/45/8643daa3b4147e433adfcccefdd0380d3aad79d86b15d8999730fe1944d5/pandas-3.0.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3c5ed2e7c06e91d340dfd091d7934f9bc82e4a36b95f647f090b9d1c9ac649da", size = 12028708, upload-time = "2026-07-22T22:19:02.164Z" }, + { url = "https://files.pythonhosted.org/packages/96/58/ad979ae617615576e8aafd569c9d4b62f1191d896e38f51d66ba06f3b89a/pandas-3.0.5-cp314-cp314-win_amd64.whl", hash = "sha256:cd8f7c6dc98527058ee6264219343f5392240a6f1bfa654fc5d79023020d0c92", size = 9951806, upload-time = "2026-07-22T22:19:04.596Z" }, + { url = "https://files.pythonhosted.org/packages/69/32/7ac03886b304049a9d2625ee88f59af760d8a93bd30ed9239bce7b9869a8/pandas-3.0.5-cp314-cp314-win_arm64.whl", hash = "sha256:5183427f5a8156d480f30333777bc978be93650a49a7c01db26adffe95b31e85", size = 9238297, upload-time = "2026-07-22T22:19:06.836Z" }, + { url = "https://files.pythonhosted.org/packages/be/ed/1d1f2ee5547d5167face2376d11c8b2a4c7bfff5a416ee7a9046891fab1e/pandas-3.0.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:303da736987d481074ca720ada325f8bd80c64ebc2d45ed79b29df3aaa4a26ca", size = 10849690, upload-time = "2026-07-22T22:19:09.391Z" }, + { url = "https://files.pythonhosted.org/packages/57/55/17e17152e98fbb0c4b1e562bc65387a2f20a80db0f4a86bf8d3a0e4248d4/pandas-3.0.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3b2801bbb049d0136f6c213eae02b5fca969384fc2064dd728d8620552aa49da", size = 10509945, upload-time = "2026-07-22T22:19:11.773Z" }, + { url = "https://files.pythonhosted.org/packages/88/90/817d44dbf83facf9556f33576d9af0a241981e7bb5c00606c0bcb5df8dda/pandas-3.0.5-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cce3a9d11d2b1f82c69a27ec1f4948a170e2c403c4bbfa8cca62e3fdebe2ef3a", size = 10392197, upload-time = "2026-07-22T22:19:14.024Z" }, + { url = "https://files.pythonhosted.org/packages/f1/da/889f00c0a6f5aa1545add70abbf01502dff87ab577adb855bd631c54d2f2/pandas-3.0.5-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef01af4d8dc6cd2c8d6c7736f149574ef93fe043811eeb5e445f2647154b5040", size = 10862726, upload-time = "2026-07-22T22:19:16.351Z" }, + { url = "https://files.pythonhosted.org/packages/bc/98/f1e934fb3c98fce859c6147c6785816c7b5b9ab7821115c5d8c4de9842b9/pandas-3.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e2759e890db96dfcffdbd9b86c3c2cb6afaf58def482820317e06163ec1066cd", size = 11414864, upload-time = "2026-07-22T22:19:18.981Z" }, + { url = "https://files.pythonhosted.org/packages/fe/be/d448af7d657d82e1888dd8551f79c6d6fb161080b5b9752d84d910ec2319/pandas-3.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b58b1b39d46a5862e3fb18f50d1a201398619d16a0f9f73f57eea5583cf0e63c", size = 11925105, upload-time = "2026-07-22T22:19:21.515Z" }, + { url = "https://files.pythonhosted.org/packages/29/c1/ccb4238212c8c4f496c584f3044d94e0c030ed8e1d68999db46c91c2242f/pandas-3.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:1c10461f6eeb35d8f05b6184c65c8b9991663b66c46b1d559b682cb34ae7c6ea", size = 10387612, upload-time = "2026-07-22T22:19:24.257Z" }, + { url = "https://files.pythonhosted.org/packages/d2/cf/6a51b2c38980e04c279fd2fa908a1b0982064e860444acfca4ec2e2c8359/pandas-3.0.5-cp314-cp314t-win_arm64.whl", hash = "sha256:3c5015fd1730fbf883647e88068176c839c102cea883ba1769a6f4593bfc1f8c", size = 9509776, upload-time = "2026-07-22T22:19:26.694Z" }, +] + [[package]] name = "pathspec" version = "1.1.1" @@ -2157,7 +2273,8 @@ version = "0.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coloredlogs" }, - { name = "pandas" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "peppy" }, { name = "pydantic" }, { name = "requests" }, @@ -2177,7 +2294,8 @@ dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "numpy", version = "2.4.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" }, { name = "numpy", version = "2.5.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, - { name = "pandas" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pephubclient" }, { name = "pyyaml" }, { name = "rich" }, @@ -2318,11 +2436,11 @@ wheels = [ [[package]] name = "platformdirs" -version = "4.10.1" +version = "4.11.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/cd/4f25b2f95b23f5d2c9c1fe43e49841bff5800562149b2666afc09309aa8f/platformdirs-4.10.1.tar.gz", hash = "sha256:ceab4084426fe6319ce18e86deada8ab1b7487c7aee7040c55e277c9ae793695", size = 31678, upload-time = "2026-07-18T03:53:43.808Z" } +sdist = { url = "https://files.pythonhosted.org/packages/78/9b/560e4be8e26f6fd133a03630a8df0c663b9e8d61b4ade152b72005aec83b/platformdirs-4.11.0.tar.gz", hash = "sha256:0555d18370482847566ffabcaa53ad7c6c1c29f195989ae1ed634a05f76ea1e0", size = 31953, upload-time = "2026-07-21T13:09:36.565Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/73/6fd0bb9ce84138c3857f12e9de63bc901852975a092d545f18087a204aa2/platformdirs-4.10.1-py3-none-any.whl", hash = "sha256:0e4eff26be2d75293977f7cddc153fd9b8eaa7fb0c7b64ffe4076cb443117443", size = 22906, upload-time = "2026-07-18T03:53:42.576Z" }, + { url = "https://files.pythonhosted.org/packages/7d/68/d8d58938dfb1370b266a1a729e6d77a985be23689a0496498ee17b2cbf90/platformdirs-4.11.0-py3-none-any.whl", hash = "sha256:360ccded2b7fce0af0ff80cc8f5942a1c5d99b0e856033acb030bfc634709e74", size = 23247, upload-time = "2026-07-21T13:09:35.422Z" }, ] [[package]] @@ -2345,26 +2463,26 @@ wheels = [ [[package]] name = "prek" -version = "0.4.10" +version = "0.4.11" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/54/edc21e275f9fa3540d4d98cf349c2de11621d6729cc401bb7aedf563609e/prek-0.4.10.tar.gz", hash = "sha256:db3122f4e780eb4587635e6a83df881caf2dbb1eb7799d1cca51158216d6f33b", size = 502565, upload-time = "2026-07-16T10:13:00.788Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/1a/73b6dae5ce7e997cb35a69bfe1d25a798e85fa3d2eabf95324563f461b30/prek-0.4.11.tar.gz", hash = "sha256:4a14cb9bbae850605ae3904fbdbb12f0e00c12455efaa2266da8fb8e5c0350d7", size = 516254, upload-time = "2026-07-24T17:05:35.107Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/e7/5a63528ba7b95b64f38db3e253aed49ee8e5e8ba16589889d2b7f809edb7/prek-0.4.10-py3-none-linux_armv6l.whl", hash = "sha256:023f302741d79301346c3088ba43a9592aff0ecdbe5ddc3019fa9b1183319c5e", size = 5694609, upload-time = "2026-07-16T10:12:26.352Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ef/ee9e6bf9a5ce242e9e4e66ac4e2e9042a0f6fd9f367cee18ad404456e93d/prek-0.4.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:72adc707e16f97564bbae08d22b222ac3bb2491f8fbfb5a0754f80d472c28a71", size = 6044037, upload-time = "2026-07-16T10:12:28.539Z" }, - { url = "https://files.pythonhosted.org/packages/68/7e/da08cc39e5348ccb9234e63a21ee56861f72e8497d6a78f0db1ccae6515d/prek-0.4.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:04c9321957e1b32e1fc7cf60bb4f90bba3761f8659d5551ed04f96e25596de49", size = 5535983, upload-time = "2026-07-16T10:12:30.691Z" }, - { url = "https://files.pythonhosted.org/packages/30/c6/0486a35bb687a9beac7a5810bd1104c6da56d469b30b1eeaeefd03c99da2/prek-0.4.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:e66ccf6c5e4ebadd05cd98cb338d7f553e4d27aa243cf91279c5a569b3cdccc7", size = 5862085, upload-time = "2026-07-16T10:12:33.042Z" }, - { url = "https://files.pythonhosted.org/packages/52/39/277fe17ae1f121e532e3942456f5a6d01ddacfbc550e481dcb359be7a1b0/prek-0.4.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63f9061d75a50ef0ca92c4b596ad352937a845df80758244950e513b27e9e18f", size = 5605697, upload-time = "2026-07-16T10:12:35.498Z" }, - { url = "https://files.pythonhosted.org/packages/ad/a1/08354af3e000f2656fad086690d834eab6c04631ff41313a219ea6232199/prek-0.4.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c2ff7110e4bfaafbbab13c2893a337081aca61ed797f14b6b224d2ea9741eef", size = 6034111, upload-time = "2026-07-16T10:12:37.545Z" }, - { url = "https://files.pythonhosted.org/packages/e4/74/4702396c8d486132e5ce009ab56a0b37f50cb6866830d371f2617b7bdfdc/prek-0.4.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b696a05542e79aa27bcce68d1792e77f4fe6f9c6b012b34d74d62f964f3c72d", size = 6787203, upload-time = "2026-07-16T10:12:40.031Z" }, - { url = "https://files.pythonhosted.org/packages/90/29/b5d5d6fb87ebd64b37471e3e79761de9983f85e14d69c522efe7af6620ce/prek-0.4.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:431b44d6054e72815b4b05e1173596dfd02a7f7461211d40a2e3117e414642ad", size = 6261333, upload-time = "2026-07-16T10:12:42.216Z" }, - { url = "https://files.pythonhosted.org/packages/94/d6/54ba696d19f7efdc184093353cce713a850aef9c3556e23faeecafa22e94/prek-0.4.10-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:ccbd2b4fd1df790087ba18b4506f680471922a5f13714f19801568434a040dee", size = 5867761, upload-time = "2026-07-16T10:12:44.329Z" }, - { url = "https://files.pythonhosted.org/packages/be/7d/3975098aa2baaabfc10f99f9fcf78045c4f10851beed8e9812b6a2688eab/prek-0.4.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:479e7480b447191aa5c6ed67e80f081d0f5ee4e878b140f4d2cee44165395f1c", size = 5714412, upload-time = "2026-07-16T10:12:46.297Z" }, - { url = "https://files.pythonhosted.org/packages/97/c0/3e0aac190fe95fdef98526343559b61d4d9fd54444c8c9137ba02412afe1/prek-0.4.10-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:0bb7451025cbd2b68e480a13cf665d7a5c87c8b87bf18549a78985c17df817ed", size = 5578145, upload-time = "2026-07-16T10:12:48.261Z" }, - { url = "https://files.pythonhosted.org/packages/d7/44/7b26035534204b8b8a9d5e625479201e616413d287262f557cb32e1f8d77/prek-0.4.10-py3-none-musllinux_1_1_i686.whl", hash = "sha256:4fb047e5776676805794574b2d7b178cb3ab536793aadf172419fcda56b34a57", size = 5889245, upload-time = "2026-07-16T10:12:50.818Z" }, - { url = "https://files.pythonhosted.org/packages/7e/6c/178a9d768876b4211a1bf63907fe308ae02d173639bcf41cea3c5eed35c1/prek-0.4.10-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:08318818d19caf79643babb89f872c92fda134a622b4731df1d6ed61e29d2d26", size = 6372849, upload-time = "2026-07-16T10:12:52.952Z" }, - { url = "https://files.pythonhosted.org/packages/4d/84/d5f5ac8193602883f9dd1d675d9d4084e34fbe3ed2ef50a0c336d8a53d8f/prek-0.4.10-py3-none-win32.whl", hash = "sha256:092872714dcde480a662bbdd98b980b248c2d3e10543d4d53a3a58cc9e5b35b0", size = 5413005, upload-time = "2026-07-16T10:12:55.113Z" }, - { url = "https://files.pythonhosted.org/packages/41/63/9e648fda10bc02c9b6ba305f93b6a6e4fd37d23d13a269a9d2d6bb44eaa1/prek-0.4.10-py3-none-win_amd64.whl", hash = "sha256:3d323a18d0f8c50e474a8fa29fb93bd2db680116d8afb19b76e72ad4667f58e6", size = 5799075, upload-time = "2026-07-16T10:12:56.963Z" }, - { url = "https://files.pythonhosted.org/packages/22/74/b34d8c80cec8dccc7b922c75b9dca62b18b603b5ed2eea93c9d7c2928d2d/prek-0.4.10-py3-none-win_arm64.whl", hash = "sha256:5e93865ef96756c4a26f37ece04ad514abbc19ae6a23ed1a507b6314e6a0d2fb", size = 5563955, upload-time = "2026-07-16T10:12:59.07Z" }, + { url = "https://files.pythonhosted.org/packages/8e/d7/a00b2de492a80e99b1698e72c1d196ac3ed544dc7ee0ada261ac066e78e0/prek-0.4.11-py3-none-linux_armv6l.whl", hash = "sha256:3830cb7cc47e837888b8b464ecb21355a69235cfacef0fd89101e17f09345d63", size = 5770511, upload-time = "2026-07-24T17:05:12.829Z" }, + { url = "https://files.pythonhosted.org/packages/c1/1e/f97c74defcd5d5645888cb99fcdd9b8b48cc7247cf31e64414d106d56d66/prek-0.4.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45facadf9c2332b28e6ab2744312ae0275a93ab5a437da8bcc53a8c7260cb4b0", size = 6118049, upload-time = "2026-07-24T17:05:14.451Z" }, + { url = "https://files.pythonhosted.org/packages/d9/92/8367d26421ee6fe6019a63928fb0ed31179cd0d6199879c524f89ef4c95c/prek-0.4.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2f8a194b1d00d24dff8baff691c99e2668339da2da3482b4ee99c1a0f2409378", size = 5601478, upload-time = "2026-07-24T17:05:15.81Z" }, + { url = "https://files.pythonhosted.org/packages/e1/6f/7617c9b87afaadede4167720aae7ef12d7e51167db903bc8fbac0cadef7b/prek-0.4.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:21d93e6d76bf3d7a9bb70c6ac86ef372adaee50068c45749e6b9e1c2ac4ec939", size = 5932071, upload-time = "2026-07-24T17:05:17.217Z" }, + { url = "https://files.pythonhosted.org/packages/ef/41/6796a4011b04212333259064aa885a71d03d9581ba9bff52db3ce58d1f06/prek-0.4.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7fb07cde2d2156efa6980122b3f13dc88f20c84b933c6205675d0f1e7be2cde8", size = 5677617, upload-time = "2026-07-24T17:05:18.658Z" }, + { url = "https://files.pythonhosted.org/packages/03/5f/3e339901f8460b6073313619b4fd9bf4135e48430695c53640b83ace88ea/prek-0.4.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b7f5e446d2aca739bd18b380578e9c78bb4c086299abc3e167d51c47840c56f", size = 6106370, upload-time = "2026-07-24T17:05:20.219Z" }, + { url = "https://files.pythonhosted.org/packages/8e/4e/94e24b5c1910ec15692ecaf33d0d8ef0d02a02a8b5e40d3c976396880cba/prek-0.4.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7059d640e595d098600e2d97af961f46292b4112670edbe632de84f6828389e", size = 6884342, upload-time = "2026-07-24T17:05:21.587Z" }, + { url = "https://files.pythonhosted.org/packages/a2/7c/fc0daa033dcafe74990c00af2da1e16922790b9c1b8da7e8eebf1123838b/prek-0.4.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85a4df33998fcac878bce3b2c624e1caeb9609f3d562c640702c1234ed815daf", size = 6331365, upload-time = "2026-07-24T17:05:22.87Z" }, + { url = "https://files.pythonhosted.org/packages/d7/36/49f152b8f539930e9685cff0509695ce4054abcecc22f4c16c4e1e5c23d0/prek-0.4.11-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:866991f387527c5f880ce2cc3ddea9b33cc5b986881f8c7f92524cf0969c1350", size = 5939075, upload-time = "2026-07-24T17:05:24.249Z" }, + { url = "https://files.pythonhosted.org/packages/4f/fe/7b097af9161edae7ddedcc9f5cda4a5f31346a492ce3f92583d96c46f628/prek-0.4.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:247e5d8740e137ebdf24fa96f01a95b2d2f1892e956a1ab00c7b1474a59ebcc0", size = 5799029, upload-time = "2026-07-24T17:05:25.652Z" }, + { url = "https://files.pythonhosted.org/packages/49/63/dc955ff99e1002d3cd375b21467c87046bc41deddfce86d898240757b151/prek-0.4.11-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:603ba9f2fd9d666dddb3ae190a25a5c55091b843cde90ed52e0a1116f50d4062", size = 5651211, upload-time = "2026-07-24T17:05:27.027Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b8/bf2139ec25eefb5afef43afac7620c5181f2c2661f220598beacb1771207/prek-0.4.11-py3-none-musllinux_1_1_i686.whl", hash = "sha256:f2682ece3c5fc7201106c4fdd84b0587ccea4b8a2ecefa3e94d3074d2841f1df", size = 5954784, upload-time = "2026-07-24T17:05:28.391Z" }, + { url = "https://files.pythonhosted.org/packages/fc/29/3fe5990aee1bd7c4d50a03358ad867c5e912d9510aafb83a359c7347e5fa/prek-0.4.11-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:22721d30394192931fecc80d6fc6dd47e8ddf8db8b9693805aba8ec0f50087ec", size = 6448916, upload-time = "2026-07-24T17:05:29.837Z" }, + { url = "https://files.pythonhosted.org/packages/0f/fb/abddacf43738302242ecd237236c7c80cd7c1d27545e16e803770aee76e9/prek-0.4.11-py3-none-win32.whl", hash = "sha256:8b093e7624522146049e994d5cf283d01d71632b638620b79ae0f96afeaa2624", size = 5483539, upload-time = "2026-07-24T17:05:31.228Z" }, + { url = "https://files.pythonhosted.org/packages/00/1e/c293f7a15cb93963c4be36a02e144b93f43906bc02644a3f04e5708e7453/prek-0.4.11-py3-none-win_amd64.whl", hash = "sha256:5a3d7c80b970b456e5f1bcec8382008ee1ae6a3f324a6b9bb4ff7e666ab0f3c4", size = 5861119, upload-time = "2026-07-24T17:05:32.479Z" }, + { url = "https://files.pythonhosted.org/packages/cd/0c/05fe6eb9d6a54d0e02dfa8cc5ad6f86869bf953419ec15909a32466a28ee/prek-0.4.11-py3-none-win_arm64.whl", hash = "sha256:e7b0df37ce05e45a14a9da39ab104691474d72f139bf4f6c860f754763a322cb", size = 5626386, upload-time = "2026-07-24T17:05:33.813Z" }, ] [[package]] @@ -2951,11 +3069,11 @@ wheels = [ [[package]] name = "pytz" -version = "2026.2" +version = "2026.3.post1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a", size = 320861, upload-time = "2026-05-04T01:35:29.667Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/48/fb042503b6ca6cd271261dc559fd6432f7d8c713153e9ec5c591af4dfc1c/pytz-2026.3.post1.tar.gz", hash = "sha256:2211d3fcf9a797d3405cac96ac7f61d80e6a644f72a3309607282fe8a2010c5d", size = 319745, upload-time = "2026-07-25T15:12:07.385Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141, upload-time = "2026-05-04T01:35:27.408Z" }, + { url = "https://files.pythonhosted.org/packages/0f/7b/39c34ca613b0b198cb866466651b26b045e2009864c5183c979a3b83f383/pytz-2026.3.post1-py2.py3-none-any.whl", hash = "sha256:dd95840dd199baea12d9cc096a1d452caa6596a1c1e4b5f3dbd1541855d5e815", size = 508283, upload-time = "2026-07-25T15:12:05.782Z" }, ] [[package]] @@ -3329,9 +3447,18 @@ name = "rpds-py" version = "2026.6.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15'", - "python_full_version >= '3.12' and python_full_version < '3.15'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" } wheels = [ @@ -3463,27 +3590,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.22" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/06/ae069393fc66e8ff33036d4b368003833bf6e88ccf182e17e7a2f1c754fd/ruff-0.15.22.tar.gz", hash = "sha256:3f15175b1fb580126f58285a5dae6b2ea89000136d980c64499211f116b54809", size = 4785063, upload-time = "2026-07-16T15:14:13.244Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/23/18/ee54b7ae1e121be7a28ea6da4b67564ebb0530e183a54415ab7e3bcd2c4e/ruff-0.15.22-py3-none-linux_armv6l.whl", hash = "sha256:44423e73493737f5e7c5b41d475483898ff37afcdae38bc3da5085e29af1c2d8", size = 10781258, upload-time = "2026-07-16T15:13:19.452Z" }, - { url = "https://files.pythonhosted.org/packages/2f/d2/2520cb14761ddbeaf57642a76942fc36adcbdbe53b4532241995f6fc485c/ruff-0.15.22-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b82c6482946e9eda7ff2e091d25b8bad3f718684e1916d41bd56873cee05b697", size = 10999477, upload-time = "2026-07-16T15:13:23.318Z" }, - { url = "https://files.pythonhosted.org/packages/c9/10/74e53572aa758dfaa678c2a2646b5c5515d884b7ca56be4d2ce03ca4b560/ruff-0.15.22-py3-none-macosx_11_0_arm64.whl", hash = "sha256:11c1c715af53a09f714e011106bffc419751ec8232fcb5da42173284ea3fec6f", size = 10466716, upload-time = "2026-07-16T15:13:26.162Z" }, - { url = "https://files.pythonhosted.org/packages/1e/cc/44eaaf0844e028182f2d0a8f2190d0f359159aed0a9e5ab861d892f1ae2a/ruff-0.15.22-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742a29cf29bddb7c8327895d6a10e0e6c5b38a96dd407af9b5d0857f809c0576", size = 10892644, upload-time = "2026-07-16T15:13:29.229Z" }, - { url = "https://files.pythonhosted.org/packages/9f/21/8edf559014d2b0f82beea19cfb713993ad802ccda16868769979c6090a84/ruff-0.15.22-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72af58b951b0ae395935ae79763dc349bc0eb706319d28f7a33ad2cfb3cfc178", size = 10576719, upload-time = "2026-07-16T15:13:32.35Z" }, - { url = "https://files.pythonhosted.org/packages/bf/1e/3a13abd392a3b50b62e5938a831f9ab6e588358cacad5c18545b716d2182/ruff-0.15.22-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d425005c1835eb24e2ee4161cb90e8db263415f4a71c8c72c33abaa6c0c224", size = 11376494, upload-time = "2026-07-16T15:13:35.958Z" }, - { url = "https://files.pythonhosted.org/packages/bf/3e/422d3d95bcf04dd78e1aeac22184d4f9a8fb2c01865d39d44618484a0317/ruff-0.15.22-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b9b3f8779a4f08c969defc3c8c35abffaa757e601ed5ae66d6d1db6519969a", size = 12208370, upload-time = "2026-07-16T15:13:39.185Z" }, - { url = "https://files.pythonhosted.org/packages/1e/91/5d065a0e0a02bf4813f5119ad278462eed081d2b832eb7c021ade0ec9e65/ruff-0.15.22-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e0dd1b2e4d3d585f897a0d137cbf4eaf6223bef4e8ce34d6bb12556c5f9249e", size = 11581098, upload-time = "2026-07-16T15:13:42.132Z" }, - { url = "https://files.pythonhosted.org/packages/f6/f9/a0d4871d12fae702eb1f41b686caf05f1f8b124dc6db6f784f53d74918fa/ruff-0.15.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365523eb91d9224e1bcb03b022fbf0facb8f9e23792a2c53d9d4b3924bdbdebb", size = 11399422, upload-time = "2026-07-16T15:13:45.2Z" }, - { url = "https://files.pythonhosted.org/packages/18/80/c843a5176cddbceb0b7e8dd41cf9993490796c1c469348d384f5a5c13c56/ruff-0.15.22-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fabfd168afdf29fee5be98b831efa9683c94d7c5a3b58b9ce5a2e38444589a74", size = 11381683, upload-time = "2026-07-16T15:13:48.46Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/8485de0ae92239438a36cfc51350db9b9e85c9ebdfaea91b18e422706662/ruff-0.15.22-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:225dbf095a87f1d9f90f5fd7924d2613ee452a75a4308c63a8f50f761787aa7c", size = 10850295, upload-time = "2026-07-16T15:13:51.655Z" }, - { url = "https://files.pythonhosted.org/packages/fa/91/24977ec2ec72eaf15e4394ace2959fdff2dd1e14f03e005e838023407169/ruff-0.15.22-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1877d63b9d24ed278744f1523fd11b85540566d54641f97c566d7d9dc5ca5296", size = 10579640, upload-time = "2026-07-16T15:13:54.79Z" }, - { url = "https://files.pythonhosted.org/packages/9c/47/9b51216951974df1f263ac19da550d34252e0ed7218c25f10c5ef9ed7517/ruff-0.15.22-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1606c510bd7215680d32efab38965f7cdec3ef69f5170a3f4791404ffdd5262", size = 11105077, upload-time = "2026-07-16T15:13:57.915Z" }, - { url = "https://files.pythonhosted.org/packages/c2/47/20e9d4a3b8016778acea5fc32bb50d35d207500a17ddb529ffa6996feef8/ruff-0.15.22-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:630479b18625f5ffc373f77603a22a9f8ac0acd7ff0501178b5db28ec71e9c64", size = 11490980, upload-time = "2026-07-16T15:14:01.032Z" }, - { url = "https://files.pythonhosted.org/packages/4d/76/3f72d8fc38c1cb77b38c56a70da9d0c17700cc1cc50f9649c9d3c8f5ba71/ruff-0.15.22-py3-none-win32.whl", hash = "sha256:e5ba0e4a13fd14abbed2a77b517a3911290c6c6c59ef67784328d1668fab76cf", size = 10789165, upload-time = "2026-07-16T15:14:04.16Z" }, - { url = "https://files.pythonhosted.org/packages/cb/46/4965251734c2b6fcdca1b1b187d20bcac3af0ee5b083b89c910bb961ce3a/ruff-0.15.22-py3-none-win_amd64.whl", hash = "sha256:9be63ba1eb936acd2d1342fb8337c356353706fce233b2a15a09a97037e6acde", size = 11938297, upload-time = "2026-07-16T15:14:07.316Z" }, - { url = "https://files.pythonhosted.org/packages/57/c9/e69b1ff4c8b69093ef08b8919ab767af0569666865b39c30a8795d88d3c6/ruff-0.15.22-py3-none-win_arm64.whl", hash = "sha256:e1168075b72158510839f250027659cdd78476f40507dd517892304c41318661", size = 11298172, upload-time = "2026-07-16T15:14:10.51Z" }, +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4d/94/1e5e4967626faf12fa56999cd6222dff6992ceb086ad7945756baf70c7a7/ruff-0.16.0.tar.gz", hash = "sha256:e460aafd5495ec89efaa6ced2e4a9a581116451e1c88b9d37ef497e0f8e93982", size = 4790557, upload-time = "2026-07-23T19:11:30.981Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/81/1c8818fee7ce1a04cd7d1b3172e0a8f8e4f1dc4feb7fc390e16daa8af323/ruff-0.16.0-py3-none-linux_armv6l.whl", hash = "sha256:e5115729eb08c585e5121978ba5d5b60caeae394ce21b9fb5e6cd33a1c6c9b1e", size = 10754633, upload-time = "2026-07-23T19:10:46.415Z" }, + { url = "https://files.pythonhosted.org/packages/23/df/beaf59c09d68db84304d555f188b276a77132a5d5b0b67a5c762aa143628/ruff-0.16.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3c954b1d580bfa035b41654f7858cc7e71d5fc3ac5b723dd62bd9133830ed522", size = 10969164, upload-time = "2026-07-23T19:10:50.271Z" }, + { url = "https://files.pythonhosted.org/packages/42/ce/741cd197496a1abbf51352710fd15ed995d2a2be87189c1da26a450d6e83/ruff-0.16.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e01c21d10eb1b29f47b7454e1f4056db9a3f0260c646aa88457c610291db9f81", size = 10488846, upload-time = "2026-07-23T19:10:52.639Z" }, + { url = "https://files.pythonhosted.org/packages/52/2a/a2db8e88cade358f5cdcb05674a917751074109315d014eb6352d9a893f7/ruff-0.16.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e364e5ed22ed8dc05082fd78e35308618260907ac2d3c1d637b2e682415b6c9", size = 10889729, upload-time = "2026-07-23T19:10:54.89Z" }, + { url = "https://files.pythonhosted.org/packages/42/65/62a771694ebd63029dc953e27dbad40e1588bd4860ff9fe881018fddaa49/ruff-0.16.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d327b8fc113a1d4421a04f3839d3752057c8dd1ee320223a6f3f52d04ada462a", size = 10568275, upload-time = "2026-07-23T19:10:56.993Z" }, + { url = "https://files.pythonhosted.org/packages/3f/e2/ced249fe8af5f086c5c58cc21cc3356d50f32f7401c5df87050c999620a7/ruff-0.16.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b50c55e263103586b3dcf5f73d479eb8cb5fdb6098fec59a62891dab653717", size = 11385112, upload-time = "2026-07-23T19:10:59.615Z" }, + { url = "https://files.pythonhosted.org/packages/87/0b/05154977a8fd69eeb6c103271f55403bfd8711f5c0f8ed07489d95a504e7/ruff-0.16.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ff4a79ce3ec0172f3241943835de1c4cb4e2dcd07f0f8c2d02603dbbbee4b17", size = 12207008, upload-time = "2026-07-23T19:11:02.154Z" }, + { url = "https://files.pythonhosted.org/packages/fb/29/98225831a3a1eab0e02f4acc6ca6559a98611dcc68b6965ff4b7234627c1/ruff-0.16.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e95c448fca1fb2a18372a9440926c5a6ee789639bb975c72e7ae6d0b04218ab4", size = 11650842, upload-time = "2026-07-23T19:11:04.557Z" }, + { url = "https://files.pythonhosted.org/packages/91/66/6bd3cf90500653d55dc0ffc8507aa8300bd49d0214b2e8cb4d3fef2943ba/ruff-0.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f11a8d11010301d0a398a2fdef67691feca7294da6aef55e2150e8fa2cd520b", size = 11400718, upload-time = "2026-07-23T19:11:09.233Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a2/a54eb4eae05d66364050a5d3b8a9c5ef88196531b3cbe7109d873f87f819/ruff-0.16.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:48044c678e9cb8698246c99b14aaccfa6601dea7379eb48a6f8f73f7a6d86cd0", size = 11426177, upload-time = "2026-07-23T19:11:11.994Z" }, + { url = "https://files.pythonhosted.org/packages/1a/be/16e3eea4b2a478a496919f5e36f17c4559e54620bd3bbac5d6affa068006/ruff-0.16.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7aa0959bad8eb8bef50340154fc9b58678dae31fa4293afa38b44b6e552c0213", size = 10856126, upload-time = "2026-07-23T19:11:14.221Z" }, + { url = "https://files.pythonhosted.org/packages/a2/84/252eb8b868a16eec7257c14f504f77537e734b2d69c762e639e588e304a3/ruff-0.16.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28ea2b7df8ebf7f9da6b7d47b230ab48f387c0a29be3b474c4d0740e197bb9af", size = 10571208, upload-time = "2026-07-23T19:11:16.378Z" }, + { url = "https://files.pythonhosted.org/packages/21/09/817a482f542f7570cbb4554b26e896610c7114f539b1d9e2d2145bf6bef6/ruff-0.16.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:33a3dfac8c35f81498dea9181bccc2f4c4bc8f1521a1dd9406e77643e0f0fb09", size = 11063329, upload-time = "2026-07-23T19:11:19.173Z" }, + { url = "https://files.pythonhosted.org/packages/2e/23/9403c180ca1cb9b1f7335f5c3e5305c09d49ea5b345196682a36028bde4a/ruff-0.16.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a5237a0bda500d30d81b8e07a6973a5cbc772864cbf746ae2f4e8a2e01c9f4ed", size = 11489751, upload-time = "2026-07-23T19:11:21.74Z" }, + { url = "https://files.pythonhosted.org/packages/b2/1d/1b2ef7bcde851c78d7f17f1cca13fd6dc695fc4b3d6197941e72cae5b132/ruff-0.16.0-py3-none-win32.whl", hash = "sha256:7fab76fa065c873f41ff744347c6e77bcc3dfec4bcc754dc26b63d23c0f7f5fb", size = 10785885, upload-time = "2026-07-23T19:11:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/a3/d5e4ef7a56be3f928ffb90b94c25ba7d3cb9c7fe0736aeaaedf361770712/ruff-0.16.0-py3-none-win_amd64.whl", hash = "sha256:429c117f022bf481fabd9d551e7a3952b24c65e6ef44337ea09d90bebef14472", size = 11923141, upload-time = "2026-07-23T19:11:26.409Z" }, + { url = "https://files.pythonhosted.org/packages/cb/9a/8415f2657cbe200f41a4531ccededf135505a92d4a012229121f885b26f9/ruff-0.16.0-py3-none-win_arm64.whl", hash = "sha256:14296fedcd2705c77ab8235439278bbb38f285cf7da5528b00b3e330c3d4872d", size = 11273407, upload-time = "2026-07-23T19:11:28.705Z" }, ] [[package]] @@ -3567,7 +3694,9 @@ name = "sphinx" version = "9.0.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version == '3.11.*'", + "python_full_version == '3.11.*' and sys_platform == 'win32'", + "python_full_version == '3.11.*' and sys_platform == 'emscripten'", + "python_full_version == '3.11.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "alabaster" }, @@ -3598,8 +3727,15 @@ name = "sphinx" version = "9.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15'", - "python_full_version >= '3.12' and python_full_version < '3.15'", + "python_full_version >= '3.15' and sys_platform == 'win32'", + "python_full_version >= '3.15' and sys_platform == 'emscripten'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'win32'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "alabaster" }, @@ -3847,14 +3983,14 @@ wheels = [ [[package]] name = "tqdm" -version = "4.69.0" +version = "4.70.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/69/40407dfc835517f058b603dbf37a6df094d8582b015a51eddc988febbcb7/tqdm-4.69.0.tar.gz", hash = "sha256:700c5e85dcd5f009dd6222588a29180a193a748247a5d855b4d67db93d79a53b", size = 792569, upload-time = "2026-07-17T18:09:06.2Z" } +sdist = { url = "https://files.pythonhosted.org/packages/21/3b/6c24bec5be5e743ffd99576daa5cc077722fc7d5bbc00bd133fa0c698dc6/tqdm-4.70.0.tar.gz", hash = "sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220", size = 795438, upload-time = "2026-07-27T11:33:15.271Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/21/99a0cdaf54eb35e77623c41b5a2c9472ee4404bba687052791fe2aba6773/tqdm-4.69.0-py3-none-any.whl", hash = "sha256:9979978912be667a6ef21fd5d8abf54e324e63d82f7f43c360792ebc2bc4e622", size = 676680, upload-time = "2026-07-17T18:09:04.172Z" }, + { url = "https://files.pythonhosted.org/packages/f9/1c/01bfd571a64e7f270e6bab5e33777debe0edc56759233ce84f27dec92d14/tqdm-4.70.0-py3-none-any.whl", hash = "sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953", size = 80184, upload-time = "2026-07-27T11:33:13.167Z" }, ] [[package]] @@ -3908,11 +4044,11 @@ wheels = [ [[package]] name = "types-pyyaml" -version = "6.0.12.20260518" +version = "6.0.12.20260724" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b8/83/4a1afc3fbfcf5b8d46fc390cd95ed6b0dc9010a265f4e9f46314efffa37a/types_pyyaml-6.0.12.20260518.tar.gz", hash = "sha256:d917f83fb38462550338c1297faedd860b3ec83912b96b1e3d73255f7473e466", size = 17850, upload-time = "2026-05-18T06:01:58.675Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/6f/a28f44bcd56bebed42b028a2894c79853e2f5e6b5279e633cb3f287a05e7/types_pyyaml-6.0.12.20260724.tar.gz", hash = "sha256:3c1ce1bb73cd5ec02e90390c2b1f00e810d241d8825fd73ff359696839271b6b", size = 17893, upload-time = "2026-07-24T04:58:43.453Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/a2/c01db32be2ae7d6a1689972f3c492b149ee4e164b12fdfd9f64b50888215/types_pyyaml-6.0.12.20260518-py3-none-any.whl", hash = "sha256:d2150f75a231c9fe9c7463bd29487d93e60bac90400287351384bc2284eba7cd", size = 20312, upload-time = "2026-05-18T06:01:57.368Z" }, + { url = "https://files.pythonhosted.org/packages/8b/42/0337fefc615e20ee55d1c8f71b774a9b2b734a04669139c20753b27a2a3a/types_pyyaml-6.0.12.20260724-py3-none-any.whl", hash = "sha256:d57db930a4b2efbc57cf430ec8882765d246929432fa253092f383902329a453", size = 20312, upload-time = "2026-07-24T04:58:42.486Z" }, ] [[package]] @@ -3929,11 +4065,11 @@ wheels = [ [[package]] name = "types-setuptools" -version = "83.0.0.20260716" +version = "83.0.0.20260724" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/fa/deb7066a472bb23d28205a9dde66caef317db4b0f2ce612068c5d45a9f87/types_setuptools-83.0.0.20260716.tar.gz", hash = "sha256:a36ad71a57919b80db314e6104478ee75376a34abea88ba0f3d28db4d10006d7", size = 45672, upload-time = "2026-07-16T04:47:56.484Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/8c/e069673eb23a7a8242f6e28184ef6911849b2667a61b3bf298d86b807f33/types_setuptools-83.0.0.20260724.tar.gz", hash = "sha256:fe2801176b667f1e8209f8571b0839ca6c34318d743825aeacf3f29970c8d46f", size = 45746, upload-time = "2026-07-24T04:57:55.054Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e3/f9/b89c50c1f482b2b4e038a845c23a3b3fdfd735199634d2452b8951a8629b/types_setuptools-83.0.0.20260716-py3-none-any.whl", hash = "sha256:77315e9a921ced0c7cbef803d7cf06db8e60e9df5661955ee4ce3d1a1675e0dc", size = 68767, upload-time = "2026-07-16T04:47:55.484Z" }, + { url = "https://files.pythonhosted.org/packages/f3/5d/5c32313e6eb7298944ca0fad6486157e8ed549760a25598cddb8ac7e08c6/types_setuptools-83.0.0.20260724-py3-none-any.whl", hash = "sha256:eed1a91e1ed9d8ec9f3e71908e5bb17272e41e0852d37d1485ecd9cd33165e1a", size = 68758, upload-time = "2026-07-24T04:57:53.976Z" }, ] [[package]] From 7dc6cb4ffc27a5756bfda21528723d3cd561c7a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 13:20:20 +0000 Subject: [PATCH 131/135] Update CodSpeedHQ/action action to v5 (#4428) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codspeed.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index 4a616d2ccb..0667bcd659 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -60,7 +60,7 @@ jobs: # import/start-up cost, which CodSpeed's instruction-counting # "simulation" instrument can't see. Use "walltime" mode instead. - name: Run start-up benchmarks - uses: CodSpeedHQ/action@f22792bfac16f3e14eb9fbea76f4a48e9cc22b93 # v4.19.1 + uses: CodSpeedHQ/action@88472375d0a4572cf70a9f1fe3a4e0ab8da1b924 # v5.0.1 with: mode: walltime run: uv run pytest benchmarks/test_startup_benchmarks.py --codspeed From 84595160f7ca1f790e82538e0f1726a66144584b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 13:21:02 +0000 Subject: [PATCH 132/135] Update docker/login-action digest to dbcb813 (#4427) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/push_dockerhub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_dockerhub.yml b/.github/workflows/push_dockerhub.yml index 557c9b8a46..98f4085aa9 100644 --- a/.github/workflows/push_dockerhub.yml +++ b/.github/workflows/push_dockerhub.yml @@ -43,7 +43,7 @@ jobs: uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4 - name: Log in to Docker Hub - uses: docker/login-action@371161bbe7024a29a25c5e19bfcbc0804fe9ad2c # v4 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASS }} From 2eeb028b5c976610a09373f46446307649a4eaaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 29 Jul 2026 15:33:39 +0200 Subject: [PATCH 133/135] back-port changes from 4.0.3 for pr-comment.yml (#4431) --- .../.github/workflows/pr-comment.yml | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/nf_core/pipeline-template/.github/workflows/pr-comment.yml b/nf_core/pipeline-template/.github/workflows/pr-comment.yml index 38accbf251..c0a8c61e71 100644 --- a/nf_core/pipeline-template/.github/workflows/pr-comment.yml +++ b/nf_core/pipeline-template/.github/workflows/pr-comment.yml @@ -18,6 +18,7 @@ on: - "nf-core linting" - "nf-core template version comment" - "nf-core branch protection" + - "Run nf-test" permissions: actions: read @@ -27,7 +28,6 @@ permissions: jobs: post-comment: runs-on: ubuntu-latest - # Only act on runs that were triggered by a pull request. if: github.event.workflow_run.event == 'pull_request' steps: - name: Download PR comment artifact @@ -35,16 +35,29 @@ jobs: with:{% raw %} run_id: ${{ github.event.workflow_run.id }} name: pr-comment + path: pr-comment if_no_artifact_found: ignore - name: Read comment metadata id: meta run: | - # No comment body means there is nothing to post. - [ -f pr-comment/comment.md ] || exit 0 + echo "::group::Downloaded pr-comment contents" + ls -la pr-comment 2>/dev/null || echo "No pr-comment/ directory was downloaded." + echo "::endgroup::" + + if [ ! -d pr-comment ]; then + echo "No pr-comment artifact found; nothing to post." + exit 0 + fi + + if [ ! -f pr-comment/comment.md ]; then + echo "Artifact present but no comment.md; nothing to post." + exit 0 + fi pr_number=$(cat pr-comment/pr_number.txt) header=$(cat pr-comment/header.txt) + echo "Found comment.md (header='$header', pr_number='$pr_number')." # Guard against anything unexpected ending up in the PR number. case "$pr_number" in @@ -57,6 +70,7 @@ jobs: echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT" echo "header=$header" >> "$GITHUB_OUTPUT" echo "post=true" >> "$GITHUB_OUTPUT" + echo "Will post comment to PR #${pr_number}." - name: Post PR comment if: steps.meta.outputs.post == 'true' From 04e7242c3b126540b326d637651ea66a0cb7af2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=B6rtenhuber?= Date: Wed, 29 Jul 2026 15:33:58 +0200 Subject: [PATCH 134/135] update setup-apptainer to fix namespace error (#4430) --- nf_core/pipeline-template/.github/actions/nf-test/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nf_core/pipeline-template/.github/actions/nf-test/action.yml b/nf_core/pipeline-template/.github/actions/nf-test/action.yml index 960418271f..ec38048a6e 100644 --- a/nf_core/pipeline-template/.github/actions/nf-test/action.yml +++ b/nf_core/pipeline-template/.github/actions/nf-test/action.yml @@ -37,7 +37,7 @@ runs: - name: Setup apptainer if: contains(inputs.profile, 'singularity') - uses: eWaterCycle/setup-apptainer@4bb22c52d4f63406c49e94c804632975787312b3 # v2.0.0 + uses: eWaterCycle/setup-apptainer@3f706d898c9db585b1d741b4692e66755f3a1b40 # v2.0.0 - name: Set up Singularity if: contains(inputs.profile, 'singularity') From cb623e0762528067479639834d1589b40b0064be Mon Sep 17 00:00:00 2001 From: mashehu Date: Wed, 29 Jul 2026 15:55:28 +0200 Subject: [PATCH 135/135] update changelog title and date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c169f3a630..61ba31f6f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # nf-core/tools: Changelog -## [v4.1.0 - marshalled mamba](https://github.com/nf-core/tools/releases/tag/4.1.0) - [2026-07-21] +## [v4.1.0 - Marshalled Mamba](https://github.com/nf-core/tools/releases/tag/4.1.0) - [2026-07-29] ### General