[{"data":1,"prerenderedAt":1295},["ShallowReactive",2],{"navigation_docs":3,"-guide-custom":116,"-guide-custom-surround":1290},[4,36],{"title":5,"path":6,"stem":7,"children":8,"icon":35},"Guide","\u002Fguide","1.guide\u002F01.index",[9,11,15,19,23,27,31],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Encode and decode","\u002Fguide\u002Ftransform","1.guide\u002F02.transform",{"title":16,"path":17,"stem":18},"Analysis","\u002Fguide\u002Fanalysis","1.guide\u002F03.analysis",{"title":20,"path":21,"stem":22},"CLI","\u002Fguide\u002Fcli","1.guide\u002F04.cli",{"title":24,"path":25,"stem":26},"Agents","\u002Fguide\u002Fagents","1.guide\u002F05.agents",{"title":28,"path":29,"stem":30},"Custom ciphers","\u002Fguide\u002Fcustom","1.guide\u002F06.custom",{"title":32,"path":33,"stem":34},"Playground","\u002Fguide\u002Fplayground","1.guide\u002F07.playground","i-solar-book-2-linear",{"title":37,"path":38,"stem":39,"children":40,"icon":115},"Ciphers","\u002Fciphers","2.ciphers\u002F00.index",[41,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111],{"title":42,"path":38,"stem":39},"Overview",{"title":44,"path":45,"stem":46},"Caesar","\u002Fciphers\u002Fcaesar","2.ciphers\u002F01.caesar",{"title":48,"path":49,"stem":50},"ROT-13","\u002Fciphers\u002Frot13","2.ciphers\u002F02.rot13",{"title":52,"path":53,"stem":54},"ROT-47","\u002Fciphers\u002Frot47","2.ciphers\u002F03.rot47",{"title":56,"path":57,"stem":58},"Atbash","\u002Fciphers\u002Fatbash","2.ciphers\u002F04.atbash",{"title":60,"path":61,"stem":62},"Affine","\u002Fciphers\u002Faffine","2.ciphers\u002F05.affine",{"title":64,"path":65,"stem":66},"Vigenère","\u002Fciphers\u002Fvigenere","2.ciphers\u002F06.vigenere",{"title":68,"path":69,"stem":70},"Trithemius","\u002Fciphers\u002Ftrithemius","2.ciphers\u002F07.trithemius",{"title":72,"path":73,"stem":74},"Alberti","\u002Fciphers\u002Falberti","2.ciphers\u002F08.alberti",{"title":76,"path":77,"stem":78},"Playfair","\u002Fciphers\u002Fplayfair","2.ciphers\u002F09.playfair",{"title":80,"path":81,"stem":82},"Polybius square","\u002Fciphers\u002Fpolybius","2.ciphers\u002F10.polybius",{"title":84,"path":85,"stem":86},"Morse code","\u002Fciphers\u002Fmorse","2.ciphers\u002F11.morse",{"title":88,"path":89,"stem":90},"Bacon's cipher","\u002Fciphers\u002Fbacon","2.ciphers\u002F12.bacon",{"title":92,"path":93,"stem":94},"Tap code","\u002Fciphers\u002Ftap-code","2.ciphers\u002F13.tap-code",{"title":96,"path":97,"stem":98},"ADFGVX","\u002Fciphers\u002Fadfgvx","2.ciphers\u002F14.adfgvx",{"title":100,"path":101,"stem":102},"Bifid","\u002Fciphers\u002Fbifid","2.ciphers\u002F15.bifid",{"title":104,"path":105,"stem":106},"Rail fence","\u002Fciphers\u002Frail-fence","2.ciphers\u002F16.rail-fence",{"title":108,"path":109,"stem":110},"Columnar transposition","\u002Fciphers\u002Fcolumnar","2.ciphers\u002F17.columnar",{"title":112,"path":113,"stem":114},"Enigma M3","\u002Fciphers\u002Fenigma","2.ciphers\u002F18.enigma","i-solar-library-linear",{"id":117,"title":28,"body":118,"description":1283,"extension":1284,"links":1285,"meta":1286,"navigation":252,"path":29,"seo":1288,"stem":30,"__hash__":1289},"docs\u002F1.guide\u002F06.custom.md",{"type":119,"value":120,"toc":1277},"minimark",[121,126,135,1052,1143,1147,1228,1232,1249,1253,1256,1273],[122,123,125],"h2",{"id":124},"one-class-four-methods","One class, four methods",[127,128,129,130,134],"p",{},"Every built-in is a concrete class extending the exported abstract ",[131,132,133],"code",{},"Cipher",". Yours is the same shape, one file:",[136,137,143],"pre",{"className":138,"code":139,"filename":140,"language":141,"meta":142,"style":142},"language-ts shiki shiki-themes github-light github-light poimandres","import {\n  Cipher,\n  InvalidOptionError,\n  getOpt,\n  register,\n  type CipherBaseOptions,\n  type CipherInfo,\n  type CipherResult,\n} from \"@agntn\u002Fciphers\";\n\nclass Reverse extends Cipher {\n  name(): string {\n    return \"reverse\";\n  }\n\n  info(): CipherInfo {\n    return {\n      name: \"reverse\",\n      label: \"Reverse\",\n      description: \"Text backwards, optionally in blocks\",\n      family: \"transposition\",\n      selfInverse: true,\n      options: [\n        { name: \"block\", type: \"number\", required: false, default: 0, description: \"Block length, 0 for the whole text\" },\n      ],\n      keyspace: \"n (block lengths)\",\n    };\n  }\n\n  encode(text: string, options: Readonly\u003CCipherBaseOptions> = {}): CipherResult {\n    const block = getOpt\u003Cnumber>(options, \"block\", 0);\n    if (!Number.isInteger(block) || block \u003C 0) {\n      throw new InvalidOptionError(\"block\", block, \"must be a non-negative integer\");\n    }\n    const size = block === 0 ? text.length : block;\n    let out = \"\";\n    for (let i = 0; i \u003C text.length; i += size) {\n      out += [...text.slice(i, i + size)].reverse().join(\"\");\n    }\n    return { text: out, cipher: \"reverse\", operation: \"encode\", options: { block } };\n  }\n\n  decode(text: string, options: Readonly\u003CCipherBaseOptions> = {}): CipherResult {\n    return { ...this.encode(text, options), operation: \"decode\" };\n  }\n}\n\nregister(\"reverse\", Reverse);\n","reverse.ts","ts","",[131,144,145,158,168,176,184,192,204,214,224,247,254,273,291,307,313,318,333,340,356,373,390,407,421,432,503,509,526,532,537,542,591,634,675,711,717,752,768,811,863,868,926,931,936,974,1016,1021,1027,1032],{"__ignoreMap":142},[146,147,150,154],"span",{"class":148,"line":149},"line",1,[146,151,153],{"class":152},"sP0CR","import",[146,155,157],{"class":156},"sKlNE"," {\n",[146,159,161,165],{"class":148,"line":160},2,[146,162,164],{"class":163},"snHMy","  Cipher",[146,166,167],{"class":156},",\n",[146,169,171,174],{"class":148,"line":170},3,[146,172,173],{"class":163},"  InvalidOptionError",[146,175,167],{"class":156},[146,177,179,182],{"class":148,"line":178},4,[146,180,181],{"class":163},"  getOpt",[146,183,167],{"class":156},[146,185,187,190],{"class":148,"line":186},5,[146,188,189],{"class":163},"  register",[146,191,167],{"class":156},[146,193,195,199,202],{"class":148,"line":194},6,[146,196,198],{"class":197},"stCPd","  type",[146,200,201],{"class":163}," CipherBaseOptions",[146,203,167],{"class":156},[146,205,207,209,212],{"class":148,"line":206},7,[146,208,198],{"class":197},[146,210,211],{"class":163}," CipherInfo",[146,213,167],{"class":156},[146,215,217,219,222],{"class":148,"line":216},8,[146,218,198],{"class":197},[146,220,221],{"class":163}," CipherResult",[146,223,167],{"class":156},[146,225,227,230,233,237,241,244],{"class":148,"line":226},9,[146,228,229],{"class":156},"}",[146,231,232],{"class":197}," from",[146,234,236],{"class":235},"scVjq"," \"",[146,238,240],{"class":239},"sQ7BG","@agntn\u002Fciphers",[146,242,243],{"class":235},"\"",[146,245,246],{"class":156},";\n",[146,248,250],{"class":148,"line":249},10,[146,251,253],{"emptyLinePlaceholder":252},true,"\n",[146,255,257,261,265,268,271],{"class":148,"line":256},11,[146,258,260],{"class":259},"s1TYA","class",[146,262,264],{"class":263},"scZRh"," Reverse",[146,266,267],{"class":152}," extends",[146,269,270],{"class":263}," Cipher",[146,272,157],{"class":156},[146,274,276,279,282,285,289],{"class":148,"line":275},12,[146,277,278],{"class":263},"  name",[146,280,281],{"class":156},"()",[146,283,284],{"class":259},":",[146,286,288],{"class":287},"s8yaW"," string",[146,290,157],{"class":156},[146,292,294,298,300,303,305],{"class":148,"line":293},13,[146,295,297],{"class":296},"sZW6a","    return",[146,299,236],{"class":235},[146,301,302],{"class":239},"reverse",[146,304,243],{"class":235},[146,306,246],{"class":156},[146,308,310],{"class":148,"line":309},14,[146,311,312],{"class":156},"  }\n",[146,314,316],{"class":148,"line":315},15,[146,317,253],{"emptyLinePlaceholder":252},[146,319,321,324,326,328,331],{"class":148,"line":320},16,[146,322,323],{"class":263},"  info",[146,325,281],{"class":156},[146,327,284],{"class":259},[146,329,211],{"class":330},"sCrqT",[146,332,157],{"class":156},[146,334,336,338],{"class":148,"line":335},17,[146,337,297],{"class":296},[146,339,157],{"class":156},[146,341,343,346,348,350,352,354],{"class":148,"line":342},18,[146,344,345],{"class":163},"      name",[146,347,284],{"class":156},[146,349,236],{"class":235},[146,351,302],{"class":239},[146,353,243],{"class":235},[146,355,167],{"class":156},[146,357,359,362,364,366,369,371],{"class":148,"line":358},19,[146,360,361],{"class":163},"      label",[146,363,284],{"class":156},[146,365,236],{"class":235},[146,367,368],{"class":239},"Reverse",[146,370,243],{"class":235},[146,372,167],{"class":156},[146,374,376,379,381,383,386,388],{"class":148,"line":375},20,[146,377,378],{"class":163},"      description",[146,380,284],{"class":156},[146,382,236],{"class":235},[146,384,385],{"class":239},"Text backwards, optionally in blocks",[146,387,243],{"class":235},[146,389,167],{"class":156},[146,391,393,396,398,400,403,405],{"class":148,"line":392},21,[146,394,395],{"class":163},"      family",[146,397,284],{"class":156},[146,399,236],{"class":235},[146,401,402],{"class":239},"transposition",[146,404,243],{"class":235},[146,406,167],{"class":156},[146,408,410,413,415,419],{"class":148,"line":409},22,[146,411,412],{"class":163},"      selfInverse",[146,414,284],{"class":156},[146,416,418],{"class":417},"siHFe"," true",[146,420,167],{"class":156},[146,422,424,427,429],{"class":148,"line":423},23,[146,425,426],{"class":163},"      options",[146,428,284],{"class":156},[146,430,431],{"class":156}," [\n",[146,433,435,438,441,443,445,448,450,453,456,458,460,463,465,467,470,472,476,478,481,483,486,488,491,493,495,498,500],{"class":148,"line":434},24,[146,436,437],{"class":156},"        {",[146,439,440],{"class":163}," name",[146,442,284],{"class":156},[146,444,236],{"class":235},[146,446,447],{"class":239},"block",[146,449,243],{"class":235},[146,451,452],{"class":156},",",[146,454,455],{"class":163}," type",[146,457,284],{"class":156},[146,459,236],{"class":235},[146,461,462],{"class":239},"number",[146,464,243],{"class":235},[146,466,452],{"class":156},[146,468,469],{"class":163}," required",[146,471,284],{"class":156},[146,473,475],{"class":474},"sNe8j"," false",[146,477,452],{"class":156},[146,479,480],{"class":163}," default",[146,482,284],{"class":156},[146,484,485],{"class":417}," 0",[146,487,452],{"class":156},[146,489,490],{"class":163}," description",[146,492,284],{"class":156},[146,494,236],{"class":235},[146,496,497],{"class":239},"Block length, 0 for the whole text",[146,499,243],{"class":235},[146,501,502],{"class":156}," },\n",[146,504,506],{"class":148,"line":505},25,[146,507,508],{"class":156},"      ],\n",[146,510,512,515,517,519,522,524],{"class":148,"line":511},26,[146,513,514],{"class":163},"      keyspace",[146,516,284],{"class":156},[146,518,236],{"class":235},[146,520,521],{"class":239},"n (block lengths)",[146,523,243],{"class":235},[146,525,167],{"class":156},[146,527,529],{"class":148,"line":528},27,[146,530,531],{"class":156},"    };\n",[146,533,535],{"class":148,"line":534},28,[146,536,312],{"class":156},[146,538,540],{"class":148,"line":539},29,[146,541,253],{"emptyLinePlaceholder":252},[146,543,545,548,551,555,557,559,562,565,567,570,573,576,579,582,585,587,589],{"class":148,"line":544},30,[146,546,547],{"class":263},"  encode",[146,549,550],{"class":156},"(",[146,552,554],{"class":553},"s1jWp","text",[146,556,284],{"class":259},[146,558,288],{"class":287},[146,560,561],{"class":156},", ",[146,563,564],{"class":553},"options",[146,566,284],{"class":259},[146,568,569],{"class":330}," Readonly",[146,571,572],{"class":156},"\u003C",[146,574,575],{"class":330},"CipherBaseOptions",[146,577,578],{"class":156},"> ",[146,580,581],{"class":259},"=",[146,583,584],{"class":156}," {})",[146,586,284],{"class":259},[146,588,221],{"class":330},[146,590,157],{"class":156},[146,592,594,597,601,604,608,610,612,615,618,620,622,624,626,628,631],{"class":148,"line":593},31,[146,595,596],{"class":259},"    const",[146,598,600],{"class":599},"saoiD"," block",[146,602,603],{"class":259}," =",[146,605,607],{"class":606},"sULi6"," getOpt",[146,609,572],{"class":156},[146,611,462],{"class":287},[146,613,614],{"class":156},">(",[146,616,564],{"class":617},"spVlQ",[146,619,561],{"class":156},[146,621,243],{"class":235},[146,623,447],{"class":239},[146,625,243],{"class":235},[146,627,561],{"class":156},[146,629,630],{"class":417},"0",[146,632,633],{"class":156},");\n",[146,635,637,640,643,646,649,652,655,657,659,662,665,667,670,672],{"class":148,"line":636},32,[146,638,639],{"class":197},"    if",[146,641,642],{"class":156}," (",[146,644,645],{"class":259},"!",[146,647,648],{"class":617},"Number",[146,650,651],{"class":156},".",[146,653,654],{"class":606},"isInteger",[146,656,550],{"class":156},[146,658,447],{"class":617},[146,660,661],{"class":156},") ",[146,663,664],{"class":259},"||",[146,666,600],{"class":617},[146,668,669],{"class":259}," \u003C",[146,671,485],{"class":417},[146,673,674],{"class":156},") {\n",[146,676,678,682,685,688,690,692,694,696,698,700,702,704,707,709],{"class":148,"line":677},33,[146,679,681],{"class":680},"szlwh","      throw",[146,683,684],{"class":152}," new",[146,686,687],{"class":606}," InvalidOptionError",[146,689,550],{"class":156},[146,691,243],{"class":235},[146,693,447],{"class":239},[146,695,243],{"class":235},[146,697,561],{"class":156},[146,699,447],{"class":617},[146,701,561],{"class":156},[146,703,243],{"class":235},[146,705,706],{"class":239},"must be a non-negative integer",[146,708,243],{"class":235},[146,710,633],{"class":156},[146,712,714],{"class":148,"line":713},34,[146,715,716],{"class":156},"    }\n",[146,718,720,722,725,727,729,732,734,737,740,742,745,748,750],{"class":148,"line":719},35,[146,721,596],{"class":259},[146,723,724],{"class":599}," size",[146,726,603],{"class":259},[146,728,600],{"class":617},[146,730,731],{"class":259}," ===",[146,733,485],{"class":417},[146,735,736],{"class":259}," ?",[146,738,739],{"class":617}," text",[146,741,651],{"class":156},[146,743,744],{"class":599},"length",[146,746,747],{"class":259}," :",[146,749,600],{"class":617},[146,751,246],{"class":156},[146,753,755,758,761,763,766],{"class":148,"line":754},36,[146,756,757],{"class":259},"    let",[146,759,760],{"class":617}," out",[146,762,603],{"class":259},[146,764,765],{"class":235}," \"\"",[146,767,246],{"class":156},[146,769,771,774,776,779,782,784,786,789,792,794,796,798,800,802,804,807,809],{"class":148,"line":770},37,[146,772,773],{"class":197},"    for",[146,775,642],{"class":156},[146,777,778],{"class":259},"let",[146,780,781],{"class":617}," i",[146,783,603],{"class":259},[146,785,485],{"class":417},[146,787,788],{"class":156},"; ",[146,790,791],{"class":617},"i",[146,793,669],{"class":259},[146,795,739],{"class":617},[146,797,651],{"class":156},[146,799,744],{"class":599},[146,801,788],{"class":156},[146,803,791],{"class":617},[146,805,806],{"class":259}," +=",[146,808,724],{"class":617},[146,810,674],{"class":156},[146,812,814,817,819,822,825,827,829,832,834,836,838,840,843,845,848,850,853,856,858,861],{"class":148,"line":813},38,[146,815,816],{"class":617},"      out",[146,818,806],{"class":259},[146,820,821],{"class":156}," [",[146,823,824],{"class":259},"...",[146,826,554],{"class":617},[146,828,651],{"class":156},[146,830,831],{"class":606},"slice",[146,833,550],{"class":156},[146,835,791],{"class":617},[146,837,561],{"class":156},[146,839,791],{"class":617},[146,841,842],{"class":259}," +",[146,844,724],{"class":617},[146,846,847],{"class":156},")].",[146,849,302],{"class":606},[146,851,852],{"class":156},"().",[146,854,855],{"class":606},"join",[146,857,550],{"class":156},[146,859,860],{"class":235},"\"\"",[146,862,633],{"class":156},[146,864,866],{"class":148,"line":865},39,[146,867,716],{"class":156},[146,869,871,873,876,878,880,882,884,887,889,891,893,895,897,900,902,904,907,909,911,914,916,918,920,923],{"class":148,"line":870},40,[146,872,297],{"class":296},[146,874,875],{"class":156}," {",[146,877,739],{"class":163},[146,879,284],{"class":156},[146,881,760],{"class":617},[146,883,452],{"class":156},[146,885,886],{"class":163}," cipher",[146,888,284],{"class":156},[146,890,236],{"class":235},[146,892,302],{"class":239},[146,894,243],{"class":235},[146,896,452],{"class":156},[146,898,899],{"class":163}," operation",[146,901,284],{"class":156},[146,903,236],{"class":235},[146,905,906],{"class":239},"encode",[146,908,243],{"class":235},[146,910,452],{"class":156},[146,912,913],{"class":163}," options",[146,915,284],{"class":156},[146,917,875],{"class":156},[146,919,600],{"class":617},[146,921,922],{"class":156}," }",[146,924,925],{"class":156}," };\n",[146,927,929],{"class":148,"line":928},41,[146,930,312],{"class":156},[146,932,934],{"class":148,"line":933},42,[146,935,253],{"emptyLinePlaceholder":252},[146,937,939,942,944,946,948,950,952,954,956,958,960,962,964,966,968,970,972],{"class":148,"line":938},43,[146,940,941],{"class":263},"  decode",[146,943,550],{"class":156},[146,945,554],{"class":553},[146,947,284],{"class":259},[146,949,288],{"class":287},[146,951,561],{"class":156},[146,953,564],{"class":553},[146,955,284],{"class":259},[146,957,569],{"class":330},[146,959,572],{"class":156},[146,961,575],{"class":330},[146,963,578],{"class":156},[146,965,581],{"class":259},[146,967,584],{"class":156},[146,969,284],{"class":259},[146,971,221],{"class":330},[146,973,157],{"class":156},[146,975,977,979,981,984,988,990,992,994,996,998,1000,1003,1005,1007,1009,1012,1014],{"class":148,"line":976},44,[146,978,297],{"class":296},[146,980,875],{"class":156},[146,982,983],{"class":259}," ...",[146,985,987],{"class":986},"s-lox","this",[146,989,651],{"class":156},[146,991,906],{"class":606},[146,993,550],{"class":156},[146,995,554],{"class":617},[146,997,452],{"class":156},[146,999,913],{"class":617},[146,1001,1002],{"class":156},"),",[146,1004,899],{"class":163},[146,1006,284],{"class":156},[146,1008,236],{"class":235},[146,1010,1011],{"class":239},"decode",[146,1013,243],{"class":235},[146,1015,925],{"class":156},[146,1017,1019],{"class":148,"line":1018},45,[146,1020,312],{"class":156},[146,1022,1024],{"class":148,"line":1023},46,[146,1025,1026],{"class":156},"}\n",[146,1028,1030],{"class":148,"line":1029},47,[146,1031,253],{"emptyLinePlaceholder":252},[146,1033,1035,1038,1040,1042,1044,1046,1048,1050],{"class":148,"line":1034},48,[146,1036,1037],{"class":606},"register",[146,1039,550],{"class":156},[146,1041,243],{"class":235},[146,1043,302],{"class":239},[146,1045,243],{"class":235},[146,1047,561],{"class":156},[146,1049,368],{"class":617},[146,1051,633],{"class":156},[136,1053,1055],{"className":138,"code":1054,"language":141,"meta":142,"style":142},"import \".\u002Freverse\";\nimport { create } from \"@agntn\u002Fciphers\";\n\ncreate(\"reverse\").encode(\"ATTACK AT DAWN\", { block: 6 }).text; \u002F\u002F \"KCATTAAD TA NW\"\n",[131,1056,1057,1070,1091,1095],{"__ignoreMap":142},[146,1058,1059,1061,1063,1066,1068],{"class":148,"line":149},[146,1060,153],{"class":152},[146,1062,236],{"class":235},[146,1064,1065],{"class":239},".\u002Freverse",[146,1067,243],{"class":235},[146,1069,246],{"class":156},[146,1071,1072,1074,1076,1079,1081,1083,1085,1087,1089],{"class":148,"line":160},[146,1073,153],{"class":152},[146,1075,875],{"class":156},[146,1077,1078],{"class":163}," create",[146,1080,922],{"class":156},[146,1082,232],{"class":197},[146,1084,236],{"class":235},[146,1086,240],{"class":239},[146,1088,243],{"class":235},[146,1090,246],{"class":156},[146,1092,1093],{"class":148,"line":170},[146,1094,253],{"emptyLinePlaceholder":252},[146,1096,1097,1100,1102,1104,1106,1108,1111,1113,1115,1117,1120,1122,1125,1127,1129,1132,1135,1137,1139],{"class":148,"line":178},[146,1098,1099],{"class":606},"create",[146,1101,550],{"class":156},[146,1103,243],{"class":235},[146,1105,302],{"class":239},[146,1107,243],{"class":235},[146,1109,1110],{"class":156},").",[146,1112,906],{"class":606},[146,1114,550],{"class":156},[146,1116,243],{"class":235},[146,1118,1119],{"class":239},"ATTACK AT DAWN",[146,1121,243],{"class":235},[146,1123,1124],{"class":156},", {",[146,1126,600],{"class":163},[146,1128,284],{"class":156},[146,1130,1131],{"class":417}," 6",[146,1133,1134],{"class":156}," }).",[146,1136,554],{"class":617},[146,1138,788],{"class":156},[146,1140,1142],{"class":1141},"sjhu3","\u002F\u002F \"KCATTAAD TA NW\"\n",[122,1144,1146],{"id":1145},"the-contract","The contract",[1148,1149,1150,1177,1195,1212,1219],"ul",{},[1151,1152,1153,1156,1157,1160,1161,1164,1165,561,1168,1171,1172,1176],"li",{},[131,1154,1155],{},"name()"," is the registry name, ",[131,1158,1159],{},"info()"," describes it. Put every option into ",[131,1162,1163],{},"info().options"," with a type, required or not, a default and a description. ",[131,1166,1167],{},"ciphers info",[131,1169,1170],{},"cipher_info"," and the ",[1173,1174,32],"a",{"href":1175},"\u002Fplayground"," form read that list, so an option you skip there is invisible to all three.",[1151,1178,1179,1182,1183,1186,1187,1190,1191,1194],{},[131,1180,1181],{},"MissingOptionError"," for a required option that is absent, ",[131,1184,1185],{},"InvalidOptionError"," for one that is wrong, both before you touch the text. Anything else - wrap it with ",[131,1188,1189],{},"normalizeError(error, \"reverse\")"," so callers get a ",[131,1192,1193],{},"CipherError"," that names the cipher.",[1151,1196,1197,1198,1201,1202,1205,1206,1201,1209,651],{},"Honour ",[131,1199,1200],{},"preserveCase"," and ",[131,1203,1204],{},"stripNonAlpha"," when they make sense for your alphabet. Every built-in defaults them the same way, ",[131,1207,1208],{},"true",[131,1210,1211],{},"false",[1151,1213,1214,1215,1218],{},"Fill ",[131,1216,1217],{},"normalizedInput"," when you had to reshape the input, so a caller sees why the round trip differs.",[1151,1220,1221,1224,1225,1227],{},[131,1222,1223],{},"register(name, Class)"," takes a constructor, not an instance. ",[131,1226,1099],{}," builds one and caches it. Register the same name again and the cached instance is dropped, so a hot reload actually takes.",[122,1229,1231],{"id":1230},"where-it-shows-up","Where it shows up",[127,1233,1234,1235,561,1238,1241,1242,1245,1246,1248],{},"Once the module is imported, the cipher is in ",[131,1236,1237],{},"ciphers()",[131,1239,1240],{},"has()"," says true, ",[131,1243,1244],{},"resolveCipher"," finds it. The CLI and the MCP server only load the built-ins. To use a custom cipher there you fork the binary or build your own around ",[131,1247,1099],{},". There is no plugin path.",[122,1250,1252],{"id":1251},"conventions-worth-copying","Conventions worth copying",[127,1254,1255],{},"The built-ins agree on a few things. A custom cipher that follows them surprises nobody:",[1148,1257,1258,1264,1270],{},[1151,1259,1260,1261,1263],{},"Latin alphabets are A to Z. Non-ASCII letters, digits and punctuation pass through untouched unless ",[131,1262,1204],{}," is set.",[1151,1265,1266,1267,1269],{},"The ",[131,1268,564],{}," echoed in the result are the values actually applied, defaults included.",[1151,1271,1272],{},"Shift 0, one rail, a multiplier sharing a factor with 26 - an option that turns the cipher into an identity or breaks the bijection is an error, not a silent pass.",[1274,1275,1276],"style",{},"html pre.shiki code .sP0CR, html code.shiki .sP0CR{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#5DE4C7}html pre.shiki code .sKlNE, html code.shiki .sKlNE{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#A6ACCD}html pre.shiki code .snHMy, html code.shiki .snHMy{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#ADD7FF}html pre.shiki code .stCPd, html code.shiki .stCPd{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#A6ACCD}html pre.shiki code .scVjq, html code.shiki .scVjq{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#A6ACCD}html pre.shiki code .sQ7BG, html code.shiki .sQ7BG{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#5DE4C7}html pre.shiki code .s1TYA, html code.shiki .s1TYA{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#91B4D5}html pre.shiki code .scZRh, html code.shiki .scZRh{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#ADD7FF}html pre.shiki code .s8yaW, html code.shiki .s8yaW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#A6ACCDC0}html pre.shiki code .sZW6a, html code.shiki .sZW6a{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#5DE4C7C0}html pre.shiki code .sCrqT, html code.shiki .sCrqT{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#A6ACCDC0}html pre.shiki code .siHFe, html code.shiki .siHFe{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#5DE4C7}html pre.shiki code .sNe8j, html code.shiki .sNe8j{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#D0679D}html pre.shiki code .s1jWp, html code.shiki .s1jWp{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#E4F0FB}html pre.shiki code .saoiD, html code.shiki .saoiD{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#E4F0FB}html pre.shiki code .sULi6, html code.shiki .sULi6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#E4F0FBD0}html pre.shiki code .spVlQ, html code.shiki .spVlQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E4F0FB}html pre.shiki code .szlwh, html code.shiki .szlwh{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#D0679D}html pre.shiki code .s-lox, html code.shiki .s-lox{--shiki-light:#005CC5;--shiki-light-font-style:inherit;--shiki-default:#005CC5;--shiki-default-font-style:inherit;--shiki-dark:#5DE4C7;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sjhu3, html code.shiki .sjhu3{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#767C9DB0;--shiki-dark-font-style:italic}",{"title":142,"searchDepth":160,"depth":160,"links":1278},[1279,1280,1281,1282],{"id":124,"depth":160,"text":125},{"id":1145,"depth":160,"text":1146},{"id":1230,"depth":160,"text":1231},{"id":1251,"depth":160,"text":1252},"Extend the abstract Cipher, register the class, and it shows up in create, the CLI and the tools.","md",null,{"icon":1287},"i-solar-add-circle-linear",{"title":28,"description":1283},"F6qOqKUD1Tx9MdUykBWm6MJl5SSV-qvOpX9BhjgN6os",[1291,1293],{"title":24,"path":25,"stem":26,"description":1292,"children":-1},"The same five tools over MCP, the Pi extension and the OMP extension. What they validate, what they bound.",{"title":32,"path":33,"stem":34,"description":1294,"children":-1},"The page behind ciphers.agntn.dev\u002Fplayground runs the library in your browser. What it can tell you and what it can't.",1788614951661]