text:
const mimetypes = Dict{String,String}([
("semd", "application/vnd.semd"),
("mrc", "application/marc"),
("asc", "application/pgp-signature"),
("fe_launch", "application/vnd.denovo.fcselayout-link"),
("esa", "application/vnd.osgi.subsystem"),
("sub", "text/vnd.dvb.subtitle"),
("clkx", "application/vnd.crick.clicker"),
("xdw", "application/vnd.fujixerox.docuworks"),
("nsc", "application/x-conference"),
("lostxml", "application/lost+xml"),
("rsd", "application/rsd+xml"),
("p8", "application/pkcs8"),
("dra", "audio/vnd.dra"),
("x3db", "model/x3d+binary"),
("text", "text/plain"),
("vox", "application/x-authorware-bin"),
("bmi", "application/vnd.bmi"),
("ma", "application/mathematica"),
("xbd", "application/vnd.fujixerox.docuworks.binder"),
("mgz", "application/vnd.proteus.magazine"),
("pgm", "image/x-portable-graymap"),
("xpi", "application/x-xpinstall"),
("htm", "text/html"),
("lasxml", "application/vnd.las.las+xml"),
("ait", "application/vnd.dvb.ait"),
("abw", "application/x-abiword"),
("wm", "video/x-ms-wm"),
("sdkd", "application/vnd.solent.sdkm+xml"),
("swi", "application/vnd.aristanetworks.swi"),
("iif", "application/vnd.shana.informed.interchange"),
("bpk", "application/octet-stream"),
("gxt", "application/vnd.geonext"),
("wpl", "application/vnd.ms-wpl"),
("sxd", "application/vnd.sun.xml.draw"),
("ktx", "image/ktx"),
("acc", "application/vnd.americandynamics.acc"),
("mxml", "application/xv+xml"),
("setpay", "application/set-payment-initiation"),
("aac", "audio/x-aac"),
("vsw", "application/vnd.visio"),
("uris", "text/uri-list"),
("mp4", "video/mp4"),
("st", "application/vnd.sailingtracker.track"),
("3ds", "image/x-3ds"),
("sgm", "text/sgml"),
("xwd", "image/x-xwindowdump"),
("slt", "application/vnd.epson.salt"),
("pya", "audio/vnd.ms-playready.media.pya"),
("dir", "application/x-director"),
("utz", "application/vnd.uiq.theme"),
("z6", "application/x-zmachine"),
("z4", "application/x-zmachine"),
("xvm", "application/xv+xml"),
("pki", "application/pkixcmp"),
("vor", "application/vnd.stardivision.writer"),
("vxml", "application/voicexml+xml"),
("plb", "application/vnd.3gpp.pic-bw-large"),
("tar", "application/x-tar"),
("dmp", "application/vnd.tcpdump.pcap"),
("gmx", "application/vnd.gmx"),
("spf", "application/vnd.yamaha.smaf-phrase"),
("susp", "application/vnd.sus-calendar"),
("xlam", "application/vnd.ms-excel.addin.macroenabled.12"),
("odf", "application/vnd.oasis.opendocument.formula"),
("wspolicy", "application/wspolicy+xml"),
("gml", "application/gml+xml"),
("msl", "application/vnd.mobius.msl"),
("mseq", "application/vnd.mseq"),
("rmvb", "application/vnd.rn-realmedia-vbr"),
("saf", "application/vnd.yamaha.smaf-audio"),
("fh7", "image/x-freehand"),
("uvvu", "video/vnd.uvvu.mp4"),
("mpkg", "application/vnd.apple.installer+xml"),
("shf", "application/shf+xml"),
("org", "application/vnd.lotus-organizer"),
("cpp", "text/x-c"),
("deploy", "application/octet-stream"),
("uvu", "video/vnd.uvvu.mp4"),
("z3", "application/x-zmachine"),
("application", "application/x-ms-application"),
("wps", "application/vnd.ms-works"),
("dtd", "application/xml-dtd"),
("cww", "application/prs.cww"),
("cmdf", "chemical/x-cmdf"),
("mpe", "video/mpeg"),
("sv4crc", "application/x-sv4crc"),
("appcache", "text/cache-manifest"),
("in", "text/plain"),
("png", "image/png"),
("wmv", "video/x-ms-wmv"),
("aep", "application/vnd.audiograph"),
("gim", "application/vnd.groove-identity-message"),
("sdd", "application/vnd.stardivision.impress"),
("ccxml", "application/ccxml+xml"),
("sh", "application/x-sh"),
("pptm", "application/vnd.ms-powerpoint.presentation.macroenabled.12"),
("sdkm", "application/vnd.solent.sdkm+xml"),
("ulx", "application/x-glulx"),
("xbap", "application/x-ms-xbap"),
("xlsm", "application/vnd.ms-excel.sheet.macroenabled.12"),
("n-gage", "application/vnd.nokia.n-gage.symbian.install"),
("stc", "application/vnd.sun.xml.calc.template"),
("icc", "application/vnd.iccprofile"),
("f4v", "video/x-f4v"),
("mmr", "image/vnd.fujixerox.edmics-mmr"),
("eml", "message/rfc822"),
("rgb", "image/x-rgb"),
("m3a", "audio/mpeg"),
("cdbcmsg", "application/vnd.contact.cmsg"),
("jlt", "application/vnd.hp-jlyt"),
("xar", "application/vnd.xara"),
("icm", "application/vnd.iccprofile"),
("etx", "text/x-setext"),
("iges", "model/iges"),
("clkw", "application/vnd.crick.clicker.wordbank"),
("uvva", "audio/vnd.dece.audio"),
("pcurl", "application/vnd.curl.pcurl"),
("rq", "application/sparql-query"),
("azf", "application/vnd.airzip.filesecure.azf"),
("gram", "application/srgs"),
("jad", "text/vnd.sun.j2me.app-descriptor"),
("mmf", "application/vnd.smaf"),
("c4u", "application/vnd.clonk.c4group"),
("mp4s", "application/mp4"),
("jsonml", "application/jsonml+json"),
("itp", "application/vnd.shana.informed.formtemplate"),
("nc", "application/x-netcdf"),
("qwd", "application/vnd.quark.quarkxpress"),
("spp", "application/scvp-vp-response"),
("pqa", "application/vnd.palm"),
("uvv", "video/vnd.dece.video"),
("pub", "application/x-mspublisher"),
("gph", "application/vnd.flographit"),
("rmp", "audio/x-pn-realaudio-plugin"),
("ott", "application/vnd.oasis.opendocument.text-template"),
("cdkey", "application/vnd.mediastation.cdkey"),
("wqd", "application/vnd.wqd"),
("gqf", "application/vnd.grafeq"),
("sv4cpio", "application/x-sv4cpio"),
("skm", "application/vnd.koan"),
("swa", "application/x-director"),
("html", "text/html"),
("uvz", "application/vnd.dece.zip"),
("p7s", "application/pkcs7-signature"),
("uvvs", "video/vnd.dece.sd"),
("p7r", "application/x-pkcs7-certreqresp"),
("wrl", "model/vrml"),
("f77", "text/x-fortran"),
("uvvd", "application/vnd.dece.data"),
("crt", "application/x-x509-ca-cert"),
("ppt", "application/vnd.ms-powerpoint"),
("smzip", "application/vnd.stepmania.package"),
("osf", "application/vnd.yamaha.openscoreformat"),
("c11amc", "application/vnd.cluetrust.cartomobile-config"),
("m4u", "video/vnd.mpegurl"),
("mpt", "application/vnd.ms-project"),
("plf", "application/vnd.pocketlearn"),
("cbt", "application/x-cbr"),
("mseed", "application/vnd.fdsn.mseed"),
("ecma", "application/ecmascript"),
("srx", "application/sparql-results+xml"),
("cxt", "application/x-director"),
("mwf", "application/vnd.mfer"),
("pkg", "application/octet-stream"),
("ami", "application/vnd.amiga.ami"),
("mvb", "application/x-msmediaview"),
("xdssc", "application/dssc+xml"),
("rss", "application/rss+xml"),
("s", "text/x-asm"),
("odp", "application/vnd.oasis.opendocument.presentation"),
("mng", "video/x-mng"),
("lvp", "audio/vnd.lucent.voice"),
("mj2", "video/mj2"),
("uvp", "video/vnd.dece.pd"),
("dts", "audio/vnd.dts"),
("tga", "image/x-tga"),
("h263", "video/h263"),
("mpp", "application/vnd.ms-project"),
("xvml", "application/xv+xml"),
("mdi", "image/vnd.ms-modi"),
("fnc", "application/vnd.frogans.fnc"),
("json", "application/json"),
("otp", "application/vnd.oasis.opendocument.presentation-template"),
("m4v", "video/x-m4v"),
("oti", "application/vnd.oasis.opendocument.image-template"),
("ps", "application/postscript"),
("kpxx", "application/vnd.ds-keypoint"),
("m13", "application/x-msmediaview"),
("torrent", "application/x-bittorrent"),
("shar", "application/x-shar"),
("acutc", "application/vnd.acucorp"),
("smil", "application/smil+xml"),
("wcm", "application/vnd.ms-works"),
("uvvt", "application/vnd.dece.ttml+xml"),
("xop", "application/xop+xml"),
("knp", "application/vnd.kinar"),
("cpio", "application/x-cpio"),
("mc1", "application/vnd.medcalcdata"),
("svg", "image/svg+xml"),
("blb", "application/x-blorb"),
("u32", "application/x-authorware-bin"),
("hlp", "application/winhlp"),
("jpgv", "video/jpeg"),
("onetmp", "application/onenote"),
("flac", "audio/x-flac"),
("ssdl", "application/ssdl+xml"),
("sfs", "application/vnd.spotfire.sfs"),
("sdc", "application/vnd.stardivision.calc"),
("dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"),
("uvvx", "application/vnd.dece.unspecified"),
("uvvp", "video/vnd.dece.pd"),
("atc", "application/vnd.acucorp"),
("cfs", "application/x-cfs-compressed"),
("mets", "application/mets+xml"),
("wav", "audio/x-wav"),
("mods", "application/mods+xml"),
("thmx", "application/vnd.ms-officetheme"),
("mbk", "application/vnd.mobius.mbk"),
("cpt", "application/mac-compactpro"),
("fzs", "application/vnd.fuzzysheet"),
("mrcx", "application/marcxml+xml"),
("mlp", "application/vnd.dolby.mlp"),
("emma", "application/emma+xml"),
("ecelp9600", "audio/vnd.nuera.ecelp9600"),
("dvi", "application/x-dvi"),
("lrm", "application/vnd.ms-lrm"),
("mif", "application/vnd.mif"),
("mcd", "application/vnd.mcd"),
("cxx", "text/x-c"),
("dist", "application/octet-stream"),
("pml", "application/vnd.ctc-posml"),
("t3", "application/x-t3vm-image"),
("ots", "application/vnd.oasis.opendocument.spreadsheet-template"),
("umj", "application/vnd.umajin"),
("sit", "application/x-stuffit"),
("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"),
("css", "text/css"),
("g2w", "application/vnd.geoplan"),
("spx", "audio/ogg"),
("eva", "application/x-eva"),
("et3", "application/vnd.eszigno3+xml"),
("dart", "application/vnd.dart"),
("3gp", "video/3gpp"),
("kne", "application/vnd.kinar"),
("rnc", "application/relax-ng-compact-syntax"),
("m14", "application/x-msmediaview"),
("urls", "text/uri-list"),
("vst", "application/vnd.visio"),
("xslt", "application/xslt+xml"),
("xspf", "application/xspf+xml"),
("g3w", "application/vnd.geospace"),
("mxs", "application/vnd.triscape.mxs"),
("les", "application/vnd.hhe.lesson-player"),
("txf", "application/vnd.mobius.txf"),
("f", "text/x-fortran"),
("ief", "image/ief"),
("dxp", "application/vnd.spotfire.dxp"),
("tsd", "application/timestamped-data"),
("bed", "application/vnd.realvnc.bed"),
("azs", "application/vnd.airzip.filesecure.azs"),
("pfr", "application/font-tdpfr"),
("seed", "application/vnd.fdsn.seed"),
("mobi", "application/x-mobipocket-ebook"),
("dsc", "text/prs.lines.tag"),
("man", "text/troff"),
("deb", "application/x-debian-package"),
("asx", "video/x-ms-asf"),
("xlsb", "application/vnd.ms-excel.sheet.binary.macroenabled.12"),
("cb7", "application/x-cbr"),
("weba", "audio/webm"),
("fdf", "application/vnd.fdf"),
("exi", "application/exi"),
("otg", "application/vnd.oasis.opendocument.graphics-template"),
("list", "text/plain"),
("mus", "application/vnd.musician"),
("cod", "application/vnd.rim.cod"),
("qxb", "application/vnd.quark.quarkxpress"),
("pot", "application/vnd.ms-powerpoint"),
("mads", "application/mads+xml"),
("cab", "application/vnd.ms-cab-compressed"),
("fh", "image/x-freehand"),
("xlm", "application/vnd.ms-excel"),
("ogx", "application/ogg"),
("pkipath", "application/pkix-pkipath"),
("xaml", "application/xaml+xml"),
("vtu", "model/vnd.vtu"),
("fgd", "application/x-director"),
("ngdat", "application/vnd.nokia.n-gage.data"),
("scm", "application/vnd.lotus-screencam"),
("txd", "application/vnd.genomatix.tuxedo"),
("ptid", "application/vnd.pvi.ptid1"),
("nnd", "application/vnd.noblenet-directory"),
("nml", "application/vnd.enliven"),
("x3d", "model/x3d+xml"),
("cc", "text/x-c"),
("mb", "application/mathematica"),
("ahead", "application/vnd.ahead.space"),
("sisx", "application/vnd.symbian.install"),
("pas", "text/x-pascal"),
("otf", "application/x-font-otf"),
("tr", "text/troff"),
("cdmia", "application/cdmi-capability"),
("joda", "application/vnd.joost.joda-archive"),
("tmo", "application/vnd.tmobile-livetv"),
("dll", "application/x-msdownload"),
("mesh", "model/mesh"),
("geo", "application/vnd.dynageo"),
("m3u8", "application/vnd.apple.mpegurl"),
("p12", "application/x-pkcs12"),
("acu", "application/vnd.acucobol"),
("bat", "application/x-msdownload"),
("wsdl", "application/wsdl+xml"),
("cmp", "application/vnd.yellowriver-custom-menu"),
("odft", "application/vnd.oasis.opendocument.formula-template"),
("smv", "video/x-smv"),
("dae", "model/vnd.collada+xml"),
("efif", "application/vnd.picsel"),
("aso", "application/vnd.accpac.simply.aso"),
("cdf", "application/x-netcdf"),
("gv", "text/vnd.graphviz"),
("xls", "application/vnd.ms-excel"),
("bdf", "application/x-font-bdf"),
("gbr", "application/rpki-ghostbusters"),
("evy", "application/x-envoy"),
("stf", "application/vnd.wt.stf"),
("onetoc", "application/onenote"),
("oa2", "application/vnd.fujitsu.oasys2"),
("jpeg", "image/jpeg"),
("djv", "image/vnd.djvu"),
("aifc", "audio/x-aiff"),
("docm", "application/vnd.ms-word.document.macroenabled.12"),
("stl", "application/vnd.ms-pki.stl"),
("uvg", "image/vnd.dece.graphic"),
("m21", "application/mp21"),
("stw", "application/vnd.sun.xml.writer.template"),
("p7b", "application/x-pkcs7-certificates"),
("ai", "application/postscript"),
("wmz", "application/x-msmetafile"),
("pbm", "image/x-portable-bitmap"),
("cbz", "application/x-cbr"),
("mks", "video/x-matroska"),
("mmd", "application/vnd.chipnuts.karaoke-mmd"),
("p", "text/x-pascal"),
("sitx", "application/x-stuffitx"),
("xenc", "application/xenc+xml"),
("jpg", "image/jpeg"),
("clkp", "application/vnd.crick.clicker.palette"),
("uvvg", "image/vnd.dece.graphic"),
("cdx", "chemical/x-cdx"),
("wad", "application/x-doom"),
("yin", "application/yin+xml"),
("emz", "application/x-msmetafile"),
("stk", "application/hyperstudio"),
("nlu", "application/vnd.neurolanguage.nlu"),
("sig", "application/pgp-signature"),
("opf", "application/oebps-package+xml"),
("box", "application/vnd.previewsystems.box"),
("log", "text/plain"),
("dxr", "application/x-director"),
("igm", "application/vnd.insors.igm"),
("mag", "application/vnd.ecowin.chart"),
("rep", "application/vnd.businessobjects"),
("jpm", "video/jpm"),
("std", "application/vnd.sun.xml.draw.template"),
("clp", "application/x-msclip"),
("cmx", "image/x-cmx"),
("gif", "image/gif"),
("ods", "application/vnd.oasis.opendocument.spreadsheet"),
("z7", "application/x-zmachine"),
("ssml", "application/ssml+xml"),
("mfm", "application/vnd.mfmp"),
("teacher", "application/vnd.smart.teacher"),
("cat", "application/vnd.ms-pki.seccat"),
("z5", "application/x-zmachine"),
("kwt", "application/vnd.kde.kword"),
("uvvh", "video/vnd.dece.hd"),
("ei6", "application/vnd.pg.osasli"),
("vcard", "text/vcard"),
("ppm", "image/x-portable-pixmap"),
("rtx", "text/richtext"),
("opml", "text/x-opml"),
("epub", "application/epub+zip"),
("uvf", "application/vnd.dece.data"),
("ksp", "application/vnd.kde.kspread"),
("semf", "application/vnd.semf"),
("sc", "application/vnd.ibm.secure-container"),
("mpeg", "video/mpeg"),
("qxt", "application/vnd.quark.quarkxpress"),
("xif", "image/vnd.xiff"),
("js", "application/javascript"),
("mjs", "text/javascript"),
("ttl", "text/turtle"),
("sti", "application/vnd.sun.xml.impress.template"),
("sus", "application/vnd.sus-calendar"),
("odb", "application/vnd.oasis.opendocument.database"),
("qt", "video/quicktime"),
("gca", "application/x-gca-compressed"),
("g3", "image/g3fax"),
("sid", "image/x-mrsid-image"),
("ez2", "application/vnd.ezpix-album"),
("xltm", "application/vnd.ms-excel.template.macroenabled.12"),
("chm", "application/vnd.ms-htmlhelp"),
("pyv", "video/vnd.ms-playready.media.pyv"),
("kwd", "application/vnd.kde.kword"),
("mid", "audio/midi"),
("class", "application/java-vm"),
("eol", "audio/vnd.digital-winds"),
("uvh", "video/vnd.dece.hd"),
("dd2", "application/vnd.oma.dd2+xml"),
("dp", "application/vnd.osgi.dp"),
("mp2", "audio/mpeg"),
("zirz", "application/vnd.zul"),
("ez", "application/andrew-inset"),
("sldm", "application/vnd.ms-powerpoint.slide.macroenabled.12"),
("roff", "text/troff"),
("pnm", "image/x-portable-anymap"),
("crd", "application/x-mscardfile"),
("sxg", "application/vnd.sun.xml.writer.global"),
("sgml", "text/sgml"),
("uoml", "application/vnd.uoml+xml"),
("uvi", "image/vnd.dece.graphic"),
("daf", "application/vnd.mobius.daf"),
("imp", "application/vnd.accpac.simply.imp"),
("csp", "application/vnd.commonspace"),
("t", "text/troff"),
("dbk", "application/docbook+xml"),
("c4f", "application/vnd.clonk.c4group"),
("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
("dgc", "application/x-dgc-compressed"),
("aab", "application/x-authorware-bin"),
("svgz", "image/svg+xml"),
("ras", "image/x-cmu-raster"),
("ntf", "application/vnd.nitf"),
("omdoc", "application/omdoc+xml"),
("dtb", "application/x-dtbook+xml"),
("odg", "application/vnd.oasis.opendocument.graphics"),
("qxd", "application/vnd.quark.quarkxpress"),
("mny", "application/x-msmoney"),
("uvvf", "application/vnd.dece.data"),
("musicxml", "application/vnd.recordare.musicxml+xml"),
("yang", "application/yang"),
("chrt", "application/vnd.kde.kchart"),
("scd", "application/x-msschedule"),
("ecelp4800", "audio/vnd.nuera.ecelp4800"),
("kmz", "application/vnd.google-earth.kmz"),
("cdxml", "application/vnd.chemdraw+xml"),
("igl", "application/vnd.igloader"),
("ufd", "application/vnd.ufdl"),
("pbd", "application/vnd.powerbuilder6"),
("dcurl", "text/vnd.curl.dcurl"),
("sxc", "application/vnd.sun.xml.calc"),
("mp3", "audio/mpeg"),
("scq", "application/scvp-cv-request"),
("igx", "application/vnd.micrografx.igx"),
("onetoc2", "application/onenote"),
("bmp", "image/bmp"),
("ssf", "application/vnd.epson.ssf"),
("tif", "image/tiff"),
("dataless", "application/vnd.fdsn.seed"),
("cmc", "application/vnd.cosmocaller"),
("qbo", "application/vnd.intu.qbo"),
("vcf", "text/x-vcard"),
("str", "application/vnd.pg.format"),
("c", "text/x-c"),
("flx", "text/vnd.fmi.flexstor"),
("gac", "application/vnd.groove-account"),
("gxf", "application/gxf"),
("zaz", "application/vnd.zzazz.deck+xml"),
("h261", "video/h261"),
("7z", "application/x-7z-compressed"),
("dwg", "image/vnd.dwg"),
("x32", "application/x-authorware-bin"),
("ttc", "application/x-font-ttf"),
("eot", "application/vnd.ms-fontobject"),
("wdb", "application/vnd.ms-works"),
("atomcat", "application/atomcat+xml"),
("ddd", "application/vnd.fujixerox.ddd"),
("ipfix", "application/ipfix"),
("potm", "application/vnd.ms-powerpoint.template.macroenabled.12"),
("dic", "text/x-c"),
("xul", "application/vnd.mozilla.xul+xml"),
("maker", "application/vnd.framemaker"),
("x3dv", "model/x3d+vrml"),
("rtf", "application/rtf"),
("nzb", "application/x-nzb"),
("fcs", "application/vnd.isac.fcs"),
("gre", "application/vnd.geometry-explorer"),
("woff", "application/font-woff"),
("fh4", "image/x-freehand"),
("obj", "application/x-tgif"),
("aif", "audio/x-aiff"),
("mxl", "application/vnd.recordare.musicxml"),
("jpgm", "video/jpm"),
("dxf", "image/vnd.dxf"),
("car", "application/vnd.curl.car"),
("xpl", "application/xproc+xml"),
("tei", "application/tei+xml"),
("paw", "application/vnd.pawaafile"),
("plc", "application/vnd.mobius.plc"),
("mqy", "application/vnd.mobius.mqy"),
("m2v", "video/mpeg"),
("tex", "application/x-tex"),
("crl", "application/pkix-crl"),
("xap", "application/x-silverlight-app"),
("fvt", "video/vnd.fvt"),
("mk3d", "video/x-matroska"),
("wax", "audio/x-ms-wax"),
("htke", "application/vnd.kenameaapp"),
("cst", "application/x-director"),
("i2g", "application/vnd.intergeo"),
("webm", "video/webm"),
("lwp", "application/vnd.lotus-wordpro"),
("aiff", "audio/x-aiff"),
("ink", "application/inkml+xml"),
("eps", "application/postscript"),
("clkt", "application/vnd.crick.clicker.template"),
("p10", "application/pkcs10"),
("csml", "chemical/x-csml"),
("qxl", "application/vnd.quark.quarkxpress"),
("vcd", "application/x-cdlink"),
("pvb", "application/vnd.3gpp.pic-bw-var"),
("smf", "application/vnd.stardivision.math"),
("ivp", "application/vnd.immervision-ivp"),
("listafp", "application/vnd.ibm.modcap"),
("tpl", "application/vnd.groove-tool-template"),
("gsf", "application/x-font-ghostscript"),
("rlc", "image/vnd.fujixerox.edmics-rlc"),
("unityweb", "application/vnd.unity"),
("fxpl", "application/vnd.adobe.fxp"),
("wri", "application/x-mswrite"),
("rp9", "application/vnd.cloanto.rp9"),
("so", "application/octet-stream"),
("pfb", "application/x-font-type1"),
("tcl", "application/x-tcl"),
("scurl", "text/vnd.curl.scurl"),
("vsd", "application/vnd.visio"),
("rmi", "audio/midi"),
("rdz", "application/vnd.data-vision.rdz"),
("frame", "application/vnd.framemaker"),
("mxf", "application/mxf"),
("tfi", "application/thraud+xml"),
("kon", "application/vnd.kde.kontour"),
("ifm", "application/vnd.shana.informed.formdata"),
("xbm", "image/x-xbitmap"),
("pre", "application/vnd.lotus-freelance"),
("c4d", "application/vnd.clonk.c4group"),
("ipk", "application/vnd.shana.informed.package"),
("ktr", "application/vnd.kahootz"),
("z1", "application/x-zmachine"),
("kia", "application/vnd.kidspiration"),
("hal", "application/vnd.hal+xml"),
("es3", "application/vnd.eszigno3+xml"),
("xht", "application/xhtml+xml"),
("uva", "audio/vnd.dece.audio"),
("exe", "application/x-msdownload"),
("cap", "application/vnd.tcpdump.pcap"),
("pfm", "application/x-font-type1"),
("xps", "application/vnd.ms-xpsdocument"),
("clkk", "application/vnd.crick.clicker.keyboard"),
("tra", "application/vnd.trueapp"),
("vis", "application/vnd.visionary"),
("osfpvg", "application/vnd.yamaha.openscoreformat.osfpvg+xml"),
("pclxl", "application/vnd.hp-pclxl"),
("oxt", "application/vnd.openofficeorg.extension"),
("xlc", "application/vnd.ms-excel"),
("vcx", "application/vnd.vcx"),
("ace", "application/x-ace-compressed"),
("wtb", "application/vnd.webturbo"),
("cct", "application/x-director"),
("scs", "application/scvp-cv-response"),
("sxm", "application/vnd.sun.xml.math"),
("mie", "application/x-mie"),
("tsv", "text/tab-separated-values"),
("f90", "text/x-fortran"),
("fti", "application/vnd.anser-web-funds-transfer-initiation"),
("c11amz", "application/vnd.cluetrust.cartomobile-config-pkg"),
("sil", "audio/silk"),
("vob", "video/x-ms-vob"),
("gnumeric", "application/x-gnumeric"),
("xdf", "application/xcap-diff+xml"),
("gpx", "application/gpx+xml"),
("fst", "image/vnd.fst"),
("srt", "application/x-subrip"),
("lrf", "application/octet-stream"),
("chat", "application/x-chat"),
("air", "application/vnd.adobe.air-application-installer-package+zip"),
("psf", "application/x-font-linux-psf"),
("hvp", "application/vnd.yamaha.hv-voice"),
("src", "application/x-wais-source"),
("fxp", "application/vnd.adobe.fxp"),
("ecelp7470", "audio/vnd.nuera.ecelp7470"),
("cii", "application/vnd.anser-web-certificate-issue-initiation"),
("oxps", "application/oxps"),
("cdmio", "application/cdmi-object"),
("atx", "application/vnd.antix.game-component"),
("wdp", "image/vnd.ms-photo"),
("pic", "image/x-pict"),
("qfx", "application/vnd.intu.qfx"),
("mar", "application/octet-stream"),
("3dml", "text/vnd.in3d.3dml"),
("gtm", "application/vnd.groove-tool-message"),
("wmd", "application/x-ms-wmd"),
("xz", "application/x-xz"),
("der", "application/x-x509-ca-cert"),
("me", "text/troff"),
("dssc", "application/dssc+der"),
("smi", "application/smil+xml"),
("nb", "application/mathematica"),
("pdf", "application/pdf"),
("atomsvc", "application/atomsvc+xml"),
("mpc", "application/vnd.mophun.certificate"),
("dotm", "application/vnd.ms-word.template.macroenabled.12"),
("mp4v", "video/mp4"),
("hvd", "application/vnd.yamaha.hv-dic"),
("uu", "text/x-uuencode"),
("afm", "application/x-font-type1"),
("p7c", "application/pkcs7-mime"),
("spq", "application/scvp-vp-request"),
("tpt", "application/vnd.trid.tpt"),
("twds", "application/vnd.simtech-mindmapper"),
("vcs", "text/x-vcalendar"),
("jisp", "application/vnd.jisp"),
("mathml", "application/mathml+xml"),
("sxw", "application/vnd.sun.xml.writer"),
("x3dbz", "model/x3d+binary"),
("x3dz", "model/x3d+xml"),
("edm", "application/vnd.novadigm.edm"),
("for", "text/x-fortran"),
("wbxml", "application/vnd.wap.wbxml"),
("pskcxml", "application/pskc+xml"),
("gtw", "model/vnd.gtw"),
("dcr", "application/x-director"),
("ogv", "video/ogg"),
("wmlsc", "application/vnd.wap.wmlscriptc"),
("potx", "application/vnd.openxmlformats-officedocument.presentationml.template"),
("mka", "audio/x-matroska"),
("adp", "audio/adpcm"),
("dna", "application/vnd.dna"),
("mp4a", "audio/mp4"),
("oas", "application/vnd.fujitsu.oasys"),
("fcdt", "application/vnd.adobe.formscentral.fcdt"),
("rms", "application/vnd.jcp.javame.midlet-rms"),
("pcap", "application/vnd.tcpdump.pcap"),
("rm", "application/vnd.rn-realmedia"),
("csv", "text/csv"),
("123", "application/vnd.lotus-1-2-3"),
("rcprofile", "application/vnd.ipunplugged.rcprofile"),
("msty", "application/vnd.muvee.style"),
("sxi", "application/vnd.sun.xml.impress"),
("xml", "application/xml"),
("wmf", "application/x-msmetafile"),
("psb", "application/vnd.3gpp.pic-bw-small"),
("taglet", "application/vnd.mynfc"),
("psd", "image/vnd.adobe.photoshop"),
("mxu", "video/vnd.mpegurl"),
("sql", "application/x-sql"),
("ppd", "application/vnd.cups-ppd"),
("odt", "application/vnd.oasis.opendocument.text"),
("dms", "application/octet-stream"),
("cer", "application/pkix-cert"),
("mpy", "application/vnd.ibm.minipay"),
("snf", "application/x-font-snf"),
("uvvm", "video/vnd.dece.mobile"),
("texi", "application/x-texinfo"),
("bin", "application/octet-stream"),
("h264", "video/h264"),
("jam", "application/vnd.jam"),
("cla", "application/vnd.claymore"),
("xm", "audio/xm"),
("dot", "application/msword"),
("dwf", "model/vnd.dwf"),
("ivu", "application/vnd.immervision-ivu"),
("skd", "application/vnd.koan"),
("mp2a", "audio/mpeg"),
("tcap", "application/vnd.3gpp2.tcap"),
("jnlp", "application/x-java-jnlp-file"),
("cdy", "application/vnd.cinderella"),
("ltf", "application/vnd.frogans.ltf"),
("bz", "application/x-bzip"),
("rar", "application/x-rar-compressed"),
("cif", "chemical/x-cif"),
("pfa", "application/x-font-type1"),
("wma", "audio/x-ms-wma"),
("fpx", "image/vnd.fpx"),
("apk", "application/vnd.android.package-archive"),
("dpg", "application/vnd.dpgraph"),
("wvx", "video/x-ms-wvx"),
("qps", "application/vnd.publishare-delta-tree"),
("karbon", "application/vnd.kde.karbon"),
("wml", "text/vnd.wap.wml"),
("udeb", "application/x-debian-package"),
("pgn", "application/x-chess-pgn"),
("c4p", "application/vnd.clonk.c4group"),
("uvvz", "application/vnd.dece.zip"),
("nns", "application/vnd.noblenet-sealer"),
("rl", "application/resource-lists+xml"),
("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
("rif", "application/reginfo+xml"),
("ms", "text/troff"),
("cu", "application/cu-seeme"),
("xfdl", "application/vnd.xfdl"),
("uvvi", "image/vnd.dece.graphic"),
("aam", "application/x-authorware-map"),
("cdmic", "application/cdmi-container"),
("odc", "application/vnd.oasis.opendocument.chart"),
("boz", "application/x-bzip2"),
("ram", "audio/x-pn-realaudio"),
("asf", "video/x-ms-asf"),
("uvd", "application/vnd.dece.data"),
("ext", "application/vnd.novadigm.ext"),
("swf", "application/x-shockwave-flash"),
("msh", "model/mesh"),
("hbci", "application/vnd.hbci"),
("doc", "application/msword"),
("davmount", "application/davmount+xml"),
("wg", "application/vnd.pmi.widget"),
("zmm", "application/vnd.handheld-entertainment+xml"),
("tfm", "application/x-tex-tfm"),
("iso", "application/x-iso9660-image"),
("ggt", "application/vnd.geogebra.tool"),
("fig", "application/x-xfig"),
("bh2", "application/vnd.fujitsu.oasysprs"),
("rip", "audio/vnd.rip"),
("nnw", "application/vnd.noblenet-web"),
("oa3", "application/vnd.fujitsu.oasys3"),
("p7m", "application/pkcs7-mime"),
("cryptonote", "application/vnd.rig.cryptonote"),
("lnk", "application/x-ms-shortcut"),
("gqs", "application/vnd.grafeq"),
("flv", "video/x-flv"),
("uvm", "video/vnd.dece.mobile"),
("xyz", "chemical/x-xyz"),
("qam", "application/vnd.epson.quickanime"),
("nsf", "application/vnd.lotus-notes"),
("oga", "audio/ogg"),
("flo", "application/vnd.micrografx.flo"),
("grv", "application/vnd.groove-injector"),
("sru", "application/sru+xml"),
("irm", "application/vnd.ibm.rights-management"),
("wpd", "application/vnd.wordperfect"),
("ppam", "application/vnd.ms-powerpoint.addin.macroenabled.12"),
("fh5", "image/x-freehand"),
("hh", "text/x-c"),
("3g2", "video/3gpp2"),
("kpt", "application/vnd.kde.kpresenter"),
("uvvv", "video/vnd.dece.video"),
("texinfo", "application/x-texinfo"),
("zir", "application/vnd.zul"),
("prf", "application/pics-rules"),
("msi", "application/x-msdownload"),
("uvs", "video/vnd.dece.sd"),
("aas", "application/x-authorware-seg"),
("qwt", "application/vnd.quark.quarkxpress"),
("kpr", "application/vnd.kde.kpresenter"),
("nitf", "application/vnd.nitf"),
("ice", "x-conference/x-cooltalk"),
("spl", "application/x-futuresplash"),
("xlw", "application/vnd.ms-excel"),
("ogg", "audio/ogg"),
("obd", "application/x-msbinder"),
("skt", "application/vnd.koan"),
("distz", "application/octet-stream"),
("msf", "application/vnd.epson.msf"),
("prc", "application/x-mobipocket-ebook"),
("bdm", "application/vnd.syncml.dm+wbxml"),
("mpn", "application/vnd.mophun.application"),
("fg5", "application/vnd.fujitsu.oasysgp"),
("edx", "application/vnd.novadigm.edx"),
("tao", "application/vnd.tao.intent-module-archive"),
("ico", "image/x-icon"),
("mdb", "application/x-msaccess"),
("com", "application/x-msdownload"),
("mov", "video/quicktime"),
("sgi", "image/sgi"),
("wbmp", "image/vnd.wap.wbmp"),
("fhc", "image/x-freehand"),
("sfd-hdstx", "application/vnd.hydrostatix.sof-data"),
("cil", "application/vnd.ms-artgalry"),
("xlt", "application/vnd.ms-excel"),
("mpg", "video/mpeg"),
("webp", "image/webp"),
("pfx", "application/x-pkcs12"),
("wks", "application/vnd.ms-works"),
("aw", "application/applixware"),
("hvs", "application/vnd.yamaha.hv-script"),
("xhtml", "application/xhtml+xml"),
("spc", "application/x-pkcs7-certificates"),
("elc", "application/octet-stream"),
("gex", "application/vnd.geometry-explorer"),
("conf", "text/plain"),
("cbr", "application/x-cbr"),
("ktz", "application/vnd.kahootz"),
("uri", "text/uri-list"),
("ac", "application/pkix-attr-cert"),
("ustar", "application/x-ustar"),
("cml", "chemical/x-cml"),
("ris", "application/x-research-info-systems"),
("ics", "text/calendar"),
("n3", "text/n3"),
("vcg", "application/vnd.groove-vcard"),
("dfac", "application/vnd.dreamfactory"),
("install", "application/x-install-instructions"),
("sdp", "application/sdp"),
("mkv", "video/x-matroska"),
("bz2", "application/x-bzip2"),
("uvx", "application/vnd.dece.unspecified"),
("sis", "application/vnd.symbian.install"),
("mcurl", "text/vnd.curl.mcurl"),
("xpw", "application/vnd.intercon.formnet"),
("hps", "application/vnd.hp-hps"),
("odi", "application/vnd.oasis.opendocument.image"),
("dmg", "application/x-apple-diskimage"),
("odm", "application/vnd.oasis.opendocument.text-master"),
("onepkg", "application/onenote"),
("xdp", "application/vnd.adobe.xdp+xml"),
("irp", "application/vnd.irepository.package+xml"),
("cba", "application/x-cbr"),
("ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"),
("dtshd", "audio/vnd.dts.hd"),
("dis", "application/vnd.mobius.dis"),
("xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"),
("xsl", "application/xml"),
("rdf", "application/rdf+xml"),
("mime", "message/rfc822"),
("fsc", "application/vnd.fsc.weblaunch"),
("mscml", "application/mediaservercontrol+xml"),
("mjp2", "video/mj2"),
("mbox", "application/mbox"),
("pct", "image/x-pict"),
("wgt", "application/widget"),
("trm", "application/x-msterminal"),
("rld", "application/resource-lists-diff+xml"),
("roa", "application/rpki-roa"),
("oprc", "application/vnd.palm"),
("atom", "application/atom+xml"),
("sm", "application/vnd.stepmania.stepchart"),
("wmls", "text/vnd.wap.wmlscript"),
("silo", "model/mesh"),
("mpm", "application/vnd.blueice.multipass"),
("xer", "application/patch-ops-error+xml"),
("sdw", "application/vnd.stardivision.writer"),
("z8", "application/x-zmachine"),
("spot", "text/vnd.in3d.spot"),
("hpgl", "application/vnd.hp-hpgl"),
("bcpio", "application/x-bcpio"),
("arc", "application/x-freearc"),
("teicorpus", "application/tei+xml"),
("nfo", "text/x-nfo"),
("rs", "application/rls-services+xml"),
("pcf", "application/x-font-pcf"),
("xpm", "image/x-xpixmap"),
("sse", "application/vnd.kodak-descriptor"),
("gtar", "application/x-gtar"),
("ifb", "text/calendar"),
("kar", "audio/midi"),
("c4g", "application/vnd.clonk.c4group"),
("x3dvz", "model/x3d+vrml"),
("kfo", "application/vnd.kde.kformula"),
("m2a", "audio/mpeg"),
("res", "application/x-dtbresource+xml"),
("wmx", "video/x-ms-wmx"),
("apr", "application/vnd.lotus-approach"),
("movie", "video/x-sgi-movie"),
("au", "audio/basic"),
("ims", "application/vnd.ms-ims"),
("s3m", "audio/s3m"),
("igs", "model/iges"),
("mp21", "application/mp21"),
("ra", "audio/x-pn-realaudio"),
("afp", "application/vnd.ibm.modcap"),
("djvu", "image/vnd.djvu"),
("pls", "application/pls+xml"),
("meta4", "application/metalink4+xml"),
("flw", "application/vnd.kde.kivio"),
("cdmid", "application/cdmi-domain"),
("book", "application/vnd.framemaker"),
("gramps", "application/x-gramps-xml"),
("oth", "application/vnd.oasis.opendocument.text-web"),
("dvb", "video/vnd.dvb.file"),
("fbs", "image/vnd.fastbidsheet"),
("emf", "application/x-msmetafile"),
("pgp", "application/pgp-encrypted"),
("list3820", "application/vnd.ibm.modcap"),
("pcl", "application/vnd.hp-pcl"),
("wmlc", "application/vnd.wap.wmlc"),
("svd", "application/vnd.svd"),
("blorb", "application/x-blorb"),
("oda", "application/oda"),
("lha", "application/x-lzh-compressed"),
("zip", "application/zip"),
("npx", "image/vnd.net-fpx"),
("xpr", "application/vnd.is-xpr"),
("ppsm", "application/vnd.ms-powerpoint.slideshow.macroenabled.12"),
("mft", "application/rpki-manifest"),
("inkml", "application/inkml+xml"),
("csh", "application/x-csh"),
("btif", "image/prs.btif"),
("gdl", "model/vnd.gdl"),
("ftc", "application/vnd.fluxtime.clip"),
("mts", "model/vnd.mts"),
("ggb", "application/vnd.geogebra.file"),
("def", "text/plain"),
("ttf", "application/x-font-ttf"),
("hpid", "application/vnd.hp-hpid"),
("nbp", "application/vnd.wolfram.player"),
("fm", "application/vnd.framemaker"),
("otc", "application/vnd.oasis.opendocument.chart-template"),
("xfdf", "application/vnd.adobe.xfdf"),
("mgp", "application/vnd.osgeo.mapguide.package"),
("vss", "application/vnd.visio"),
("xpx", "application/vnd.intercon.formnet"),
("lzh", "application/x-lzh-compressed"),
("fli", "video/x-fli"),
("twd", "application/vnd.simtech-mindmapper"),
("fly", "text/vnd.fly"),
("h", "text/x-c"),
("mpga", "audio/mpeg"),
("tiff", "image/tiff"),
("esf", "application/vnd.epson.esf"),
("cdmiq", "application/cdmi-queue"),
("vsf", "application/vnd.vsf"),
("link66", "application/vnd.route66.link66+xml"),
("rpst", "application/vnd.nokia.radio-preset"),
("txt", "text/plain"),
("w3d", "application/x-director"),
("ufdl", "application/vnd.ufdl"),
("pwn", "application/vnd.3m.post-it-notes"),
("svc", "application/vnd.dvb.service"),
("pcx", "image/x-pcx"),
("sbml", "application/sbml+xml"),
("ser", "application/java-serialized-object"),
("skp", "application/vnd.koan"),
("mpg4", "video/mp4"),
("metalink", "application/metalink+xml"),
("ncx", "application/x-dtbncx+xml"),
("avi", "video/x-msvideo"),
("pps", "application/vnd.ms-powerpoint"),
("java", "text/x-java-source"),
("midi", "audio/midi"),
("dump", "application/octet-stream"),
("hdf", "application/x-hdf"),
("xlf", "application/x-xliff+xml"),
("see", "application/vnd.seemail"),
("ghf", "application/vnd.groove-help"),
("hqx", "application/mac-binhex40"),
("lbe", "application/vnd.llamagraphics.life-balance.exchange+xml"),
("sfv", "text/x-sfv"),
("portpkg", "application/vnd.macports.portpkg"),
("ez3", "application/vnd.ezpix-package"),
("vrml", "model/vrml"),
("m3u", "audio/x-mpegurl"),
("viv", "video/vnd.vivo"),
("jar", "application/java-archive"),
("latex", "application/x-latex"),
("xdm", "application/vnd.syncml.dm+xml"),
("caf", "audio/x-caf"),
("m1v", "video/mpeg"),
("z2", "application/x-zmachine"),
("jpe", "image/jpeg"),
("rpss", "application/vnd.nokia.radio-presets"),
("snd", "audio/basic"),
("xhvml", "application/xv+xml"),
("sgl", "application/vnd.stardivision.writer-global"),
("gam", "application/x-tads"),
("lbd", "application/vnd.llamagraphics.life-balance.desktop"),
("wbs", "application/vnd.criticaltools.wbs+xml"),
("cgm", "image/cgm"),
("uvt", "application/vnd.dece.ttml+xml"),
("setreg", "application/set-registration-initiation"),
("sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"),
("grxml", "application/srgs+xml"),
("azw", "application/vnd.amazon.ebook"),
("xla", "application/vnd.ms-excel"),
("xsm", "application/vnd.syncml+xml"),
("sema", "application/vnd.sema"),
("iota", "application/vnd.astraea-software.iota"),
("sda", "application/vnd.stardivision.draw"),
("asm", "text/x-asm"),
("kml", "application/vnd.google-earth.kml+xml"),
("pdb", "application/vnd.palm"),
("xo", "application/vnd.olpc-sugar"),
("curl", "text/vnd.curl")
])


text:
#TODO Test with standard generated graphs from IIF
# Add some nodes.
v1 = addVariable!(dfg, :a, ContinuousScalar, tags = [:POSE])
addFactor!(dfg, [:a], Prior(Normal(0,1)))
v2 = addVariable!(dfg, :b, ContinuousScalar, tags = [:POSE])
v3 = addVariable!(dfg, :c, ContinuousScalar, tags = [:LANDMARK])
f1 = addFactor!(dfg, [:a; :b], LinearRelative(Normal(50.0,2.0)) )
f2 = addFactor!(dfg, [:b; :c], LinearRelative(Normal(50.0,2.0)) )

# Solve it
tree = solveTree!(dfg)

ext: jl


text:
#-----------Sql-------------------
"""
    function SqlSourceParameters(datastorename::String,tablename::String;sqlwhereclause::Union{String,Void}=nothing)
"""
type SqlSourceParameters <: AbstractSourceParameters
    DataStoreName::String
    TableName::String
    SqlWhereClause::Union{String,Void}
    function SqlSourceParameters(datastorename::String,tablename::String;sqlwhereclause::Union{String,Void}=nothing)
        new(datastorename,tablename,sqlwhereclause)
    end
end

"""
    function SqlSinkParameters(datastorename::String,tablename::String;expressions::Union{Array{String,1},Void}=nothing,whereclause::Union{String,Void}=nothing)
"""
type SqlSinkParameters <: AbstractSinkParameters
    DataStoreName::String
    TableName::String
    Expressions::Union{Array{String,1},Void}
    WhereClause::Union{String,Void}
    function SqlSinkParameters(datastorename,tablename;expressions=nothing,whereclause=nothing)
        new(datastorename,tablename,expressions,whereclause)
    end
end

function sinktosource(sink::SqlSinkParameters,response::AbstractStreamResponse)::SqlSourceParameters
    return SqlSourceParameters(sink.DataStoreName,sink.TableName)
end

#-----------NotebookCsv----------------
"""
    function CsvNotebookFileShareSourceParameters(filename::String,datastartrow::Int,headers::Array{String,1},types::Array{String,1})
    Source and Sink data types can be found through NeuroData.getdatatypes()
"""
type CsvNotebookFileShareSourceParameters <: AbstractSourceParameters
    FileName::String
    DataStartRow::Int
    Headers::Array{String,1}
    Types::Array{String,1}
    function CsvNotebookFileShareSourceParameters(filename,datastartrow,headers,types)
        filename=strip(replace(strip(pwd(),'/'),strip(NeuroJulia.homedir,'/'),"")*"/"*strip(filename,'/'),'/')
        if !isfile("/"*strip(NeuroJulia.homedir,'/')*"/"*filename)
            error("File doesn't exitst")
        end
        new(filename,datastartrow,headers,types)
    end
end

"""
    function CsvNotebookFileShareSinkParameters(filename::String,headers::Array{String,1},types::Array{String,1};expressions::Union{Array{String,1},Void}=nothing,whereclause::Union{String,Void}=nothing)
    Source and Sink data types can be found through NeuroData.getdatatypes()
"""
type CsvNotebookFileShareSinkParameters <: AbstractSinkParameters
    FileName::String
    Headers::Array{String,1}
    Types::Array{String,1}
    Expressions::Union{Array{String,1},Void}
    WhereClause::Union{String,Void}
    function CsvNotebookFileShareSinkParameters(filename,headers,types;expressions=nothing,whereclause=nothing)
        filename=strip(replace(strip(pwd(),'/'),strip(NeuroJulia.homedir,'/'),"")*"/"*strip(filename,'/'),'/')
        new(filename,headers,types,expressions,whereclause)
    end
end

function sinktosource(sink::CsvNotebookFileShareSinkParameters,response::AbstractStreamResponse)::CsvNotebookFileShareSourceParameters
    return CsvNotebookFileShareSourceParameters(sink.FileName,2,sink.Headers,sink.Types)
end

#----------DataLakeCsv-----------------
"""
    function CsvDataLakeSourceParameters(datastorename::String,tablename::String,filename_including_partition::String,datastartrow::Int)
"""
type CsvDataLakeSourceParameters <: AbstractSourceParameters
    DataStoreName::String
    TableName::String
    FileName::String
    DataStartRow::Int
    function CsvDataLakeSourceParameters(datastorename,tablename,filename_including_partition,datastartrow)
        table_def=get_table_definition(storename=datastorename,tablename=tablename)
        schematype=filter(tuple->last(tuple)==table_def.SchemaType,collect(schema_type_map))[1][1]
        filename=lowercase("/managed/$schematype/table/$tablename/")*strip(filename_including_partition,'/')
        new(datastorename,tablename,filename,datastartrow)
    end
end

"""
    function CsvDataLakeSinkParameters(datastorename::String,tablename::String,partitionpath::String;expressions::Union{Array{String,1},Void}=nothing,whereclause::Union{String,Void}=nothing)
"""
type CsvDataLakeSinkParameters <: AbstractSinkParameters
    DataStoreName::String
    TableName::String
    FolderPath::String
    Expressions::Union{Array{String,1},Void}
    WhereClause::Union{String,Void}
    function CsvDataLakeSinkParameters(datastorename,tablename,partitionpath;expressions=nothing,whereclause=nothing)
        table_def=get_table_definition(storename=datastorename,tablename=tablename)
        schematype=filter(tuple->last(tuple)==table_def.SchemaType,collect(schema_type_map))[1][1]
        folderpath=lowercase("/managed/$schematype/table/$tablename/"*strip(partitionpath,'/'))
        new(datastorename,tablename,folderpath,expressions,whereclause)
    end
end

function sinktosource(sink::CsvDataLakeSinkParameters,response::AbstractStreamResponse)::CsvDataLakeSourceParameters
    fileName=sink.FolderPath * "/" * response.JobId * "_" * replace(replace(response.TimeStamp,":","-"),".","-") * ".csv"
    fileName=split(fileName,lowercase(sink.TableName))[2]
    return CsvDataLakeSourceParameters(sink.DataStoreName,sink.TableName,fileName,1)
end

#----------ExternalSql-------------
"""
    function ExternalSqlSourceParameters(tablename::String,connectionstring::String)
"""
type ExternalSqlSourceParameters <: AbstractSourceParameters
    TableName::String
    ConnectionString::String
end

max_stars_repo_name: SnowdenNeuroverse/NeuroJulia

max_issues_repo_name: SnowdenNeuroverse/NeuroJulia

max_forks_repo_name: SnowdenNeuroverse/NeuroJulia


text:
@testset "lx nesting nomaths" begin
    t = raw"""
        \newcommand{\bar}[1]{A!#1A}
        \newcommand{\dtan}[1]{\bar{!#1}}
        \newcommand{\baz}[2]{#1 / #2}
        \baz{\dtan{x}}{x}
        """ |> fd2html
    @test isapproxstr(t, "AxA / x")
end

@testset "lx nesting maths" begin
    s = raw"""
        \newcommand{\dtan}[1]{\dot{#1}}
        $$\frac{\dtan{a}}{b}$$
        """ |> fd2html
    @test isapproxstr(s, raw"\[\frac{\dot{a}}{b}\]")

    s = raw"""
        \newcommand{\ip}[2]{\langle #1, #2 \rangle}
        $$\ip{\dot{a}}{\dot{b}}$$
        """ |> fd2html
    @test isapproxstr(s, raw"\[\langle \dot{a}, \dot{b} \rangle\]")
end


text:
using NamedTupleTools: namedtuple

ntkeys(::Type{NamedTuple{K,V}}) where {K, V} = K
ntvaltype(::Type{NamedTuple{K,V}}) where {K, V} = V

"""
    fromtype(::Type)

`fromtype` turns a type into a value that's easier to work with.

Example:

    julia> nt = (a=(b=[1,2],c=(d=[3,4],e=[5,6])),f=[7,8]);

    julia> NT = typeof(nt)
    NamedTuple{(:a, :f),Tuple{NamedTuple{(:b, :c),Tuple{Array{Int64,1},NamedTuple{(:d, :e),Tuple{Array{Int64,1},Array{Int64,1}}}}},Array{Int64,1}}}

    julia> fromtype(NT)
    (a = (b = Array{Int64,1}, c = (d = Array{Int64,1}, e = Array{Int64,1})), f = Array{Int64,1})
"""
function fromtype end

function fromtype(NT::Type{NamedTuple{names, T}}) where {names, T}
    return namedtuple(ntkeys(NT), fromtype(ntvaltype(NT)))
end

function fromtype(TT::Type{T}) where {T <: Tuple}
    return fromtype.(Tuple(TT.types))
end

fromtype(T) = T


text:
# https://docs.julialang.org/en/stable/manual/variables/
x = 1
y = "string"
z = "α Unicode string"
β = 2.72
println(pi)
const ⊗ = kron
A = ones(2,2)
B = reshape([0:3...].+1, 2, 2)
println(A)
println(B)
println(A ⊗ B)

max_stars_repo_name: cdluminate/MyNotes

max_issues_repo_name: cdluminate/MyNotes

max_forks_repo_name: cdluminate/MyNotes


text:
# Tests for perturb.jl

test_pocket_r_filepath = testfile("1DVM_pocket_r.pdb")
test_pocket_all_filepath = testfile("1DVM_pocket_all.pdb")

@testset "Perturb" begin
    atom_one = Atom("N", "ALA", 'A', 20, [0.0, 0.0, 0.0], "N")
    atom_two = Atom("CA", "ALA", 'A', 20, [0.0, 1.0, 0.0], "C")
    atom_thr = Atom("C", "ALA", 'A', 20, [1.0, 1.0, 0.0], "C")
    atoms = [atom_one, atom_two, atom_thr]
    lower = [0.9, 0.9]
    upper = [1.1, 1.1]
    pres_inds = [
        2 1;
        3 2;
    ]
    constraints = Constraints(atoms, lower, upper, pres_inds)
    mod_coords = [
        0.5 1.5;
        -0.5 0.5;
        0.0 0.0;
    ]
    new_constraints = Constraints(atoms, constraints, mod_coords, intra_cutoff=1000.0,
        intra_tolerance=0.1, inter_cutoff=1.0, inter_tolerance=0.1)
    @test length(new_constraints.atoms) == 5
    @test new_constraints.atoms[4].res_name == mod_atom_info["res_name"]
    real_lower = [
        0.9,
        0.9,
        sqrt(2) - 0.1,
        sqrt(2) * 0.5 - 0.1,
        sqrt(2) * 0.5 - 0.1,
    ]
    real_upper = [
        1.1,
        1.1,
        sqrt(2) + 0.1,
        sqrt(2) * 0.5 + 0.1,
        sqrt(2) * 0.5 + 0.1,
    ]
    @test isapprox(new_constraints.lower, real_lower)
    @test isapprox(new_constraints.upper, real_upper)
    @test new_constraints.pres_inds == [
        2 1;
        3 2;
        5 4;
        4 1;
        5 3;
    ]

    pock_points = [
        1.0 2.0;
        3.0 4.0;
        5.0 6.0;
    ]
    mod_coords = repeatpocketpoints(pock_points)
    @test size(mod_coords) == (3,defaults["mod_n_points"])
    @test defaults["mod_n_points"] < 4 || mod_coords[:,1:4] == [
        1.0 2.0 1.0 2.0;
        3.0 4.0 3.0 4.0;
        5.0 6.0 5.0 6.0;
    ]
    pock_points = [1.0, 2.0, 3.0]
    mod_coords = repeatpocketpoints(pock_points)
    @test mod_coords == repeat([1.0; 2.0; 3.0], inner=[1,defaults["mod_n_points"]])
    pock_points = ones(3, 2*defaults["mod_n_points"])
    mod_coords = repeatpocketpoints(pock_points)
    @test mod_coords == ones(3, defaults["mod_n_points"])

    temp_filepath = tempname()
    clusterligsite(test_pocket_r_filepath, test_pocket_all_filepath, temp_filepath)
    rm(temp_filepath)
end


text:
using HorizonSideRobots

#--------- ИСПОЛЬЗУЕМЫЕ "БИБЛИОТЕЧНЫЕ" ФУНКЦИИ ДЛЯ ТИПА HorizonSideRobots.HorizonSide:

inverse(side::HorizonSide) = HorizonSide(mod(Int(side)+2, 4))
left(side::HorizonSide) = HorizonSide(mod(Int(side)+1, 4))
right(side::HorizonSide) = HorizonSide(mod(Int(side)-1, 4))

#---------------- ВСПОМОГАТЕЛЬНЫЙ КОНКРЕТНЫЙ ТИП Coord: -----------------------------

mutable struct Coord   # supertype(Coord) == Any
    x::Int
    y::Int
end

Coord() = Coord(0,0)
# - это определение внешнего (вне структуры) конструктора типа CoordRobot (для удобства использования),
#   где Coord(0,0) - это конструктор по умолчанию

import HorizonSideRobots: move!
# !!! этот импорт необходим для обеспечения возможности переопределения функции move!, которая уже определена в пакете HorizonSideRobots,
#   и который мы собираемся использовать, для нового типа (Coord)
#   Если этого не сделать, то при использовании пакета HorizonSideRobots возникнет конфликт имён.
#

function move!(coord::Coord, side::HorizonSide)
    if side==Nord
        coord.y += 1
    elseif side==Sud
        coord.y -= 1
    elseif side==Ost
        coord.x += 1
    elseif side==West
        coord.x -= 1
    end
    nothing
end

get_coord(coord::Coord) = (coord.x, coord.y)

#----------------------- ИЕРАРХИЯ ПРОЕКТИРУЕМЫХ ТИПОВ: ------------------------------
#=
Any:
|           try_move!
|           movements! - перемещает робота в заданном направлении (4 разных метода)
|           shuttle! - перемещает робота "челноком" с увеличением амплитуды до тех пор, пока не выполнится некорое заданное условие
|           spiral! - перемещает робота по раскручивающейся спирали до тех пор, пока не выполнится некорое заданное условие
|           snake!  - (2 метода) перемещает робота "змейкой" (по верикальным или по горизонтальным рядам)
|                     до тех пор, пока не будет пройдено все поле, или пока не выполнится некорое заданное условие
|
| # КОНКРЕТНЫЕ ТИПЫ:
|
|-- CoordRobot (тип робота, при перемещениях отслеживающего свои координаты):
|           move!, isborder, putmarker!, ismarker, temperature - стандартный интерфейс робота
|           get_coord - возвращает текущие координаты робота
|
| # КОНКРЕТНЫЕ ПАРАМЕТРИЧЕСКИЕ ТИПЫ:
|
|-- BorderRobot{TypeRobot}
|       (здесь TypeRobot - это формальный параметр;
|        cответствующий фактический параметр, например, может быть равен или SimpleRobot, или CoordRobot)
|
|           try_move! - переопредяляемая функция, обеспечивающая обход простых (прямолинейных) или прямоугольных перегородок
|           (после каждой удачной попытки сделать щаг в заданном направлении, вызывающая функцию action!(), )
|
|--
|       (здесь TypeRobot - это формальный параметр;
|       cответствующий фактический параметр, например, может быть равен или SimpleRobot, или CoordRobot, или BorderRobot{SimpleRobot},
|       или BorderRobot{CoordRobot})
|
|-- CountmarkersRobot{TypeRobot}
|
|-- MarkersCoordsRobot{TypeRobot}

=#

#------------------- ОБОБЩЕННЫЕ ФУНКЦИИ: ------------------------
"""
try_move!(robot, side)::Bool

-- перемещает робота на 1 шаг в заданном направлении, если это возможно, в этом случае возвращает true, в противном - false
"""
function try_move!(robot, side)::Bool
    if isborder(robot, side) # - это вызов виртуальной функции (кторая реально будет определена в каком-то из производных типов)
        false
    else
        move!(robot, side) # - это вызов виртуальной функции (кторая реально будет определена в каком-то из производных типов)
        true
    end
end

"""
movements!(robot, side)

-- перемещает робота в заданном направлении "до упора" (пока возможно) и возвращает число сделанных шагов
"""
function movements!(robot, side)
    n=0

    while try_move!(robot, side)
        n += 1
    end

    return n
end

"""
movements!(robot, side)

-- перемещает робота в заданном не более чем на max_num_steps шагов, пока это возможно, и возвращает число сделанных шагов
"""
function movements!(robot, side, max_num_steps::Integer)
    n=0
    while n < max_num_steps && try_move!(robot, side) # - в этом логическом выражении порядок аргументов важен!
        n += 1
    end
    return n
end

"""
movements!(stop_condition::Function, robot, side, max_num_steps)

-- делает не более чем max_num_steps шагов в заданном направлении, пока выпоняется условие !stop_condition()==true",
и возвращает число сделанных шагов

-- stop_condition - функция без аргументов, возвращающая логическое значение, определяет условие останова
"""
function movements!(stop_condition::Function, robot, side, max_num_steps)
    n = 0
    while n < max_num_steps && !stop_condition() && try_move!(robot, side) # - в этом логическом выражении порядок аргументов важен!
        n += 1
    end
    return n
end

"""
movements!(stop_condition::Function, robot, side)

-- перемещает робота в заданном направлении пока возможен try_move! и пока выпоняется условие !stop_condition()==true",
и возвращает число сделанных шагов

-- stop_condition - функция без аргументов, возвращающая логическое значение
"""
function movements!(stop_condition::Function, robot, side)
    n=0
    while !stop_condition() && try_move!(robot,side)
        n += 1
    end
    return n
end

"""
shuttle!(stop_condition::Function, robot, side)

- перемещает робота "туда-сюда" (челноком), с увеличением амплитуды, до тех пор пока не выполнится условие condition()
- side - начальное направление перемещений
"""
function  shuttle!(stop_condition::Function, robot, side)
    n=0 # число шагов от начального положения
    while !stop_condition()  # condition(robot) - как вариант
        n += 1
        movements!(() -> !stop_condition(), robot, side, n)
        side = inverse(side)
    end
end

"""
spiral!(condition::Function, robot, side=Nord)

- перемещает робота по раскручивающейся спипали (влево), до тех пор пока не выполнится условие condition()

- condition - это condition(::HorizonSide)::Bool

- side - начальное направление перемещений

"""
function spiral!(condition::Function, robot, side = Nord)
    n=1
    while true
        movements!(() -> !condition(side), robot, side, n)
        if condition(side)
            return
        end
        side = left(side)
        movements!(() -> !condition(side), robot, side, n)
        if condition(side)
            return
        end
        side = left(side)
        n += 1
    end
end

"""
snake!(stop_condition::Function, robot, (next_row_side, move_side)::NTuple{2,HorizonSide} = (Nord, Ost))

-- выполняет движение зиейкой пока пока не выполнено условие останова (или не пройденны все ряды в направлении next_row_side)

stop_condition - функция без ургумента, возвращающая логическое значение, определяет условие останова при движении змейкой

"""
function snake!(stop_condition::Function, robot, (next_row_side, move_side)::NTuple{2,HorizonSide} = (Nord, Ost)) # - это обобщенная функция
    # Робот - в (inverse(next_row_side), inverse(move_side)) - углу поля
    movements!(stop_condition, robot, move_side)
    while !stop_condition() && try_move!(robot, next_row_side)
        move_side = inverse(move_side)
        movements!(stop_condition, robot, move_side)
    end
end

"""
snake!(robot, (next_row_side, move_side)::NTuple{2,HorizonSide} = (Nord, Ost))

-- перемещает робта "зиейкой" пока не будут пройденны все ряды в направлении next_row_side
"""
function snake!(robot, (next_row_side, move_side)::NTuple{2,HorizonSide}=(Nord, Ost)) # - это обобщенная функция
    # Робот - в (inverse(next_row_side), inverse(move_side)) - углу поля
    snake!(() -> false, robot, (next_row_side, move_side))
end
#----------------------- КОНКРЕТНЫЙ ТИП CoordRobot: ----------------------

struct CoordRobot
    robot::Robot
    coord::Coord
end

# Тип CoordRobot представляет собой КОМПОЗИЦИЮ типов.
# Это есть альтернатива множественному наследованию, которого в языке Julia нет.

import HorizonSideRobots: move!, isborder, putmarker!, ismarker, temperature

function move!(robot::CoordRobot, side)
    move!(robot.robot, side)
    move!(robot.coord, side)
end

isborder(robot::CoordRobot, side) = isborder(robot.robot, side)
putmarker!(robot::CoordRobot) = putmarker!(robot.robot)
ismarker(robot::CoordRobot) = ismarker(robot.robot)
temperature(robot::CoordRobot) = temperature(robot.robot)

get_coord(robot::CoordRobot) = robot.coord

#-------------------- КОНКРЕТНЫЕ ПАРАМЕТРИЧЕСКИЕ ТИПЫ: -----------------------------

# Конкретный ПАРАМЕТРИЧЕСКИЙ тип BorderRobot{TypeRobot}:

import HorizonSideRobots: move!, isborder, putmarker!, ismarker, temperature

struct BorderRobot{TypeRobot}  # TypeRobot = Robot | CoordRobot | ...?
    robot::TypeRobot
end
# robot= BorderRobot{TypeRobot}(robot_of_TypeRobot)

#get(robot::BorderRobot) = robot.robot

"""
try_move!(robot::BorderRobot, side::HorizonSide)::Bool

-- делает попытку прямолинейного перемещение робота в заданном направлении, в случае необходимости пытаясь обойти внутреннюю прямолинейную
или прямоугольную перегородку, и возвращает, в случае успеха, значение true, или значение - false, если робот упирается во внешнюю рамку
"""
function try_move!(robot::BorderRobot, side::HorizonSide)::Bool
    ort_side = left(side)
    n = movements!(() -> !isborder(robot.robot, side), robot.robot, ort_side)
    if isborder(r, side)
        movements!(robot.robot, inverse(ort_side), n)
        return false
    end
    move!(robot.robot, side)
    if n > 0
        movements!(() -> !isborder(robot.robot, inverse(ort_side)), robot.robot, side)
        movements!(robot.robot, inverse(ort_side), n)
    end
    return true
end

import HorizonSideRobots: move!, isborder, putmarker!, ismarker, temperature

move!(robot::BorderRobot,side) = move!(robot.robot,side)
isborder(robot::BorderRobot, side) = isborder(robot.robot, side)
putmarker!(robot::BorderRobot) = putmarker!(robot.robot)
ismarker(robot::BorderRobot) = ismarker(robot.robot)
temperature(robot::BorderRobot) = temperature(robot.robot)

#=
Поскольку от фактического параметра TypeRobot типа BorderRobot реализация функции try_move! в данном случае не зависит, то
в аннотации типа аргумента robot значение параметра TypeRobot не указано.

ЗАМЕЧАНИЕ.

В принципе, при определении данной функции, указать на то, что фактическое значение параметра типа может быть любым, можно было бы ещё и
используюя ключевое слово where:

function try_move!(robot::BorderRobot{TypeRobot}, side::HorizonSide)::Bool where TypeRobot
    ...
end

И это было бы в точности то же самое, но в данном конкретном случае лучше обойтись просто без указания параметра.

Использование же ключевого слова where бы оправдано, например, в ситуации, когда определяемая функция имеет 2 аргумента
параметрического типа, и необходимо указать, что значения параметра типа и там и там должно быть одно и тоже (хотя и не конкретным):

function f(x::Rational{T}, y::Rational{T}) where {T <: Unsigned}
    ...
end
=#

#--------------------- Конкретный ПАРАМЕТРИЧЕСКИЙ тип PutmarkerRobot: ---------------------

struct PutmarkersRobot{TypeRobot} # TypeRobot = Robot | CoordRobot | ...?
    robot::TypeRobot
end

get(robot::PutmarkersRobot) = robot.robot

function try_move!(robot::PutmarkersRobot, side)::Bool
    result = try_move!(robot.robot, side)
    if result
        putmarker!(robot.robot) # предполагается, что для каждого возможного конкретного типа TypeRobot определен метод putmarker!
    end
    return result
end

import HorizonSideRobots: move!, isborder, putmarker!, ismarker, temperature

move!(robot::PutmarkersRobot,side) = move!(robot.robot,side)
isborder(robot::PutmarkersRobot, side) = isborder(robot.robot, side)
putmarker!(robot::PutmarkersRobot) = putmarker!(robot.robot)
ismarker(robot::PutmarkersRobot) = ismarker(robot.robot)
temperature(robot::PutmarkersRobot) = temperature(robot.robot)

#------------------ Конкретный ПАРАМЕТРИЧЕСКИЙ тип CountmarkersRobot: ------------------------------

mutable struct CountmarkersRobot{TypeRobot}
    robot::TypeRobot
    count::Int
end
# TypeRobot = Robot | CoordRobot | BorderRobot{Robot} | BorderRobot{CoordRobot} | ...?

CountmarkersRobot{TypeRobot}(r::Robot) where TypeRobot =  CountmarkersRobot{TypeRobot}(TypeRobot(r))
# определять этот внешний конструктор не обязательно, это сделано просто для удобства использования, см. также замечание ниже.

function move!(robot::CountmarkersRobot, side)
    if try_move!(robot.robot, side)
        robot.count += 1
    end
end

get_num_markers(robot::CountmarkersRobot) = robot.count

#--------------- Конкретный ПАРАМЕТРИЧЕСКИЙ тип MarkersCoordsRobot: ------------------------------

mutable struct MarkersCoordsRobot{TypeRobot}
    robot::TypeRobot
    coord::Vector{NTuple{2,Int}}
end
# TypeRobot = CoordRobot | BorderRobot{CoordRobot} | ...?

# Предполагается использовать только конструктор по умолчанию

function move!(robot::MarkersCoordsRobot, side)
    if try_move!(robot.robot, side) && ismarker(robot.robot)
        push!(robot.count, get_coord(robot.robot))
    end
end

get_coord(robot::MarkersCoordsRobot) = robot.coord

#-----------------------------------

max_stars_repo_name: AntonDudDm/mirea-progs

max_issues_repo_name: AntonDudDm/mirea-progs

max_forks_repo_name: AntonDudDm/mirea-progs


text:
macro ce_curl(f, handle, args...)
  local esc_args = [esc(arg) for arg in args]
  quote
    cc = $(esc(f))($(esc(handle)), $(esc_args...))

    if cc != CURLE_OK
      err = unsafe_string(curl_easy_strerror(cc))
      error(string($f) * "() failed: " * err)
    end
  end
end

macro ce_curlm(f, handle, args...)
  local esc_args = [esc(arg) for arg in args]
  quote
    cc = $(esc(f))($(esc(handle)), $(esc_args...))

    if cc != CURLM_OK
      err = unsafe_string(curl_multi_strerror(cc))
      error(string($f) * "() failed: " * err)
    end
  end
end

function set_opt_blocking(o::SendOptions)
  o2 = deepcopy(o)
  o2.blocking = true
  o2
end

function setup_easy_handle(url, options::SendOptions)
  ctxt = ConnContext(options)

  curl = curl_easy_init()
  curl == C_NULL && throw("curl_easy_init() failed")

  ctxt.curl = curl

  ctxt.url = url

  @ce_curl curl_easy_setopt curl CURLOPT_URL url
  @ce_curl curl_easy_setopt curl CURLOPT_WRITEFUNCTION c_curl_write_cb
  @ce_curl curl_easy_setopt curl CURLOPT_WRITEDATA ctxt
  @ce_curl curl_easy_setopt curl CURLOPT_UPLOAD 1

  if options.isSSL
    @ce_curl curl_easy_setopt curl CURLOPT_USE_SSL CURLUSESSL_ALL
  end

  if !isempty(options.username)
    @ce_curl curl_easy_setopt curl CURLOPT_USERNAME options.username
    @ce_curl curl_easy_setopt curl CURLOPT_PASSWORD options.passwd
  end

  ctxt
end

cleanup_easy_context(::Bool) = nothing

function cleanup_easy_context(ctxt::ConnContext)
  if (ctxt.curl != C_NULL)
    curl_easy_cleanup(ctxt.curl)
  end

  if ctxt.close_ostream
    close(ctxt.resp.body)
    ctxt.resp.body = nothing
    ctxt.close_ostream = false
  end
end

function process_response(ctxt)
  http_code = Array{Int}(undef, 1)
  @ce_curl curl_easy_getinfo ctxt.curl CURLINFO_RESPONSE_CODE http_code

  total_time = Array{Float64}(undef, 1)
  @ce_curl curl_easy_getinfo ctxt.curl CURLINFO_TOTAL_TIME total_time

  ctxt.resp.code = http_code[1]
  ctxt.resp.total_time = total_time[1]
end


text:
using Documenter, RateLimiter

makedocs(
    modules = [RateLimiter],
    sitename="RateLimiter.jl",
    authors = "Chip Kent",
    format = Documenter.HTML(),
)

deploydocs(
    repo = "github.com/chipkent/RateLimiter.jl.git",
    devbranch = "main",
    push_preview = true,
)


text:
struct WeightNormRBM{V<:AbstractLayer, H<:AbstractLayer, G<:AbstractArray, U<:AbstractArray}
    visible::V
    hidden::H
    g::G # weight norms for each hidden unit
    u::U # weight (unormalized) directions
    function WeightNormRBM(visible::AbstractLayer, hidden::AbstractLayer, g::AbstractArray, u::AbstractArray)
        @assert all(size(g)[1:ndims(visible)] .== 1)
        @assert size(g)[(ndims(visible) + 1):end] == size(hidden)
        @assert size(u) == (size(visible)..., size(hidden)...)
        return new{typeof(visible), typeof(hidden), typeof(g), typeof(u)}(visible, hidden, g, u)
    end
end

function RBMs.RBM(wrbm::WeightNormRBM)
    w, _ = gu2w(wrbm.g, wrbm.u)
    return RBMs.RBM(wrbm.visible, wrbm.hidden, w)
end

function WeightNormRBM(rbm::RBM, un::AbstractArray)
    g, u = w2gu(rbm.w, un)
    return WeightNormRBM(rbm.visible, rbm.hidden, g, u)
end

function WeightNormRBM(rbm::RBM)
    g = weight_norms(rbm)
    u = copy(rbm.w)
    return WeightNormRBM(rbm.visible, rbm.hidden, g, u)
end

"""
    weight_norms(rbm)

Norms of weight patterns attached to each hidden unit.
"""
weight_norms(rbm::RBM) = sqrt.(sum(abs2, rbm.w; dims=1:ndims(rbm.visible)))

function RBMs.∂free_energy(
    wrbm::WeightNormRBM, v::AbstractArray; wts = nothing,
    stats = RBMs.sufficient_statistics(wrbm.visible, v; wts)
)
    ∂ = RBMs.∂free_energy(RBM(wrbm), v; wts, stats)
    ∂g, ∂u = ∂wnorm(∂.w, wrbm.g, wrbm.u)
    return (visible = ∂.visible, hidden = ∂.hidden, g = ∂g, u = ∂u)
end


text:
module TestStuff

include("StarStuff.jl")
using .StarStuff
# using Gtk
# js"""
# function(){
#     function clearactive(item,index){

#     }
#     let thisindex = 1;
#     let tablist = ['particles','bfield','sim','plot'];
#     let thisid = tablist[thisindex];
#     let thistab = document.getElementById(thisid);
#     for (let iname in tablist){
#         let itab = document.getElementById(iname);
#         itab.classList.remove('is-active');
#     }

#     alert('test');

#     thistab.classList.add('is-active');
# }
# """

function run()
    a = Vector([1.,2.,3.])
    b = Vector([4.,5.,6.])

    c = ArrayPartition(a,b)
    d = Coords(c)
    println(d)

    # win = GtkWindow("My First Gtk.jl Program", 400, 200)

    # b = GtkButton("Click Me")
    # push!(win,b)

    # function on_button_clicked(w)
    #   println("The button has been clicked")
    # end
    # signal_connect(on_button_clicked, b, "clicked")

    # Gtk.showall(win)
    # appdir = joinpath(@__DIR__,"..","app")
    # bulma  = joinpath(appdir,"bulma.css")
    # uijs   = joinpath(appdir,"ui.js")
    # WNode  = WebIO.Node
    # w = Window(async=false)
    # load!(w,bulma)
    # load!(w,uijs)
    # tabitems = WNode(
    #     :ul,
    #     WNode(:li,
    #         WNode(:a,"Particles"),
    #         id="particles",
    #         # className="is-active",
    #         events=Dict(
    #             # "click" => js"tabs.setActive(1)"
    #         )
    #     ),
    #     WNode(:li,
    #         WNode(:a,"Magnetic Field"),
    #         id="bfield",
    #         className="is-active",
    #         events=Dict(
    #             # "click" => js"tabs.setActive(2)"
    #         )

    #     ),
    #     WNode(:li,
    #         WNode(:a,"Simulate"),
    #         id="sim",
    #         events=Dict(
    #             # "click" => js"tabs.setActive(3)"
    #         )

    #     ),
    #     WNode(:li,
    #         WNode(:a,"Plot"),
    #         id="plot",
    #         events=Dict(
    #             # "click" => js"tabs.setActive(4)"
    #         )

    #     )

    # )
    # tabs = WNode(
    #     :div,
    #     tabitems,
    #     attributes=Dict(:class=>"tabs is-boxed",:id=>"star-tabs")
    # )

    # body!(w,tabs)

    # ********** ParticleTree widget test **********
    # pt = pt_manualdt_wdg()

    # # printbutton = Interact.button("Print")
    # # Interact.@on println("Number of particles = ",length(getproperty(&pt,:nodes)))
    # Interact.@on println("*** New Particle ***\n",getindex(&pt,2))
    # # Interact.@map (&printbutton; println(pt[]))

    # w = Window()
    # ui = dom"div"(
    #     pt
    # )
    # body!(w,ui)

    # ********** Creation of empty ParticleTree and appending nodes **********
    # test = ParticleTree()
    # println(length(test.nodes))
    # push!(test,ParticleTree())
    # println("length(test.nodes) = ", length(test.nodes))
    # # parameters for push! test
    # el = ParticleID(0,0,1)
    # en = upreferred(1.0u"GeV")
    # pos = Vector([-8.5,0.0,0.0]*u"kpc")
    # dir = Vector([1.0,0.0,0.0])
    # dt = 1.0u"s"

    # elpt = ParticleTree(el,en,pos,dir,dt)
    # elcopy = deepcopy(elpt)
    # println("length(elpt.nodes) = ", length(elpt.nodes))
    # println("length(elcopy.nodes) = ", length(elcopy.nodes))

    # println(elpt)
    # # test = push(test,elpt)
    # push!(test,elpt)
    # println("length(test.nodes) = ", length(test.nodes))

    # println(test)
    # # test = push(test,elpt)
    # push!(test,elpt)
    # println("length(test.nodes) = ", length(test.nodes))
    # println(test)

    # aim2 = Vector([0.0,1.0,0.0])
    # aim2 = normalize(aim2)
    # pos2 = usistrip.(pos)
    # mom2 = momentum_si(usistrip(en),el)
    # mom2 = aim2*mom2
    # coords2 = Coords(ArrayPartition(pos2,mom2))

    # println("*** debug 1 ***")
    # function make_pt()
    #     # parameters to test build 1
    #     el = ParticleID(0,0,1)
    #     en = upreferred(1.0u"GeV")
    #     pos = Vector([-8.5,0.0,0.0]*u"kpc")
    #     aim = Vector([1.0,0.0,0.0])
    #     dt = 3.6e3u"s"

    #     ### build 1 ###
    #     return ParticleTree(el,en,pos,aim,dt)
    # end

    # pt = make_pt()
    # println("*** debug 2 ***")

    # # push! test
    # push!(pt,coords2)

    # println(typeof(pt[1,1,1,1]) == typeof(coords2))

    # println("*** debug 3 ***")

    # return pt
    return nothing
end

export run

end

import .TestStuff

a = TestStuff.run();


text:
using LinearAlgebra
using Printf

function exp_lanczos!(A::L,
                      v::AbstractVector,
                      τ::T, m::Integer,
                      vp::AbstractVector,
                      V::AbstractMatrix,
                      α::Vector{R},
                      β::Vector{R},
                      sub_v::Vector{T},
                      d_sub_v::AbstractVector,
                      sw::stegr_work;
                      atol::R = 1.0e-8,
                      rtol::R = 1.0e-4,
                      verbose::Bool = false) where {L<:LinearMap, T<:Number, R<:Real}
    β₀ = norm(v)
    copyto!(view(V,:,1), v)
    lmul!(one(T)/β₀, view(V,:,1))

    ε = atol + rtol * β₀
    verbose && @printf("Initial norm: β₀ %e, stopping threshold: %e\n", β₀, ε)

    j = 1
    jj = 1 # Which Krylov subspace to use, in the end

    for j = 1:m
        x,y = view(V,:,j),view(V,:,j+1)
        mul!(y,A,x)
        α[j] = real(dot(x,y))
        j > 1 && (y .-= β[j-1]*view(V,:,j-1))
        y .-= α[j]*x
        β[j] = norm(y)
        lmul!(one(T)/β[j], y)

        expT(view(α, 1:jj), view(β, 1:jj-1), τ, view(sub_v, 1:j), sw)
        σ = β[j]*abs(sub_v[j])
        verbose && @printf("iter %d, α[%d] %e, β[%d] %e, σ %e\n",j, j, α[j], j, β[j], σ)

        if σ < ε
            break
        else
            j != m && (jj += 1)
        end
    end
    verbose && println("Krylov subspace size: ", jj)
    copyto!(d_sub_v, sub_v)
    vp[:] = β₀*view(V,:,1:jj)*view(d_sub_v, 1:jj)
end

mutable struct LanczosExponentiator{T<:AbstractFloat,U<:Number} <: KrylovExponentiator
    m::Integer
    V::AbstractMatrix
    α::Vector{T}
    β::Vector{T}
    sub_v::Vector{U}
    d_sub_v::AbstractVector
    sw::stegr_work{T}
    atol::T
    rtol::T
    verbose::Bool
end
function LanczosExponentiator(m::Integer, v::AbstractVector;
                              atol::Float64 = 1.0e-8,
                              rtol::Float64 = 1.0e-4,
                              verbose::Bool = false)
    U = eltype(v)
    T = real(U)
    N = length(v)
    V = similar(v, U, N, m + 1)
    α = Array{real(U)}(undef,m)
    β = Array{real(U)}(undef,m)
    sub_v = Array{U}(undef,m)
    d_sub_v = similar(v, U, m)
    LanczosExponentiator(m, V, α, β, sub_v, d_sub_v,
                         stegr_work(real(U), LinearAlgebra.BlasInt(m)),
                         T(atol), T(rtol), verbose)
end

(LE::LanczosExponentiator{T,U})(Ω::L, τ::U,
                                v::AbstractVector, w::AbstractVector) where {L<:LinearMap, T<:AbstractFloat,U<:Number} =
                                    exp_lanczos!(Ω, v, τ, LE.m, w,
                                                 LE.V, LE.α, LE.β,
                                                 LE.sub_v, LE.d_sub_v,
                                                 LE.sw;
                                                 atol = LE.atol,
                                                 rtol = LE.rtol,
                                                 verbose = LE.verbose)

export LanczosExponentiator


text:
"""
Abstract supertype of Interact outputs including `InteractOuput` and `ElectronOutput`
"""
abstract type AbstractInteractOutput{T,F} <: ImageOutput{T,F} end

"""
    InteractOutput(init; ruleset, fps=25.0, store=false,
                   processor=ColorProcessor(), minval=nothing, maxval=nothing,
                   extrainit=Dict())

An `Output` for Atom/Juno and Jupyter notebooks,
and the back-end for [`ElectronOutput`](@ref) and [`ServerOutput`](@ref).

### Arguments:
- `init`: initialisation Array or NamedTuple of arrays.

### Keyword Arguments:
- `ruleset`: the ruleset to run in the interface simulations.
- `tspan`: `AbstractRange` timespan for the simulation
- `fps::Real`: frames per second to display the simulation
- `store::Bool`: whether ot store the simulation frames for later use
- `processor::GridProcessor
- `minval::Number`: minimum value to display in the simulation
- `maxval::Number`: maximum value to display in the simulation
"""
mutable struct InteractOutput{T,F<:AbstractVector{T},E,GC,IC,RS<:Ruleset,Pa,IM,TI} <: AbstractInteractOutput{T,F}
    frames::F
    running::Bool
    extent::E
    graphicconfig::GC
    imageconfig::IC
    ruleset::RS
    page::Pa
    image_obs::IM
    t_obs::TI
end
# Most defaults are passed in from the generic ImageOutput constructor
function InteractOutput(;
    frames, running, extent, graphicconfig, imageconfig, ruleset,
    extrainit=Dict(), throttle=0.1, interactive=true, grouped=true, kwargs...
)
    # Observables that update during the simulation
    image_obs = Observable{Any}(dom"div"())
    t_obs = Observable{Int}(1)

    # Page and output construction
    page = vbox()
    output = InteractOutput(
         frames, running, extent, graphicconfig, imageconfig, ruleset, page, image_obs, t_obs
    )

    # Widgets
    timedisplay = _time_text(t_obs)
    controls = _control_widgets(output, ruleset, extrainit)
    sliders = _rule_sliders(ruleset, throttle, grouped, interactive)

    # Put it all together into a web page
    output.page = vbox(hbox(output.image_obs), timedisplay, controls, sliders)

    # Initialise image Observable
    simdata = DynamicGrids.SimData(extent, ruleset)
    # image_obs[] = _webimage(DG.grid2image(output, simdata)

    return output
end

# Base interface
Base.display(o::InteractOutput) = display(o.page)
Base.show(o::InteractOutput) = show(o.page)

# DynamicGrids interface
DynamicGrids.isasync(o::InteractOutput) = true
function DynamicGrids.showimage(image::AbstractArray, o::InteractOutput, data::AbstractSimData)
    # Update simulation image, makeing sure any errors are printed in the REPL
    try
        o.t_obs[] = currentframe(data)
        o.image_obs[] = _webimage(image)
    catch e
        println(e)
    end
    return nothing
end

_webimage(image) = dom"div"(image)

# Widget buliding

function _time_text(t_obs::Observable)
    timedisplay = Observable{Any}(dom"div"("0"))
    map!(timedisplay, t_obs) do t
        dom"div"(string(t))
    end
    return timedisplay
end

function _rule_sliders(ruleset, throttle, grouped, interactive)
    if interactive
        return InteractModels.attach_sliders!(ruleset; throttle=throttle, grouped=grouped)
    else
        return dom"div"()
    end
end

function _control_widgets(o::InteractOutput, ruleset, extrainit)
    # We use the init dropdown for the simulation init, even if we don't
    # show the dropdown because it only has 1 option.
    extrainit[:init] = deepcopy(init(o))
    init_dropdown = dropdown(extrainit, value=extrainit[:init], label="Init")
    maybe_init_dropdown = length(extrainit) > 1 ? (init_dropdown,) : ()

    fps_slider = slider(1:200, value=fps(o), label="FPS")

    # Buttons
    sim = button("sim")
    resume = button("resume")
    stop = button("stop")

    # Control mappings. Make errors visible in the console.
    on(observe(sim)) do _
        try
            !DG.isrunning(o) && sim!(o, ruleset; init=init_dropdown[])
        catch e
            println(e)
        end
    end
    on(observe(resume)) do _
        try
            !DG.isrunning(o) && resume!(o, ruleset; tstop=last(tspan(o)))
        catch e
            println(e)
        end
    end
    on(observe(stop)) do _
        try
            DG.setrunning!(o, false)
        catch e
            println(e)
        end
    end
    on(observe(fps_slider)) do fps
        try
            DG.setfps!(o, fps)
            DG.settimestamp!(o, o.t_obs[])
        catch e
            println(e)
        end
    end

    return hbox(sim, resume, stop, fps_slider, maybe_init_dropdown...)
end


text:
using MultiFloats

import StructArrays
import Base: getproperty

# minimal effort to get MultiFloat struct of arrays to work.
# todo: complex.
Base.getproperty(a::MultiFloat, i::Int) = a._limbs[i]
StructArrays.staticschema(::Type{MultiFloat{T,M}}) where {T,M} = NTuple{M,T}
StructArrays.createinstance(::Type{MultiFloat{T,M}}, args::Vararg{T,M}) where {T,M} = MultiFloat{T,M}(values(args))


text:
function maketable5(panel::DataFrame; trialrunonly::Bool=trialrunonly,
    runpanela::Bool=true,
    runpanelb::Bool=true,
    runpanelc::Bool=true,
    runpaneld::Bool=true
    )::Nothing
  #load the data we will work with
  #panel::DataFrame = constructportfolios(refreshportfolios=false, trialrunonly=trialrunonly)
  sort!(panel, [:permno, :date])
  apanel::DataFrame = panel[panel.annflag,:]

  ################common data
  cqports::PortfolioConstructions = leverageconstructions()
  T5_FNAMES::Vector{Symbol} = CQUART_FNAMES_RMD
  T5_FVALS::Vector{Symbol} = CQUART_FVALS_RMD
  T5_FGROUPS::Vector{Symbol} = CQUART_FGROUPS_RMD
  T5_FNAMES_ALT::Vector{Symbol} = CQUART_FNAMES_ALT_RMD
  T5_FGROUPS_ALT::Vector{Symbol} = CQUART_FGROUPS_ALT_RMD

  ################Table A
  T5_PANEL_A_ROWKEYS::Vector{Symbol} = [:mean, :std, :stdxt]

  T5_PANEL_A_ROWLABEL::Dict = Dict(
    :mean=>"Mean",
    :std=>"SD",
    :stdxt=>"SD(X,T)")

  T5_PANEL_A_IDX::Dict = Dict(
    :mean=>1,
    :std=>2,
    :stdxt=>3)
  T5_PANEL_A_NAME::String = "t5panela-$(REPLICATION_TYPE[])-$(OUT_SUFFIX[])"

  runpanela && tablexpanelA(apanel,
    fvals = T5_FVALS,
    rowkeys=T5_PANEL_A_ROWKEYS,
    rowlabel=T5_PANEL_A_ROWLABEL,
    idx=T5_PANEL_A_IDX,
    tablename=T5_PANEL_A_NAME)

  #####################TABLE B
  T5_PANEL_B_ROWKEYS::Vector{Symbol} = [
    :leverageQmeans,
    :quartilenum,
    :LLsd,
    :sd,
    :Δsd,
    :LLret12m,
    :ret12m,
    :Δret12m]

  T5_PANEL_B_ROWLABEL::Dict = Dict(
    :leverageQmeans=>"Leverage Q Means",
    :quartilenum=>"Quartile \\#",
    :LLsd=>"\\smallskip SD Net Lagged\$^2\$",
    :sd=>"SD Net Lead",
    :Δsd=>"SD Net 2Y Delta",
    :LLret12m=>"\\smallskip Compound Raw Lagged\$^2\$",
    :ret12m=>"Compound Raw Lead",
    :Δret12m=>"Compound Raw 2Y Delta")

  T5_PANEL_B_IDX::Dict = Dict(
    T5_PANEL_B_ROWKEYS[i]=>i for i ∈ 1:(length(T5_PANEL_B_ROWKEYS)))

  #the below is to help with future abstraction if necessary
  T5_PANEL_B_VALCOLIDX::Dict= Dict(f=>f for f ∈ T5_FVALS)

  #these are pairs of lagged and unlagged fields
  T5_PANEL_B_VOLFIELDS::NTuple{2,Symbol} = (:LLvol252d, :vol252d)
  T5_PANEL_B_RETFIELDS::NTuple{2,Symbol} = (:LLret12m, :ret12m)

  T5_PANEL_B_NAME::String = "t5panelb-$(REPLICATION_TYPE[])-$(OUT_SUFFIX[])"

  runpanelb && tablexpanelB(apanel,
    fvals = T5_FVALS,
    rowkeys=T5_PANEL_B_ROWKEYS,
    rowlabel=T5_PANEL_B_ROWLABEL,
    idx=T5_PANEL_B_IDX,
    valcolidx = T5_PANEL_B_VALCOLIDX,
    tablename=T5_PANEL_B_NAME,
    volfields=T5_PANEL_B_VOLFIELDS,
    retfields=T5_PANEL_B_RETFIELDS)

  ###################PANEL C############

  T5_PANEL_C_ROWKEYS::Vector{Symbol} = [:constant, :plusxmkt, :plussmbhml, :plusrmwcma, :plusumd]

  T5_PANEL_C_ROWLABEL::Dict = Dict(
    :constant=>"Constant",
    :plusxmkt=>"+XMKT",
    :plussmbhml=>"+SMB+HML",
    :plusrmwcma=>"+RMW+CMA",
    :plusumd=>"+UMD")

  T5_PANEL_C_CONTROLS::Dict = Dict(
    :constant=>CONTROL0,
    :plusxmkt=>[:mkt],
    :plussmbhml=>[:mkt, :P_ff3m_smb,	:P_ff3m_hml],
    :plusrmwcma=>[:mkt, :P_ff5_smb,	:P_ff5_hml,	:P_ff5_rmw,	:P_ff5_cma],
    :plusumd=>[:mkt, :P_ff5_smb,	:P_ff5_hml,	:P_ff5_rmw,	:P_ff5_cma, :P_ff3m_umd])

  T5_PANEL_C_FOCALS::Dict = Dict(
    :constant=>T5_FNAMES,
    :plusxmkt=>T5_FNAMES,
    :plussmbhml=>T5_FNAMES,
    :plusrmwcma=>T5_FNAMES,
    :plusumd=>T5_FNAMES)

  T5_PANEL_C_NAME::String = "t5panelc-$(REPLICATION_TYPE[])-$(OUT_SUFFIX[])"

  T5_PANEL_C_MIN_ROWS::Int = 24

  runpanelc && tablexpanelC(panel,
    fvals=T5_FVALS,
    fgroups=T5_FGROUPS,
    Fnames = T5_FNAMES,
    rowkeys=T5_PANEL_C_ROWKEYS,
    rowlabel=T5_PANEL_C_ROWLABEL,
    controls=T5_PANEL_C_CONTROLS,
    focals=T5_PANEL_C_FOCALS,
    tablename=T5_PANEL_C_NAME,
    minrowspergroup = T5_PANEL_C_MIN_ROWS
  )

  #########################PANEL D#########################
  T5_PANEL_D_CONTROLS::Dict = Dict(
    :quartiles=>CONTROL0,
    :quartiles4ctrl=>T1_CONTROL4,
    :quartiles10ctrl=>T1_CONTROL10,
    :values=>CONTROL0,
    :values4ctrl=>T1_CONTROL4,
    :values10ctrl=>T1_CONTROL10,
    :quartiles_ac=>CONTROL0,
    :quartiles_lret=>T1_CONTROL10)

  T5_PANEL_D_RET::Dict = Dict(
    :quartiles=>:ret,
    :quartiles4ctrl=>:ret,
    :quartiles10ctrl=>:ret,
    :values=>:ret,
    :values4ctrl=>:ret,
    :values10ctrl=>:ret,
    :quartiles_ac=>:ret,
    :quartiles_lret=>:lret)

  T5_PANEL_D_ROWKEYS::Vector{Symbol} = [:quartiles, :quartiles4ctrl, :quartiles10ctrl, :values,
    :values4ctrl, :values10ctrl, :quartiles_ac, :quartiles_lret]

  T5_PANEL_D_ROWLABEL::Dict = Dict(
    :quartiles=>"Leverage Quartiles",
    :quartiles4ctrl=>"... +4 vars",
    :quartiles10ctrl=>"... +10 vars",
    :values=>"Leverage Values",
    :values4ctrl=>"... +4 vars",
    :values10ctrl=>"... +10 vars",
    :quartiles_ac=>"\\midrule Asset-Controlled Quartiles",
    :quartiles_lret=>"Log Returns +10 vars")

  T5_PANEL_D_FOCALS::Dict = Dict(
    :quartiles=>T5_FGROUPS,
    :quartiles4ctrl=>T5_FGROUPS,
    :quartiles10ctrl=>T5_FGROUPS,
    :values=>T5_FVALS,
    :values4ctrl=>T5_FVALS,
    :values10ctrl=>T5_FVALS,
    :quartiles_ac=>T5_FGROUPS_ALT,
    :quartiles_lret=>T5_FGROUPS)

  T5_PANEL_D_NAME::String = "t5paneld-$(REPLICATION_TYPE[])-$(OUT_SUFFIX[])"

  T5_PANEL_D_MIN_ROWS::Int = 24

  runpaneld && tablexpanelD(panel,
      fvals=T5_FVALS,
      fgroups=T5_FGROUPS,
      ret = T5_PANEL_D_RET,
      rowkeys=T5_PANEL_D_ROWKEYS,
      rowlabel=T5_PANEL_D_ROWLABEL,
      controls=T5_PANEL_D_CONTROLS,
      focals=T5_PANEL_D_FOCALS,
      tablename=T5_PANEL_D_NAME,
      minrowspergroup = T5_PANEL_D_MIN_ROWS
    )

  return nothing
end

max_stars_repo_name: clintonTE/CCA

max_issues_repo_name: clintonTE/CCA

max_forks_repo_name: clintonTE/CCA


text:
# This file is a part of AstroLib.jl. License is MIT "Expat".

function _hor2eq(alt::T, az::T, jd::T, lat::T, lon::T, altitude::T,
                 pressure::T, temperature::T, ws::Bool, B1950::Bool,
                 precession::Bool, nutate::Bool, aberration::Bool,
                 refract::Bool) where {T<:AbstractFloat}

    if refract
        alt = co_refract(alt, altitude, pressure, temperature)
    end

    if ws
        az -= 180
    end
    _, _, eps, d_psi = co_nutate(jd, 45, 45)
    last = 15 * ct2lst(lon, jd) + d_psi * cos(eps) / 3600
    ha, dec = altaz2hadec(alt, az, lat)
    ra = mod(last - ha, 360)
    dra1, ddec1, eps = co_nutate(jd, ra, dec)

    if aberration
        dra2, ddec2 = co_aberration(jd, ra, dec, eps)
        ra -= dra2 / 3600
        dec -= ddec2 / 3600
    end

    if nutate
       ra -= dra1
       dec -= ddec1
    end
    j_now = (jd - J2000) / JULIANYEAR + 2000

    if precession
        if B1950
            ra, dec = precess(ra, dec, j_now, 1950, FK4=true)
        else
            ra, dec = precess(ra, dec, j_now, 2000)
        end
    end
    return ra, dec, ha
end

hor2eq(alt::Real, az::Real, jd::Real, lat::Real, lon::Real, altitude::Real=0;
       ws::Bool=false, B1950::Bool=false, precession::Bool=true, nutate::Bool=true,
       aberration::Bool=true, refract::Bool=true, pressure::Real=NaN,
       temperature::Real=NaN) =
           _hor2eq(promote(float(alt), float(az), float(jd), float(lat), float(lon),
                   float(altitude), float(temperature), float(pressure))..., ws, B1950,
                   precession, nutate, aberration, refract)

hor2eq(alt::Real, az::Real, jd::Real, obsname::AbstractString; kwargs...) =
    hor2eq(alt, az, jd, observatories[obsname].latitude, observatories[obsname].longitude,
           observatories[obsname].altitude; kwargs...)

"""
    hor2eq(alt, az, jd[, obsname; ws=false, B1950=false, precession=true, nutate=true,
           aberration=true, refract=true, lat=NaN, lon=NaN, altitude=0, pressure=NaN,
           temperature=NaN]) -> ra, dec, ha

    hor2eq(alt, az, jd, lat, lon[, altitude=0; ws=false, B1950=false,
           precession=true, nutate=true, aberration=true, refract=true, pressure=NaN,
           temperature=NaN]) -> ra, dec, ha

### Purpose

Converts local horizon coordinates (alt-az) to equatorial (ra-dec) coordinates.

### Explanation

This is a function to calculate equatorial (ra,dec) coordinates from
horizon (alt,az) coords. It is accurate to about 1 arcsecond or better.
It performs precession, nutation, aberration, and refraction corrections.

### Arguments

This function has two base methods.  With one you can specify the name of the observatory,
if present in `AstroLib.observatories`, with the other one you can provide the coordinates
of the observing site and, optionally, the altitude.

Common mandatory arguments:

* `alt`: altitude of horizon coords, in degrees
* `az`: azimuth angle measured East from North (unless ws is `true`), in degrees
* `jd`: julian date

Other positional arguments:

* `obsname`: set this to a valid observatory name in `AstroLib.observatories`.

or

* `lat`: north geodetic latitude of location, in degrees.
* `lon`: AST longitude of location, in degrees. You can specify west longitude with a
  negative sign.
* `altitude`: the altitude of the observing location, in meters.  It is `0` by default

Optional keyword arguments:

* `ws` (optional boolean keyword): set this to `true` to get the azimuth measured
  westward from south. This is `false` by default
* `B1950` (optional boolean keyword): set this to `true` if the ra and dec
  are specified in B1950 (FK4 coordinates) instead of J2000 (FK5). This is `false` by
  default
* `precession` (optional boolean keyword): set this to `false` for no precession,
  `true` by default
* `nutate` (optional boolean keyword): set this to `false` for no nutation,
  `true` by default
* `aberration` (optional boolean keyword): set this to `false` for no aberration
  correction, `true` by default
* `refract` (optional boolean keyword): set this to `false` for no refraction
  correction, `true` by default
* `pressure` (optional keyword): the pressure at the observing location, in millibars.
  Default value is `NaN`
* `temperature` (optional keyword): the temperature at the observing location, in Kelvins.
  Default value is `NaN`

### Output

* `ra`: right ascension of object, in degrees (FK5)
* `dec`: declination of the object, in degrees (FK5)
* `ha`: hour angle, in degrees

### Example

You are at Kitt Peak National Observatory, looking at a star at azimuth
angle 264d 55m 06s and elevation 37d 54m 41s (in the visible). Today is Dec 25, 2041
and the local time is 10 PM precisely. What is the right ascension and declination
(J2000) of the star you're looking at? The temperature here is about 0 Celsius,
and the pressure is 781 millibars. The Julian date for this time is 2466879.7083333

```jldoctest
julia> using AstroLib

julia> ra_o, dec_o = hor2eq(ten(37,54,41), ten(264,55,06), 2466879.7083333,
                            "kpno", pressure = 781, temperature = 273)
(3.3224480269254717, 15.19061543702944, 54.61174536229464)

julia> adstring(ra_o, dec_o)
" 00 13 17.4  +15 11 26"
```

### Notes

Code of this function is based on IDL Astronomy User's Library.
"""
hor2eq

# TODO: Make hor2eq type-stable, which it isn't currently because of keyword arguments
# Note that the inner function `_hor2eq` is type stable


text:
module TennisRanking

export simulation

import Dates
import Random

using Random
using Dates
using StatsBase
using Plots

include("types/types.jl")

include("agent/form_teams.jl")
include("agent/generate_players.jl")
include("agent/player.jl")
include("agent/team.jl")

include("algorithm/constants.jl")
include("algorithm/ranking.jl")
include("algorithm/atp_ranking.jl")
include("algorithm/elo_ranking.jl")

include("event/burnin.jl")
include("event/generate_doubles_tournaments.jl")
include("event/play_doubles_match.jl")
include("event/play_doubles_tournament.jl")
include("event/round_to_result.jl")
include("event/tournament_bracket.jl")

include("metric/correlation.jl")
include("metric/calculate_metric.jl")
include("metric/save_plot.jl")

"""
    function simulation(;
        player_count::Int64,
        seasons::Int64,
        number_of_replications::Int64,
        burn_in_seasons::Int64,
        ranking_schemes::Vector{String},
        metrics::Vector{String},
        verbose::Bool,
        strength_method::String
    )

Simulates a tennis season.

Arguments
=========
- `player_count`:
    the number of players to create.
- `seasons`:
    the number of seasons to simulate.
- `number_of_replications`:
    the number of times to repeat the simulation.
- `burn_in_seasons`:
    the number of burn in seasons to use.
- `ranking_schemes`:
    which ranking algorithms to test.
    options:
        1) "ATP"
        2) "Elo"
        3) "Dwz"
- `metrics`:
    the metrics to be evaluated during the simulation.
    options:
        1) Spearman Correlation
        2) Kendall Tau Correlation
- `verbose`:
    whether to print each stage of the simulation.
    options:
        1) true
        2) false
- `strength_method`:
    method to determine the probability team 1 beats team 2.
    options:
        1) "BT" - Bradley Terry Model
        2) "BT_Exp" - Bradley Terry Exponential Model
"""

function simulation(;
    player_count::Int64,
    seasons::Int64,
    number_of_replications::Int64,
    burn_in_seasons::Int64,
    ranking_schemes::Vector{String},
    metrics::Vector{String},
    verbose::Bool,
    strength_method::String
)
    # Set random seed for reproducability
    # Random.seed!(42)

    # Generate a pool of players
    players = generate_players(
        dataset_size = player_count,
        ranking_schemes = ranking_schemes,
        verbose = verbose
    )

    # Initialize each player's age
    update_player_ages(
        players = players,
        method = "Random",
        verbose = verbose
    )

    # Generate "Burn In" ranking
    burnin(
        players = players,
        seasons = burn_in_seasons,
        strength_method = strength_method,
        verbose = verbose
    )

    # Remove the saved doubles tournament results
    clear_doubles_results(players = players)

    # Initialize the ranking schemes with the burn in ranking
    initialize_rankings_schemes(
        players = players,
        ranking_schemes = ranking_schemes,
        verbose = verbose
    )

    # Run simulation for each ranking algorithm
    for ranking_scheme in ranking_schemes

        # Generate a pool of tournaments
        tournaments = generate_doubles_tournaments()
        sort!(tournaments, by = t -> t.date, alg = InsertionSort)

        # Store the metrics calculated
        computed_metrics::Dict{String, Vector{Float64}} = Dict()
        for metric in metrics
            computed_metrics[metric] = Vector{Float64}(undef, length(tournaments)*seasons)
            fill!(computed_metrics[metric], 0)
        end

        # Run simulation x number of times
        for _ in 1:number_of_replications
            # Simulate tournaments for each season
            for season_idx in 1:seasons
                # Simulate each tournament
                for (tournament_idx, tournament) in enumerate(tournaments)
                    index = tournament_idx * season_idx
                    # Play the tournament
                    play_doubles_tournament(
                        tournament = tournament,
                        players = players,
                        ranking_scheme = ranking_scheme,
                        strength_method = strength_method,
                        verbose = verbose
                    )
                    # Update the ranking
                    updateRanking(
                        players = players,
                        ranking_scheme_to_apply = ranking_scheme,
                        ranking_scheme_to_update = ranking_scheme,
                        last_tournament_id = tournament.id,
                        verbose = verbose
                    )
                    # Calculate the desired metrics
                    for metric in metrics
                        value = calculate_metric(
                            metric = metric,
                            players = players,
                            ranking_scheme1 = ranking_scheme,
                            ranking_scheme2 = "Ground Truth"
                        )
                        computed_metrics[metric][index] += value
                    end
                end
                # A year has past so increase every player's age
                update_player_ages(
                    players = players,
                    method = "Increment",
                    verbose = verbose
                )
            end
            # Clear the rankings
            clear_doubles_results(players = players)
        end

        # Average the metrics
        for metric in metrics
            for value in computed_metrics[metric]
                value = value / number_of_replications
            end
        end

        # Plot the results
        for metric in metrics
            save_plot(
                y_var = computed_metrics[metric],
                title = "$metric using $ranking_scheme over $number_of_replications replications",
                f_name = "$metric-$ranking_scheme ranking",
                xlabel="Tournament #",
                ylabel="$metric",
                tournaments=repeat(tournaments, seasons)
            )
        end
    end
    return nothing
end

end

max_stars_repo_name: Danial-Hussain/Tennis-Ranking

max_issues_repo_name: Danial-Hussain/Tennis-Ranking

max_forks_repo_name: Danial-Hussain/Tennis-Ranking