,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.                     ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*(#&&&&,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*#&&&%//////###&/,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                      .,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&&&(///////////####&,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                            ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,%&&(////////////////###%&,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,   DID YOU EAT ALL THE COOKIES?                 .,,,,,,,,,,,,,,,,,,,,,,,,,,/&&#///////////////////(###&&,,,%%,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.                                                   ,,,,,,,,,,,,,,,,,,,,,&&#//////////////////////(###&%*&&##&,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                                      .,,,,,,,,,,,,,,,&&(/////////////////////////###&%&(/(##&,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                                        .,,,,,,,,,,(&#///////////////////////////(##&&%///###&/,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.                                                         ,,,,,,,%&//////////////////////////////##&&////(####&,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                                          .,,,#&////////////////////////////////#&&/////#####&/,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                                          .,&#////////////////////////////////(#&//////######&,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.                                                         *&//////////////////////////////////(&///////(#####%&,,,,,,,,,,&&%&,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                                       (&///////////////////////////////////#/////////((####&*,,,,,,&&/##%%,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                                     *&////////////////////////////////////(/////////#/#####&,,,,&%//###&#,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                                    &//////////////////////,////////////////////////#/(####&(,&%///####&(,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.                                                 %#///////////#&%////////# #//////////////////////(//####%&&////(####&(,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                                                &/////////%&#&####////////&#////////////////////////(####&/////#####&%,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.                                             &//////#&#,,,,*&###//////////////////////////////////###&//////######&,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*,,,,,,,,,,,,,,,,,,,,,,,,,,,                                          *&/&//&&*,,,,,,,,&%##/////////////////////////////////(#&///////######&&,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,&#(((((#&&,,*%(&,,,,,,,,,,,,,,,,,,,,,,,,,,.                                       .&/%&&,,,,,,,,,    &##////////////#////////////////////#(///////######&&&,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,#&##(##((((&&#(%,,,,,,,,,,,,,,,,,,,,,,,,,,,                                 ,,,,,,%%/&,,,,.        &##////////////////////////////////#////////(#/####&#&,,,,,,,,,,,,,,,,,,,
,,,,,,,,,&/,,,,,,,,,,&&&(((((((((&&#((((((&((&,,,,,,,,,,,/&&&&&,,,,,,,,,,,                        .,,,,,,,,,,,,,&#,            &##/////////////////////////////////////////#//###%%#&(,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,&#(((##(((((((&((((((((((#((((((((((((((#((((((&,,,,,,,,,,,,,,,.   #&&&&&,,,,,,,,,,,,,,,,,,,,,,&.            .&#(////////////////////////////////////////////###&###&,,,,,,,,,,,,,,,,,,
,,,,,,,*///*,,,&(####%&&((((#((%%&&&%%%%((((((((((((((((((((((((&,,,,,,,,,,,,,,,&&%%&&&%&&&%%%%&&&,,,,,,,,,,,,,,&&             &#/////////////////////////////////////////#//(#######&,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,%#,&#(#&#(##((%&*,,,,,,&%%%(#(((((((((((((((((#(#&,,,,,,,,,,,,%&%%%%&&%%%%%%%%&&&*,,,,,,,,%&&&&&&&&            &##////////////////////////////////////////////########&,,,,,,,,,,,,,,,,,,
,,,,,,,,,,&%,,,,,%(#((#%&&((%&,       ,&%%%(((##((((((((((((###&,,,,,,,*&&,(&%%%%&%%%%%%%%%&&&&%###########%&&&&&&           /&#/////////((((((/////////////////////////////(########&/,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,&((##&*,,&%#&        . .&&%(&%&%((&%########&&,,,,,,,,,&&&%&%%%%%%%%%&&%#########################&           &,     &&&&&&&&&&&&&&&&&&&%////////////////////#(#######&,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,&#&(,(    &#&*         /&&,//*#&&&((###(##,,,,,,,,,,,,,&%&&%%%%%%%%&&&&&%%%%%%%%%%%%%############&(         &, ,      &&&&&&&&&&&&&&&&&&&&&////////////////#/########&,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,*&    &#%&.       .&#,,,,,,,,//(&(##&&##,,,,,,,,,,,&%%&%%%%%%%%%%%%%&&&%,,,/%&&&&&%%%%%%%%%%##&%      &%,&         &&&&&&&&&&&&&&&&&&&&&&/////////////#/########&(,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,&#(((%%%((((##(%&&#.(&&%,,,,,,,,,,//(&(#%(%&,,,,,,,,,,,,&%%%&%%%%%%%%%%%&&&&,,,,,,,,,,,,,,,,,*&&&%%%#&& (&&&            &&&&&&&&&&&&&&&&&&&&&&#///////////(/(#######&#,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,*&&%%%&&,,,,,,,,,,,,,,,,,,,,,,,,,,,/&((#((#%&&%,,,,,,,,,,/%%%%%%%%%%%%%%%&&&/,,,,,,,,,,,,,,,,,,,,,,,(&%#####%%           &&&&&&&&&&&&&&&&&&&&&&//////////////#######&/,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,(&&&&(,,,,,/,*%,,,,*(,,,,,,,,,,,*((#((((((##((###&&,,,,,,&((((((((((((((##%(,,,,,,,,,,,,,,,,,,,,,,,,,,&%######%        (&&&&&&&&&&&&&&&&&&&&&/////////////(######%&,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,#&//&,,.,%&&**//#(/,,,,,,,,,,*%(((((((#((((((((#%#%&,,,,&(#((#((((((((#%#&,,,,,,,,,,,,,,,,,,,,,,,,,,,,&######&,          *&&&&&&&&&&&&&&#/////////////(######&&,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,*&,,,.....,,,,,(&%(/////////*,&((((((#(((((((((#((####&,,,&(#(((((#(((((##&*,,,,,,,,,,,,,,,,,,,,&&%,,,*/&######%%           /////(///////////////////######&&&&(#&#,,,,,,,,,,,,,,,,,,,,,
..............&*,,,...,,,,,,,,(&*/#%////(%%%%(&(((#((*/(((((#(((((((###&*,,#((((((((((((&&&&,,,,,,,,,&&&&&&&&&&&&&&&&&&&&%######&           //////////////////////(##%&(//////##&,,,,,,,,,,,,,,,,,,,,,,,
............&,,,,...,,,,,,,,,,*%(#%/&%%#&,,,,,&(((##&*,,,,/(((((((#((#%##(,,%&%%%%%%%%%%%&&&&,,,,,,,,,,,,,,,,,,,(&&&&%%%%%%%%%#&            ///////////////////////////////(##&/,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,&*,,,,..,,,,,,,,,&#((((((((%#%,,,,,,&((((#&/,,,,,,,/((#(((#(###%,,,%%%%%%%%%%%%&&&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&&&/,,,,,,        ////////////////////////////(###&,...............,,,,,,,,,,,
,,,,,,,,,%////&*.,,,,,,,,,,&(((((((((%&,,,,,,/#((((#&&/,,,,,,,,((((((((###&,,,&%%%%%%%%%%%&&&/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*&&&,,,,.  .////////////////////////###%&&&&&&&(,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,&///////%(,,,,,,,,/#&&##((((#(((&&,,&((((#%#&&/&*,,,,,,/(((((((####,,,&((((((((((##%/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&%,,  ///////////////////////(%%%%&&&%###&,,,,,,,,,,,,,,,,,,,,,,,
...,,,,,,,*&///////%*,,,//////&#&##%(((((((((((#((#%*,,&,,,,,,,,,/(#((#(#%#&,,,((#((#(((((%#&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*&&&%%%&&&&&(///////////////////(#&&&&&&&&#####&,,,,,,,,,,,,,,,,,.....
,,,,,,,,,,,,,&(//////&//////&#####*&####(((((((((((&,,,(*,,,,,,,,,(((((((##%,,,,&(((((((((##&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&#//////////////////////////////////##############&,....................
.,,,,,,,,,,,,,,,*&&(//(//%&####&,,,,,,&&###%#(((((%##&.(,,,,,,,,,,,((((((###&...&%%%%%%%%&&&...................................&/////////////////////////////////////##############&,.,,,,,,,,,,,,,,,,,,
............,,,,,,,,,,,,*&&###&#&,,,,,,,,,,(&&&%######%%,,,,,,,,,,,/((((((##&...&%%%%%%%&&&,,,,,,,,,,,,,,,,,,,,,,,,,,,........,&///////////////////////////&#/////////##############&/,,,,,,,,,,,,,,,,,,
........................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,///**,....................................................&#////////////////////////////%&#(///////####%#########&,,,,,,,,,,,,,,,,,,
......................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&#//////////////////////////////&##///////####&#########&/,,,,,,,,,,,,,,,.
,,,,,,,,,,,,,,,,..........................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&(///////////////////////////////&##///////####&&########&....,,,,,,,,,,,,
............................................................................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&/////////////////////////////////&##///////#####&########&/,,,,,,,,,,,,,,
.............................................................................................................................,&////////////////##%%/////////////&#/////////#####&&#######&*,............
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&////////////////###&(///////////(////////////######&#######&(............
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&////////////////####&/////////////////////////(######&######%%...........
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,..............&////////////////(####&/////////////////////////############(.............
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...........,***//(####(///////////////****,,,.....................,,,,,,,
..................,,,,,,,,,,,,,,,,,,,,,*(&&&&#*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,..
...................................&&(((((((((((((%&%,,,,,,,,,,,,,,,,,*,,,,,,,,,,,,%&&&&&%,,,,,,,(&&&&&#(((((((((((((%&&&*,,&&((((((#&%,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,......................
.................................&(((#(((((((((((((#((&%.............&#&%...,,%&#((####&*/&&&((((((((((((((##((((((((((((((%&#((((((((((&(,,,,,,,.......................................................
...............................#&(#((((((((###((((((((#((&%.........(%##&..&&((#####&&%(((((((((#(((((((((((((((((##########%&&(((((((((##&,............................................................
..............................%%((((((&%###&&%%%%&&##(((((((&*......&(#%&&(((((##&((((((((#((((((((((((((########&&&&&%&((((#(((((((((((###&(...........................................................
..............................&(((((####&&%%%%%%%%%&&###((((((%&...&((#&(((((#%(((#((((((((((((((((#&&%(((((((((((((((((#&&&((((((((((((####&...........................................................
.............................#%(((####%&%%%%%%%%%%%%%&####(((#(((&%#((&((((((((#((((((((##((((((((((((((((((((((((((((((((((((%&#(((((((#####&..........................................................
.............................&(((#%##%&%%%%&&&&&&&&&&%&#####(((#((((&&((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((&%(((###%##&................                     .....................
.............................%#((#%##&%%%&&&&&&&&&&&&&&&###(((((((#(((((((((((#(((((((((((((((((((#(((((((((((((((((((##((((((((((((&&###%###&..........                               .................
.............................*&#(####&%%&&&&&&&&&&&&&&&&###((((((((((((((((#(((((((((((((((((((((((((((#%################(((#(((((((((&&####%#......                                       .............
..............................&#(####&%%&&&&&&&&&&&&&&&&%###((#(((((((((((((((((((((((((((((#(((((((((((((###%&&%################((((((#&###&....                                            ...........
...............................&(%####&%&&&&&&&&&&&&%&&&&###(((((((((((((((((((((((((((((((((((((((((((((((((#######%&&&%#############(((&%&...                                                .........
................................&######&&&&&&&&&&&&&%##(#&&###((((((((((%&&&&&&&&&&&&&((((((((((((((&((#&((((#(((%##%#######&&&&#########%&..                                                   ........
..................................&####%###&&&&&&&&%&%###(((((####((((%%%%&&&&&&&&&&&&&&&&&&&&&&&%(((&((#(#((((((((((###&&&&&&&%#%#%&&&%##&                                                      .......
....................................&&############%%##&&####%(((((((%%%%&&&&&&&&&&&&&&&&&&&&&&&&&&&%%%((((((&(((((&&&&&&&&&&&&&&&&&&*.....          OF COURSE NOT! SEE! I SAVED YOU ONE.         .......
........................................#&&&&&&&&&&&&&&%######(((((%%%%&&&&&%%%%%%%%%%%%%%%%%%%%%%&&%%%#(((&(&&&&&&&&&&&%%&&&&&&&&&......                                                         ......
................................................&&###########((((((%%%%&&&&&&&&&&&&&&&&&&&&&&&&&%%%&&%%%(((%%&&&&&%%%%%%%&&&&&&&&#&......                                                         ......
........................................................&####(((((%%%%&#,,,,,,,,,,,,,,,,,,,&,,,,,,,,&%%%((%%&&%&&&&(&(,,,,,,,,,,,,&/.....                                                         ......
.................................................../&&&&&####((((((%%%&(,.                 &      ..&%%%#(%%&&,,,,,,.&            &......                                                         ......
..................................................,/%&&&%(*,,%&((((%%%%&                   &       %&%%%(((%%&       #.          &&%*(%&&/                                                        ......
.............................................*&%/////(#/*,,,,*,,,,((%%%&                   ,      *&%%%%((((%%&(                &%%,,,///&&                                                      .......
.............................................*,..&(//,,,,,,,,,,,,,,,/&&&&*                       &&%%%%((((((#%%&%          (&&(,,,,,,,#&*(.                                                     .......
...............................................&(////,*,,,,,,,,,,,,,,,,,,,,,,*%&/              %&%%%%(((((((#(((%%%&&&&&&(,,,,,(&/,,,,,,,*&                                                     ........
..............................................&///////*,/,,,,,,,,,,,,,,,,,,**,,,,,,*&&      %&%%%%%#(((((((#((((#((&&&&&#((((#&&&*,,,,,,,/,&(                                                   ........
..............................................&///////,//,,,,,,,,,,,,,,&(&#%&,,,,,,,,,,,(&%%%%%%%((((((((#((((&&%%%%%(((((((((%%%%&,,,,,,///&/                                                 .........
...............................................&#////////,,,,,,,,,,,,,,,&###&/&,,,,,,,,,,,,,/,,,,,,,,,,,,,,,(&&&&&%%%%%%%%%%%%%%%&&#,,,//////&                                                ..........
.................................................&(///////,,,,,,,,,,,,,,&###&  *&%,,,,,,,,,(,*(,,(,%,,,,,,,,,&&&&&&&&%%%%%%%%%%&&&&%*/////(&#                                                ...........
...........................heheheh.................&(//////,,,,,,,,,,,,,&####%#####&&,,,,,,,&,,(,,,,,,,,,,,,,,&&&&&&&&&&&&&&&&&&&&&(//(&#....                                              .............
.....................................................&%//////,,,,,,,,,,,*&//,,,,#&&&&&&&#//*,,,,,,,,,,,,,,,,,,,,*&&&&&&&&&&&&&&&/&(&%.........                                           ...............
......................................................./&(/////,,,,,,,,,,,&/&#&,...*&&%(.,/&&#////////////////////////((//////&&&%##&...........                                       .................
..........................................................%&(////*,,,,,,,,,/&**&,.&&/**/&,.(&%***%&&&&#(//////////////(#&&&&#((((##%&..............                                 ....................
.............................................................(&#////,,,,,,,,,,&&/&((*****************************%%%%&   (&#(((###&#...................                          .......................
.................................................................&&///,,,,,,,,,,,&(((****##**********%%/**********%%%/*/***&#(###&..........................                ............................
....................................................................*&%/,,,,,,,,,&((((**%%%%%(****************%%%**********#&##&,.......................................................................
.......................................................................(&%*,,,,,,(&(((((/********************(%%%/********(&&&((((#&....................................................................
..........................................&&&&%,.........................%&&*,,,,,,&((((((((**********/****************((#&((####&#.....................................................................
....................................*%&&&%,,,,,,....*&&&,............&&((((((&&,,,,,,&&((((((((((((/%%%%%#******/((((((&&####&&/........................................................................
...............................*&%,,,,,,,,,,,%&.....,,,,,,*&&*..*&&((((#(((((((#&/,,,,,,*&&&#(((((((((((((((((((((%&&(((##(((((%&.......................................................................
............................&&,,,,,,,............%.,,,,,,,,,,,,%&((#(((((((#######&,,,,,,,,,,,,,(%&&&&&&&&&&&%(((((((((####&&,..........................................................................
.........................&&,,,,,,,..........,,,,....,,,,,,,,,,,,,,/&&(((((#######%&,,,,,,,,,,,,,,,,,,&#(((((((((&(((((((((####&%.........................................................*&.............
......................%&,,,,,,,........,,,,,,,,,,,,,,,,,,,,,,,,,,,///(&%####%##&(//%,,,,,,,,,,,,,,,,*&(((((((((((((((((((((((####&..........................................,,,,,,,,,*&&###&,,,,,,......
...................,&/,,,,,,,.......,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/////%&##&%(&&%,,//,,,,,,,,,,,,,,,&(((#((((((((((#((((((#(((#%##&&.....,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...,&&/(#####&............
.................#&,,,,,,,........,,,,,,,,,,,,,,,,,,,,,,,,,,/,,,,,////////#&##&&&,*/#,,,,,,,,,,,,,,,,&((((((((#((((((((((((((#((((#%#%&*,,,,,,,,,,,,,,,....................../&&/////(#####&............
...............&#,,,,,,,........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*///,//////////&#,##*//&,,,,,,,,,,,,,,,,#%(((#(((((((((((((((((((((((((#%##&&...............................&&#/////////(####&/............
,,,,,,,,,,,,/&,,,,,,,,.........,,,,,,,,,,,,,,,,,,,,,,,,,,,#%*,*////#/////////#&(&//&&,,,,/,,,,,,,,,,,,&((((((((((((((%&(((((((((((((((####%&........................*&&(/////////////(####&&*...........
..........&#,,,,,,,,........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&##((#&#/////&%//////&*&#/&&,,,,//,,,,,,,,,,,&#((((((((((((((#&(((((#(((((((#(######&,.................#&%//////////////////(####&#%%.........,
..........,,,,,,,,.........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#&##((((%&////%&&&//&....%..&,,*///,,,,,,,,,,*&(((#(((((((((#(#&#(((((#(((((((((####(,,,,,,,,,,,,,,&&(//////////////////////####&(##%%.........
............,,,,.........,,,,,,,,,,,,,,,,,,,,,,,,,*&&&&&&&&&##(((((&(#&##(&&,,,,,,,,,,#&,////,,,,,,,,,,&((((((((((((((#(#%&((((((((((((((*,,,,..........&&///////////////////////////####&/(##&,........
,,,,,,,,,,,,,,,,.......,,,,,,,,,,,,,,,,,,,,,,,,,%&#((((((((((%#(((((&&#(((&,,,,,...........*///,,,,,,,,&((((((((((((((((###&((((((/.................#&(//////////////////////////////###&(//##(&........
.....................,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&%###(((((((((((((((((((&........................,,,,/...........,,............................&&/////////////////////////////////###%&///###&........
...........,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&####&&###((((((((((((((((/,,,,,,,,,,,........................................................&&////////////////////////////////////###&////###&,.......
............................,,,,,,,,,,,,,,,,,,,,,/&#########((((((((((((/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#&//////////////////////////////////////(##&/////###%#.......
,,,,,,,,,,,,,,,,....................,,,,,,,,,,,,*///(&%#######(((((((.....................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&%////////////////////////////////////////##&//////###&/,,,,,,.
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,............................................................................................&(/////////////////////////////////////////##&(//////###&,,,,,,,,
.....,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&////////////////////////////////////////////#&////////###&,,,,,,,,
.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.                                 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&/////////////////////////////////////////////#&/////////##%%,,,,&&##
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.                                          .,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&(/////////////////////////////////////////////(#/////////(##&,,&&#####
,,,,,,,,,,,,,,,,,,,,,,,,,.                                               ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,%&//////////////////////////////////////////////(///////////##&&&//#####%
,,,,,,,,,,,,,,,,,,,,,        Don't ya want it? ??                       ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&//////////////////((##&&&///////////////////////////////////#&#///######&
,,,,,,,,,,,,,,,,,,                                                    ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*&/////////////(&&&######//////////////////////////////////////%#///#####%&#
,,,,,,,,,,,,,,,,                                                   .,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&(/(//////%&&########/////////////////////////////////////////%(///######&##
,,,,,,,,,,,,,,,                                                ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&//%//&&#########/////////////////////////////////////////////////######&###
,,,,,,,,,,,,,,                                           .,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&//&#########////////////////////////////////////////////////////##(########
,,,,,,,,,,,,,,,                             #&&&# ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&//######///////////////////////////////////////////////////////##/#########
,,,,,,,,,,,,,,,,                        &&####&%,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&//////////////////////////////////////////////////////////////##/##########
,,,,,,,,,,,,,,,,,,,,.              .,&&(####%&,,,,,,,/%&&&&&&%%%%%%&&&&%,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&///&//////////////////////////////////////////(%&&&&&&&&&&#//##/(##########
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&((####%&,,/&&((((((((((((((((#########&(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&//&%&&(//////////((&&&&&&&#,/%///////////&&&&&&&&&&&&&&&&&&&&&//###########
,,,,,,,,,,,,,,,,,,,,,,&#,,,,,,,,,&((#(###&%&((((((#((((################&&&&*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&#&&&&&&&&&&&&&&&(**,,,,,,   &*       ,&&&&&&&&&&&&&&&&&&&&&@&&############&
,,,,,,,,,,,,,,,,,,,,&##&,,,,,,,&((((###&((((#(((((####%%&&&&&#(/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&////&,,,,,,,,,,,,,,        %(           &&&&&&&&&&&&&&&&&&&&&&@##########&,
,,,,,,,,,,,,,,,,,,,&((##&,,,,/&((#((#%(((((((((#(((((((((((((((((%&%,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#&&&&&&&&*&                   &(            .&&&&&&&&&&&&&&&&&&&@@%########&%,,
,,,,,,,,,,,,,,,,,,&#((##&/,,#%(((((#((((((((((((((((((((((((##(((((((%&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&&&&&&&&&&&&&&%&                *&               &&&&&&&&&&&&&&&&&&@&%########&&&&/
,,,,,,,,,,,,,,,,,,&((#(##&,(%(((((((((((((((((((((((((#(((((((((((#(((((&*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&&&&&&&&&&&&&#####&&             &&&&.              &&&&&&&&&&&&&&&&@&//######%&(////#
,,,,,,,,,,,,,,,,,,(&((#(##&&(((((#((((((((((((((((((((((((%%#######((#(((#&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*&&&######################&&/   ./%%#(((((##&#                 &&&&&&&%(/////#####&(////(###
,,,,,,,,,,,,,,,,,,,/&(((((##((((((((((((((((((((((((((((((((((&&&%#######((&,,,,,,,,,,,,,,,,,,,,,,,,,,,*&&#################################(((.(,(/((((#%%&                  ///////////###(//////(###%&
,,,&&#(((#&&&&&*,,,,,,&&&(%((((#(((((((((((((((((((((#&#((((((((&(,,,%&&&&&&/,,,,,,,,,,,,,,,,,,,,,,*&&######################################(((((((((#%%%%&                  ./////////(////////###&&&&&
,&(((((((((((((((((((((((((((((((((((((((((((((((%&&&&&&&%#((#((##&,,,,,,,,,,,&&#(((%&&,,,,,,,,,(&################&&&&%%%%%##&#############%%%%%%%%%%%%%&&                    ///////////////(#(////////
&((((((((((((((((((((((((((((((((((((((((((#&&&&&&&&&%%%%%%%%((((#(&,,,,,,,&&((((((%%%%&%,,,,,(&&%%%%%%%%&&&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&(                          /////////////////////(###
&(((((#(((((((((((((((((((((((((((((((&&&&&&&%%%%%%%%%%%%%&&%%#(((#(&,,,&&((&##%%%%%%%%%&(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&&/,,,,,,,,,,,,,,,,,,,,,,,,,,,,         /////////////////(####%&(
%(((((((((((((((#######(((((((((((((((%%%%%%%%%%%%%%%%%%%&&&&&%%(((((&&((((,*&&&&&&%%%&&&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&&&&&/*,,,,,,,,*#&&&%*           ,/*/////////////#(///&&&&
&(((((((((((((((((((((((((((((((((((((%%%%%%%%%%%%%%%%%&&&*,(*&%%#(&(((/,,,,,,/&&&&&&&&&&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*&,              / //////////////###&%**,
&#((((#((((((((((((((((((((((((((#((((%%%%%%%%%%%%%&&&*,,,,  & &%%((/,,,,,,,,,,,,,,,(((/&/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&               ,///////////////#####&(
,&##((((((((((((((((((((#((((#(((((((((%%%%%%%%&&&*,,,,.       &&&%,,,,,,,,,,,,,,,*////#&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&                 &%/////////////######
,,&#######(((((((((((((((((#((((((((((((%%%%&&**,,,        *&&&%%#,,,,,,,,,,&,,#&(////&#%&&%/******/%&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&&,                (&///////////////######
,,,/&#########(((((((######(((#(((%&&(*,**(%%%&&&&&&&&&&%%%%%%/,,,,,,,,,,,##%/*(%(//%&**(*****%%*****((&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,%&#     .,.            &%////////////////(#####
,,,,,,&&################%&((#&(((((&#,,*,*******,,,,,,,,,,,*&&(,,,,,,,,,,*///////&&/*******%%%**/(((&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&(,,,,*(&&               (&//////////////////#####
,,,,,,,,,,%&&&%%%%%&&&&&##&&((((&%*(#/,,*********,,,,,,,*&///#&&&&#((///((%&&&#(((&&&(((((((((((&&/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&,                .&///////////////////#####
,,,,,,,,,,,,,,,,,,,,,(&&%#((((#&#&&/,*,,,,******,,,,,,,,,,,,,,,,,,,,,,,,&&  &(((((&&(((((&&&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&   ,,             &////////////////////#####
,,,,,,,,,,,,,,,,,,,,,,,&####((((&%///,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*/////(&%,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&  ,,(             &/////////////////////(####
,,,,,,,,,,,,,,,,,,,,&#%&&&###%((&////,/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,////(&&/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,(%,,,&%            &#/////////////////////(####
,,,,,,,,,,,,,,,,,,,,,&%#(((&&###&&(/////,,,,,,,,,,,,,,,,,,,,,,,,,,,,////&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,##,,/&(   *       /&///////////////////#%/(####
,,,,,,,,,,,,,,,,,,,,,,,&###(((((####%&&&(///*,,,,,,,,,,,,,,,,,,,,////&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&,,&,&   ,(      &///////////////////(#&/(####
,,,,,,,,,,,,,,,,,,,,,,,,,&&#####((((((((/(,,*/(%#(/*,,,,,,,,,,,//(&(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*,,&#  ,&*    &(//////////////////(##&/#####
,,,,,,,,,,,,,,,,,,,,,,&&##((((((((##((,*,/,,,,,,,,,,,,,,,,,,,/(&(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&(#& ,,&*, #%//////////////////(###&(#####
,,,,,,,,,,,,,,,,,,,,,,,*&&&&&&%#(((//((,,,,,,,,,,,,,,,,,,,,*&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&/////&&%&&/&///////////////////####%%#####
,,,,,,,,,,,,,,,,,,,#&%######(((((#&(,,,/,,,,,,,,,,,,,,,,,,&#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&///////####&///////////////////#####%&#####
................#&####(((((((((((((((&,,,,,,,,,,,,,,,,,,/&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*/####&(/////////////////(#######&##(/*
.............#&####(((((((((((((((#(((&(,,,,,,,,,,,,,,,,&(#%..................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*******,,,,,,,,,,,,,,,,,,,,
...........&####%(((((((((((((((((#((((%%,,,,,,,,,,,,#*,,&#(&*.........................................................................................................../&&&&..........................
........#####%#(((((((((((((((((((((((((&#,,,,,,,,/*,,%&(//&%(&..................................................................................................*&&&#(###&&..............,%&&&%(/(#&,,,
.........(##((((((((#((((((((((((((((((((&#,,,,,,,/(#/,&#%%&&#(%&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,..........................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,(&&&#////(#####&/,,,,,,*#&&&%(//////////##%%,,,
,,,............/((((((((((#(((((((((((#(((&(,,,,,///#&/&##%#(((((%..,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*%&&%/////////(####%&(*&&&&(//////////////////(##(&....
,,,,,,,,,,,,,,,,,,.......,/((((((((((((((((................................................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,%&&#/////////////#####&&%/////////////////////////(###%&.....
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,...............................................................................................(&&(////////////////(#&&(/////////////////////////////#####&%,,,,,,
.........................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.................................................................#&#///////////////////(%///////////////////////////////(######&/.......
.................................................................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&&//////////////////////////////////////////////////////##/#####&.........
.................................................................&&&%......................................................%&//////////////////////////////////////////////////////#///(####%&..........
.............................................................&&(((#&.....................................................&#///////////////////////////////////////////////////////////#####&............
........................................................./&#((((##&,..........,/(%&&&&&%(/.............................&%///////////////////////////////////////////////////////////#####&*.............
..........................................%.....&...../&(((((((##&....&&&%((((((((((((((((((((%&/.....................&////////(&&%//(&&%/////////////////////////////////////////(####&,...,(&&&&&&&&..
.......................................&...*........&#((((#((###&*&(((((((((((((##((((#######&&,.....................&//////&%///////////(&//////////////////////////////////////###&&&&&///(####&&.....
.........................................,.......#&(((((#((###&&((((((((#(((((((######%&&#..........................&/////////////////////////////////////////////////////////(##&&//////(####&&&.......
...................................&&%(#&#.....&&(((((#(((##%&(((((#(((((((#####&&&/...............................&(///////////////////////////////////////////////////////(%(////////(###%&#%%........
...............................,&#((((((((&,.#&(((((#(((##&&((((&((((((##%&((((((#%&&&%,...........................&/////////////////////////////////////////////////////////////////(###&%##&%.........
............................./&(((&&%(#((((&&(((((#((((##&(((((#((((((((((((((((((((((((((&&......................&#////////////////////////////////////////////////////////////////##&&####%&..........
............................&%#((&##&(((((%&((((((((((#(#(((((((%%%%%%%#(((((((((((##((((((((#&...................&/////////////////////////////////////////////(%&&&&&&%(/////////#&%######&...........
...........................#%###&#(##&(((%%(((((((((#(((&(((%%%%%%%%%%%%%%%#(##########((((((((#&....nom <3....../&//////////////////////////////////////#&&&&&&&&&&&&&&&&&&%////(#(/######&............
...........................&####&((##&((#&(((#(((#((((((((%%%%%%%%&&&&&&&&%%%%((##&&&#########(((&...............&///////(&/////////////////////////(&&&&&&&&&&&&&&&&&&&&&&&&&///(//(#####%&............
...........................&###%&(((%#&(&(((#((((((((#((#%%%%%&&*,,,,,,,,(&&%%%%((##&..../&&&&&&&&(......(&#(#...&//////&(/////////(%&&&&&             .&&&&&&&&&&&&&&&&&&&&&&/(////######&.............
..................,#%%#,....&#%#&(((##&%&((((((((((((((#%%%%%&,,,,,,,,,,,..,(&%%%#(((&*............,.#&&,....,&&&&&&&&&%&&&&%%%%%(#(/#%/&(                &&&&&&&&&&&&&&&&&&&&/////######&..............
..........*....&&(((((((((%&(&%##&(((##&#(((((((((/((((%%%%%&*,,,,,,          %&%%%((((&............../&&&&&&&&&&&&&&%#(((((*//*//*//,(/(###%&/           &&&&&&&&&&&&&&&&&&&//////#####&(..............
........&&&&.,&(((((((((((((((#&&#&(((((%(((((#((( *(((%%%%&&,,,,,             .&%%%((#(&......../&&(((((%%&&#########((((/*//*//*/*//,((#####%%&.        &&&&&&&&&&&&&&&&%///////#####&%...............
.......&&&&&&&(((((((((((((((((((((&&(((((((((#(((& (((%%%%&#,,,,                &%%%((((&...&&(((&#((%%%%%&&&########(((((/,//,//*(((((######%%%&&       &&&&&&&&&&&%(//////////#####&/................
......&&&&&%&%(((((((&##&%%&&(((((#(((((#((#(((((((((((#%%%&&,,,,                 &%%%((((&((((#(((&%%%%%%&&&&##########((((((((((((((######%%%%%%&         ////////////////////#####&.*&&&&............
%....(&&&&%%&##(((((###&%%%%%%&%((((((((((((((((((((((((%%%%&*,,                 / &%%%((((((#(((,,,,&&%%&&&&&###########################%%%%%%%&%            ////////////////#####&&%//(##&............
%%&..&&&&&%%&%(((#(#%#&&%%%%&&&&&&((((((((((((((#((((.(((%%%%&*,                 ( &%%%((((((*,,,,,,,,,,,/((&#%%%%%##################%%%%%%%&&                //////////////(##%&#/////##%&.............
%%%%&&&&&%%%%&((((#####&%%&&&&&&&#&&&((((((((((((((((/&(((%%%%&&,                  &%%%((*,,,,,,,,*/*,,*//(&%&&&*//&####%%#####%%%%%%%%&&&                   .////////////(%&#///////###&/..............
%%%%%&&&&%%%%%&(((######&&%&&&&&&&&%##(((((((#(((((((%&((((#%%%%&%                 %&%%,,,,,,,,,&%,,,///(&%(*&,*&&######%%%%%%%%%%&&#                       ////////////&#/////////###&(................
%%%%%%&&%%%%%%%&&((#######&&&&&&&&&&&&&&####((#(((((((#(((#(((%%%%%&#              &%%%,,,,,,,,,%,,%//%& %*/&/&###%%%%%%%%%&&&(,,,,,                       ..///////////////////(##&&&&&&/..............
%%%%%%&&%%%%%%%%%&&#(#%#####%%#########%####(((#(((((((((((((((((&&%%%%&&,       &&%%*,,,,,,,,,,,,/(&(**/**&%#%%%%%%%&&&&&&&&&%*,,,,,,.                     ./////////////////#%&(/##%&(................
%%%%%%%&%%%%%%%%%%%%%&&&#############&&###%###(((((#(((((&%//#%**********((####%#**,,,,,,,,,,,,,,%&((&&((&%%%%%%%%%&&&&,........../&%,,,   .&%//////////(&///////////////////(#&&&&&&&&&%/..............
%%%%%%%%%%%%%%%%%%%%%%%%%&..,*//*.../%%/..&####(((((((((((&(*//*********************,,,,,,,,&,,,&/*#&&&&%%%&&&(......................*&/,&%////////////////////////////////////////////((####&*.........
%%%%%%%%%%%%%%%%%%%%%%%%%%&......*&#&&.....&%##%#(#((((((&*/&/*********************,,,,,,,,,,&&**//#&#&%,..............................&////////////////////////////////////#%&%%%&&&&&&&%*.............
%%%%%%%%%%%%%%%%%%%%%%%%%((&.&&.&%#(((&......&%####(#(((%&&&/,*,,***************,,,,,,,,,,,,,//%&/..................................,&/////////////////////////////////////&//########&%................
%%%%%%%%%%%%%%%%%%#(%%(%(((&&#&&&#(((((&...&&&##&#####((((&///,,,,,,,,,,,,,,,,,,,,,,,,,,,,//&%.....................................&//////////////////////////////////////////&%/########&#.............
%%%%%%%%%%%%%%%%%%((((((((((&((&##(((((#&..(&##((((&&%####&///*,,,,,,,,,,,,,,,,,,,,,,,,,,&&......................................&(//////////////////////////////////////////////&#/#######%&...........
%%%%%%%%%%%%%%%%%%((((((((#(#((&#(((((((&....*&###%#((((##&///**,**,,,,,,,,,,,,,,,,,,,,%&.....,%&&%&...........................&#//////////////////////////////////////////////////&(/(#######&.........
%%%%%%%%%%%%%%%%(((((#(((((((((%((((((((&(......,&&########&((&%###((((#&#,,,,,,,,,,,,(,&&%*,,//&&*..........................%&/////////////////////////////////////////////////////&(///#######&/......
%%%%%%%(((%%%((((((((((((((((((#((#((((((&&*..&&&&&%%%###(((##&###((#((((((((*,,,,,,,,,,,,,**,,,,,,,*%&%.................../&////////////////////////###/////////////////////////////&////(#######&%....
&&%%%%((((((#(((((((((((((((((((((#((((((&&&&....(&&%#########&%#%(((((((((((((((,,,,,,,,,,,,,,,,,,#&#//*(&...............&(///////////////////////###&#(#&&(////////////////////////((//////#######%&..
&&&&&%((((((((((#(((((#((((((((((((((%%%%&&%%&..........#&&##%#&&#%(((((((#(((((((((,,,,,,,,,,,,,,,*,,,*&&&#............&#////////////////////////###&   /////////////////////////////%////////########&
&&&&&##%((((((((((((((((#((((((((((((%%%%&%%%%&.&&..............,&###(((((((#(((%(((((*,,,,,,,,,,,,,,/&//(&...........&&/////////////////////////###&       /////////////////////////////////////#######
,&######(((((((#((((((((((((((((((%%%%%%%%%%%%&&&&,...............&###(((#((((((((&(((((/,,,,,,,,,,,,,,(&%#%.........&/////////////////////////(###& ,        .////////////////////////////////////#####
....&&%###((((#((((((((((((#%%%%#%%%%%%%%%%%%%&&%&/................(&##((((((((((((#&((((((,,,,,,,,,,,,,,&.........&(/////////////////////////####& *,           *//////////////////////////////////(###
..&%##%%&&&&&%#(((((((((##((%%%%%%%%%%%%%%%%%%&%%%&..................&##%((((((((((((%&((#(((,,,,,,,,,,,,,&......%&//////////////////////////####&,&&   ,           //////////////////////////////////(#
.....(&&%###########((((%%%%%%%%%%%%%%%%%%%%%%&%%%&...................*&##(((((((#(((((#(((#(((,,,,,,,,,,,,&...*&///////////////////////////###%&(&.&   ,*   ,         /////////////////////////////////
.........&&%########&&&%%%%%%%%%%%%%%%%%%%%%%%%%%%......................&#,,,,................................&(///////////////////////////####&#...&  .,/   .*,,         //////////////////////////////
................./&&&&&&&&&&&&&%%%%%%%%(/................................................................. .%%///////////////////////////(###%&.....(%  ,,&   ,/(,,          ///////////////////////////
.................................................................................../&&&,.....................,//////////////////////////####&%.......#& ,,,&,  ,*&&*,           ////////////////////////
.............................................................................%&&&///##&............................////////////////////####&*..........&&,,/&&& ,*&.&*,            *////////////////////
....,,,,,,..........................................................*%&&%(/////////##&%.......................................,,*//////((*,...............*&&,..,&&&..&(           .....................
....................................,,,,,,,,,,,,,.........../&&&#////////////////(###&&.................................................................................................................
....................................................,&&&#///////////////////////####&#&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,..........................
..............................................%&&(/////////////////////////////####&##&.................................................................................................................
,......................................./&&(//////////////////////////////////###%&(##&.................................................................................................................
......,,,,,,,,,,,,,,,.............../&%/////////////////////////////////////(###&#/##%&.................................................................................................................
.......................,,,,,,,,,,&&////////////////////////////////////////####&//###&.........................................................................................................,,,,,,,,,
..............................(&//////////////////////////////////////////###&(///###&,.......................................................................,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.............
............................&&//////////////////////////////////////////(##&(////###&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,......................................
,,........................&&////////////////////////#&%//////(&(///////(#&//////###&(.......(&&(.................................................................................................,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,*&/%&&%&&////////////////(&/////////////&/////%////////(##&%,,(&&/###&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.
.......................%%%////////&//////////////////////////////(////////////(##&%&%//(###&%,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.............................
......................%&/////////////////////////////////////////////////////(##&#///(####&.............................................................................................................
,,,,,.................&(////////////////////////////////////////////////////(##&////(###&(........                      ................................................................................
,,,,,,,,,,,,,,,,,,,,,#%////////////////////////////////////////////////////(#%/////####&.....                              .............................................................................
.....,,,,,,,,,,,,,,,,&////////////////////////////////////////////////////#(/////#####&/,,.                                  ...........................................................................
..................,,,&//////////////////////////////////////////////////////////#####%&,.                                     ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
.....................&/////////////////////////////////////////////////////////######&,       thanks, dude.                   ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
.....................&////////////////////////////////////////////////////////((####&/                                        ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,........
,,,,,,,,,,,,,,,,,,,,,&////////////////////////////////////////////////////////#%@@@&&.                                        ,,,,,,,,,,,,,,,,,,,,,,,,,,................................................
,,,,,,,,,,,,,,,,,,,,,&/////////////////////////////////////////////////////(&@@&@@@&,,                                      .,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,&///&/////////////////////(/////////////////////////&&&@&&@@@@%,,,                                    ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,%&/&#/////////////////////&(///////////////////////%&&&&&&@@@@&,,,,,                                 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                     ,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,#/...%&&&&&&&&&&&&&&&&&&&%(&(((((///////(%&%&&&,       &&&&@@@@&,,,,,,,,                            ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,                             ,,,,,,,,,,
,,,,,,,,,,,,,,,,.,,,..#########%&&&&&&&&&&&##%&&&&%%%###((((*(,#/%&        &&@@@&,,,,,,,,,,,,,                   .,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,         FAGGOT?                ,,,,,,,,
,,,,,,,,,,,,,,,,,,,#%########%&&&&&&&&&&&#############&((((((,(,#%%#       #@@&&,,#&&%&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*,,,,,,,,,,,,,&&*                                .,,,,,,,
,,,,,,,,,,,,,,,,,%&#########&&&&&&&&&##############&&%&##(((((##%%&       ,,,&#&(/##&&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/&(((((((((((#&%,,,,&##(&                             ,,,,,,,,,
,,,,,,,,,,,,,,,(&#############%%#############%%&&&%%###&&##%%%%%&&      ,,/&(///###&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*&#####((#((((((((&*,%###(%/                       ,,,,,,,,,,,,
,,,,,,,,,,,,,,&#########################%%&&&%%%######%%%%%%%&&.       *&/////###&*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#&%###%%(((((((((&*&##((&,,,,,,,,,....,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,&%####################%%%&&&%%%%###%%%%%%%&&&%,,.         /////(##%&,**,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#&%(((((%((((&&%((((((&((&&&#((#(,,,,&&%#,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,&##############%%%%%%&&&%%%%%%%%%&&&&&/*,,,,,            /////##&&%##&*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&((((##(((((((#(((((((((((((((#(&(((#,&#(%,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,%&######%%%%%%%%&&&&%&&&&&&&%&&&&&&%#*,,                  ./////(##%&*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&########&&&&&&&(((.((%%%%%%%(((((((#(#&#(&,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,&%%%%%%%%&&&&%(*,,,,,,,,,,,,,,,,,,,,,,,&                    /////(##&&,,,,,,,,/%,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&,   .,,&%#((%&&,,,,,*&%((((((((%#(&,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,#&&&&%*,,,,,,,,,,,,,,,,,,,,,,(,,,,,,,,,&                  *&%/######&&,,,,,,,,,,,*#,,*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/(        ,&%(%&.      ,,&%((%.((((((%,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&%,,  ..    .%&&&&#        ////////(####%&,,,,,,,,,,&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,(      *   &%%&          ,&%(&&((#((((/,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&&*             &********/&%  ///////////#####&,,,,,,,,,/,,,,,,,,,,,,,,,,,,(&&,,,,,,,,,,,,,,,,,,,,,,,%          ,&%%&    *      &%((((((%#(((&,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&&,,,,/#            &***%%%%***(&////////////#####&*,,,,,,,,,,,,,,,,,,,,,,,,/&&&%%&,,,,,,,,,,,,,,,,,,/&&((         &%(%&           &%(#((##&#((((##,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&*&&&&           (.(&/***%%%******&////////////#####&*,,,,,,,,,,,,,,,,,,,,,,&&&%%%%%&(,,,,,,,,,,,,,,/&&#((((&(#&&&*%#//%&          ,&%(((&#%#((((#((&*,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&&.    ,  && .&******&&&&&&&&&&&&///(/////////#####&/,,,,,,,,,,,,,,,,,,&&%&&%%%%%%%&*,,,,,,,,,,,,,&&&%%%&&&,,,*///////#%.       #%%(#&(*/&&#(#((((((&,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&%&*  ,,*  &((*********&%##(&&(///&&#&&&/////////#####&*,,,,,,,,,,,,,,,,/&&&&%%%%%%%%%&&&,,,,,,,,,,,&&&&&&/,,,,,,&%******(##%(/(%##*/*,,*//*&###((((((((&/,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,/&(#& .,*,   &((#%%%/***%%%&#@@#//&&(/////&&////////#####&*,,,,,,,,,,,,,&%(&&&&%%%%%%%%%&&&**&#&,,(##(%&///,,,,,,,*,/*************/#*****,,,/&%%%####(((#(((&,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,&((##&,,&.    &%(((((********(&###&%/////////(&#/////(#####&,,,,,,,,,,,,&#(&&&%&%%%%%%%%&&%&##((&,,,%%#(((&(//*,,,,,,,,,,***************,,**,//&#####%######&*,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,&%/(###%&(       *&((((((&&((((((%&&&#////////////&#////######&,,,,,,,,,,,&##(#&(((%%%%(((&%##((((&,,,,,&%#(#((&%//%/(.#&,,,,,,*,*****,,,,,,/*///&/&&%####&&(,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,#&///####&           *&#((((((((%&&&&%&&&#///////////(&////######&,,,,,,,,,,&%#(((#((#(%((((#(((#((&,,,,&##((#&(((((%(&#&//&,,&,,,,,,,,,,,,,,//////&,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,(&////###&#                /&&&&&///&&///////////////////&///######%&,,,,,,,,,/%%#((((#(((((((((((((&&,,,,,,,&&%((((((((&&##((/#*,,,,,*//##%%&&&&&#(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,#&/////###&                 ,,,&&&////&&////////////////////&#/(######&(,,,,,,,,,&#%#((((((((((#((((&#((,,,,,,,*&##(((((((((((((&,,,,,(*&((#*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,&&/////(##%&                 ,,*&##@####@@#####/////////////////&/#######&,,,,,,,&&&&%###(((#(((#(((((((&,,,,,,,&###(((((((%(#((#((&,,/*,(&&%((%,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,&#//////###&.                 ,,,&&&&&%###@@#########//////////.   &########&,,,,,,(&&%###%((((((((%#(((&&&&&,,,,&##(((((((((&#(((((((&,,&(*&#((((&,,,,,,,,,,,,,,,,,,,,,,,,,//,(,,,,,,*,(#
,,,,,,,,,,,#&////////##%&                  ,,*&&%#&@####&@###########(/////,      &#######&#,,,,,,,&&&&&&&&%%%%%%%%%%&%%&*,,,/%##(#(((((((((&#(((((((#/%#&###((((&,,,,,,,,,,,,,,,,,,,,,,%(%,&*&&,##,,/,%
This commit is contained in:
Skip R. 2023-04-24 23:43:54 -07:00
parent 27ee437975
commit afad5f80d1
17 changed files with 446 additions and 47 deletions

5
environment.d.ts vendored
View file

@ -4,6 +4,11 @@ declare global {
DISCORD_CLIENT_ID: string;
DISCORD_CLIENT_SECRET: string;
DISCORD_ALLOWED_GUILDS: string;
LDAP_HOST: string;
LDAP_BIND_USER: string;
LDAP_BIND_PASSWORD: string;
BASE_DOMAIN: string;
}
}

90
package-lock.json generated
View file

@ -14,6 +14,7 @@
"@types/react-dom": "18.0.11",
"eslint": "8.39.0",
"eslint-config-next": "13.3.1",
"ldapts": "^4.2.5",
"next": "13.3.1",
"react": "18.2.0",
"react-dom": "18.2.0",
@ -362,6 +363,14 @@
"tslib": "^2.4.0"
}
},
"node_modules/@types/asn1": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@types/asn1/-/asn1-0.2.0.tgz",
"integrity": "sha512-5TMxIpYbIA9c1J0hYQjQDX3wr+rTgQEAXaW2BI8ECM8FO53wSW4HFZplTalrKSHuZUc76NtXcePRhwuOHqGD5g==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -403,8 +412,7 @@
"node_modules/@types/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
"dev": true
"integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA=="
},
"node_modules/@typescript-eslint/parser": {
"version": "5.59.1",
@ -655,6 +663,14 @@
"get-intrinsic": "^1.1.3"
}
},
"node_modules/asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"dependencies": {
"safer-buffer": "~2.1.0"
}
},
"node_modules/ast-types-flow": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
@ -2270,6 +2286,23 @@
"language-subtag-registry": "~0.3.2"
}
},
"node_modules/ldapts": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/ldapts/-/ldapts-4.2.5.tgz",
"integrity": "sha512-4R+q+TGFBoXqERwWWvZPF/x1X4y5vdoHhaPWzs8gHXG6mIGJrrGanUWTb7+wZ9G8+razNQ1d8tHv94mFD+3jHQ==",
"dependencies": {
"@types/asn1": ">=0.2.0",
"@types/node": ">=14",
"@types/uuid": ">=9",
"asn1": "~0.2.6",
"debug": "~4.3.4",
"strict-event-emitter-types": "~2.0.0",
"uuid": "~9.0.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -2902,6 +2935,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@ -2991,6 +3029,11 @@
"node": ">=10.0.0"
}
},
"node_modules/strict-event-emitter-types": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz",
"integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA=="
},
"node_modules/string.prototype.matchall": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz",
@ -3575,6 +3618,14 @@
"tslib": "^2.4.0"
}
},
"@types/asn1": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@types/asn1/-/asn1-0.2.0.tgz",
"integrity": "sha512-5TMxIpYbIA9c1J0hYQjQDX3wr+rTgQEAXaW2BI8ECM8FO53wSW4HFZplTalrKSHuZUc76NtXcePRhwuOHqGD5g==",
"requires": {
"@types/node": "*"
}
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@ -3616,8 +3667,7 @@
"@types/uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==",
"dev": true
"integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA=="
},
"@typescript-eslint/parser": {
"version": "5.59.1",
@ -3775,6 +3825,14 @@
"get-intrinsic": "^1.1.3"
}
},
"asn1": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"ast-types-flow": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
@ -4941,6 +4999,20 @@
"language-subtag-registry": "~0.3.2"
}
},
"ldapts": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/ldapts/-/ldapts-4.2.5.tgz",
"integrity": "sha512-4R+q+TGFBoXqERwWWvZPF/x1X4y5vdoHhaPWzs8gHXG6mIGJrrGanUWTb7+wZ9G8+razNQ1d8tHv94mFD+3jHQ==",
"requires": {
"@types/asn1": ">=0.2.0",
"@types/node": ">=14",
"@types/uuid": ">=9",
"asn1": "~0.2.6",
"debug": "~4.3.4",
"strict-event-emitter-types": "~2.0.0",
"uuid": "~9.0.0"
}
},
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -5334,6 +5406,11 @@
"is-regex": "^1.1.4"
}
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@ -5396,6 +5473,11 @@
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="
},
"strict-event-emitter-types": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz",
"integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA=="
},
"string.prototype.matchall": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz",

View file

@ -15,6 +15,7 @@
"@types/react-dom": "18.0.11",
"eslint": "8.39.0",
"eslint-config-next": "13.3.1",
"ldapts": "^4.2.5",
"next": "13.3.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View file

@ -0,0 +1,18 @@
export async function POST(request: Request) {
const form = await request.formData();
let username = form.get("username");
let displayName = form.get("display-name");
let email = form.get("email");
let avatar = form.get("avatar");
let password = form.get("password");
let confirmPassword = form.get("confirm-password");
if (!username || !displayName || !email || !password || !confirmPassword)
return new Response("Missing required fields", { status: 400 });
if (password !== confirmPassword)
return new Response("Passwords do not match", { status: 400 });
return new Response(":3", { status: 200 });
}

View file

@ -1,3 +1,31 @@
@property --bg {
syntax: "<color>";
inherits: true;
initial-value: #2d2a2e;
}
@property --fg {
syntax: "<color>";
inherits: true;
initial-value: #fcfcfa;
}
@property --bg-alt {
syntax: "<color>";
inherits: true;
initial-value: #403e41;
}
@property --fg-alt {
syntax: "<color>";
inherits: true;
initial-value: #727072;
}
:root {
--theme-transition: 0.5s ease;
}
* {
box-sizing: border-box;
padding: 0;
@ -8,15 +36,27 @@ html,
body {
max-width: 100vw;
overflow-x: hidden;
color: var(--fg);
background-color: var(--bg);
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
html, body, input, label {
transition: background-color var(--theme-transition),
color var(--theme-transition);
}
input, button {
font: inherit;
color: inherit;
}
input::placeholder {
color: var(--fg-alt);
transition: color var(--theme-transition);
}
a {
color: inherit;
text-decoration: none;
}
@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
}

View file

@ -1,3 +1,4 @@
import ColorChanger from "@/components/ColorChanger";
import "./globals.css";
import { Inter } from "next/font/google";
@ -16,7 +17,11 @@ export default function RootLayout({
}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<body className={inter.className}>
{children}
<ColorChanger />
</body>
</html>
);
}

View file

@ -8,6 +8,14 @@ export type DiscordAccessTokenResponse = {
scope: string;
};
export type DiscordUserResponse = {
id: string;
};
export type DiscordGuildResponse = {
id: string;
};
export function discordRedirectUri() {
return `${process.env.BASE_DOMAIN}oauth/discord/redirect`;
}
@ -18,8 +26,18 @@ export async function getDiscordID(token: string) {
Authorization: `Bearer ${token}`
}
});
const res: { id: string } = await req.json();
const res: DiscordUserResponse = await req.json();
return res.id;
}
export async function getDiscordGuilds(token: string) {
const req = await fetch("https://discord.com/api/users/@me/guilds", {
headers: {
Authorization: `Bearer ${token}`
}
});
const res: DiscordGuildResponse[] = await req.json();
return res.map((guild) => guild.id);
}
export const makeTicket = (): string => v4();

View file

@ -3,7 +3,8 @@ import {
discordRedirectUri,
DiscordAccessTokenResponse,
makeTicket,
getDiscordID
getDiscordID,
getDiscordGuilds
} from "../oauth";
import { cookies } from "next/dist/client/components/headers";
import prisma from "@/prisma";
@ -40,7 +41,15 @@ export async function GET(request: Request) {
});
if (!tokenResponse.ok) throw "baby";
let tokenBody: DiscordAccessTokenResponse = await tokenResponse.json();
const id = await getDiscordID(tokenBody.access_token);
const guilds = await getDiscordGuilds(tokenBody.access_token);
const allowedGuilds = process.env.DISCORD_ALLOWED_GUILDS?.split(",") ?? [];
let allowed = false;
for (const guild of allowedGuilds) if (guilds.includes(guild)) allowed = true;
if (!allowed)
return new Response("not permitted to register account", { status: 403 });
const user = await prisma.authTicket.create({
data: {

View file

@ -1,5 +1,6 @@
.main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;

View file

@ -3,6 +3,8 @@ import styles from "./page.module.css";
export default function Home() {
return (
<main className={styles.main}>
<img src="/icon.svg" alt="gluestick logo" width="256" />
<p>
:3
<br />

View file

@ -0,0 +1,45 @@
.form {
max-width: 500px;
}
.form input[type=submit] {
padding: 1rem 1.5rem;
font-size: 140%;
background: var(--bg-alt);
border: 0;
border-radius: 0.15rem;
cursor: pointer;
font-weight: 600;
}
.buttonContainer {
display: flex;
justify-content: center;
margin: 2rem 0;
}
.formRow {
margin: 1rem 0;
}
.formRow label {
display: block;
font-variant: all-small-caps;
font-size: 105%;
}
.formRow input {
padding: 0.5em 1em;
border: none;
border-radius: 0.15rem;
margin: 0.5rem 0;
width: 250px;
display: block;
background: var(--bg-alt);
}
.hint {
color: var(--fg-alt);
font-size: 80%;
transition: color var(--theme-transition);
}

View file

@ -0,0 +1,101 @@
"use client";
import React, { InputHTMLAttributes } from "react";
import { HTMLInputTypeAttribute } from "react";
import styles from "./RegisterForm.module.css";
function Input({
label,
name,
hint,
type,
placeholder,
...props
}: {
label: string;
name: string;
hint?: string;
type: HTMLInputTypeAttribute;
placeholder?: string;
} & InputHTMLAttributes<HTMLInputElement>) {
const id = React.useId();
return (
<div className={styles.formRow}>
<label htmlFor={id}>{label}</label>
<input
type={type}
name={name}
id={id}
placeholder={placeholder}
{...props}
/>
<p className={styles.hint}>{hint}</p>
</div>
);
}
export default function RegisterForm() {
return (
<div className={styles.form}>
<form action="/api/register" method="post">
<Input
hint="The username you'll use to log into NotNet services. By standard, this should be lowercase, and usually your first name."
type="text"
name="username"
label="Username"
placeholder="julian"
required
/>
<Input
hint="Your display name - this can be what you go by online, for example."
type="text"
name="display-name"
label="Display name"
placeholder="NotNite"
required
/>
<Input
hint="Your email address. An inbox will be created on @n2.pm that forwards to this email."
type="email"
name="email"
label="Email"
placeholder="hi@notnite.com"
required
/>
<Input
hint="Your password. To secure NotNet services, make this a strong and long password."
type="password"
name="password"
label="Password"
placeholder="deeznuts47"
required
autoComplete="new-password"
/>
<Input
type="password"
name="confirm-password"
label="Confirm password"
placeholder="deeznuts47"
required
/>
<Input
hint="This image will automatically be used as your avatar with supported services. Optional."
type="file"
name="avatar"
label="Avatar"
accept="image/png, image/jpeg"
/>
<div className={styles.buttonContainer}>
<input type="submit" value="Join NotNet!" />
</div>
</form>
</div>
);
}

View file

@ -1,5 +1,6 @@
import { cookies } from "next/dist/client/components/headers";
import styles from "../page.module.css";
import styles from "@/app/page.module.css";
import RegisterForm from "./RegisterForm";
export default function Page() {
const cookieStore = cookies();
@ -10,39 +11,7 @@ export default function Page() {
return (
<main className={styles.main}>
<form action="/api/register" method="post" className={styles.form}>
<div>
<label htmlFor="username">Username</label>
<input type="text" id="username" placeholder="julian" />
</div>
<div>
<label htmlFor="display-name">Display name</label>
<input type="text" id="display-name" placeholder="NotNite" />
</div>
<div>
<label htmlFor="email">Email</label>
<input type="text" id="email" placeholder="hi@notnite.com" />
</div>
<div>
<label htmlFor="password">Password</label>
<input type="password" id="password" placeholder="deeznuts47" />
</div>
<div>
<label htmlFor="avatar">Avatar</label>
<input
type="file"
id="avatar"
name="avatar"
accept="image/png, image/jpeg"
/>
</div>
<button>Submit</button>
</form>
<RegisterForm />
</main>
);
}

View file

@ -0,0 +1,15 @@
.color-changer {
position: absolute;
right: 0;
bottom: 0;
width: 40px;
padding: 8px;
opacity: 30%;
transition: opacity 0.25s ease-in-out;
}
.color-changer:hover {
opacity: 100%;
}

View file

@ -0,0 +1,59 @@
"use client";
import React from "react";
import styles from "./ColorChanger.module.css";
const colors = [
{
name: "Monokai Pro",
bg: "#2d2a2e",
bgAlt: "#403e41",
fg: "#fcfcfa",
fgAlt: "#727072"
},
{
name: "Gruvbox Dark",
bg: "#282828",
bgAlt: "#3c3836",
fg: "#ebdbb2",
fgAlt: "#a89984"
},
{
name: "Amora",
bg: "#1a1a1a",
bgAlt: "#171717",
fg: "#DEDBEB",
fgAlt: "#5c5c5c"
}
];
export default function ColorChanger() {
const [current, setCurrent] = React.useState<string>("Monokai Pro");
return (
<img
src="/paint.svg"
alt="paint"
title={current}
onClick={() => {
const pool = colors.filter((x) => x.name !== current);
const idx = Math.floor(Math.random() * pool.length);
const colorScheme = pool[idx];
const fixedColors = {
"--bg": colorScheme.bg,
"--bg-alt": colorScheme.bgAlt,
"--fg": colorScheme.fg,
"--fg-alt": colorScheme.fgAlt
};
for (const [k, v] of Object.entries(fixedColors)) {
document.documentElement.style.setProperty(k, v);
}
setCurrent(colorScheme.name);
}}
className={styles["color-changer"]}
/>
);
}

9
src/ldap.ts Normal file
View file

@ -0,0 +1,9 @@
import { Client } from "ldapts";
const client = new Client({
url: `ldap://${process.env.LDAP_HOST}`
});
// await client.bind(process.env.LDAP_USER, process.env.LDAP_BIND_PASSWORD);
export default client;

20
src/public/paint.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.5 KiB