f{Š¿Ð¿³_ñù,¶,K9o 4ŽÇµôù7lËñÞniJiggiår<¤-MGÆ
-¬À
-¬À
-¬À
-¬xuVÄ÷+zÌÒRøCÌr9‡+Gqç6ÞQWžñb"ø×Qe×ï"ùWLº‚® +è
-ß XXXXX/ÁŠ|~Åj,ÖnŒÖmu¼MÞæÚÛ¤+è
-º‚®ð
‚XXXXXñ¯Ya,–±X¼Í;¼Mº‚® +è
-ß XXXXX晋ež)oÓÓ˜Þf’|¦ƒ·™–5²H“û¸ëŠší¥÷7/D
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_21_6.dat b/lib/phpqrcode/cache/mask_6/mask_21_6.dat
deleted file mode 100644
index 6bd505b4a..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_21_6.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚQÀ Cÿ9M{ÿËi]èÒýX‰1¤À Å-½C!»É³Dìû7
WìÙœ§Ø&rDñ)~Î]<MÎ ·3(>{ƒïA¡«ÿíŽa²¼Sý
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_25_6.dat b/lib/phpqrcode/cache/mask_6/mask_25_6.dat
deleted file mode 100644
index d45083aab..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_25_6.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚQAÀ »÷5öÿŸÛ2)êe+Ä(XmÊZtÆ*(õÚ¹«;ÃçtJã<峂†_Ú¤‡3°oŠÜ½Ú´"Ì¢a²zh}Ñ&qv€µSGÊÖ™,ó-÷‡™J›Í4}³™¦oS[âü}w
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_29_6.dat b/lib/phpqrcode/cache/mask_6/mask_29_6.dat
deleted file mode 100644
index 0408e2240..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_29_6.dat
+++ /dev/null
@@ -1,3 +0,0 @@
-xÚÕRA
-À0ºûšäÿŸÛXcÔõ²ÓL(4E”ÔˆB
-8CÖܾ޳nÃM©+lǪÃÕ†Ožé1]&•Ú¥4UëD-6-$:6ÊdZá?yæÛlôÝf£?í˜
åŽ8?žß²±<Ûlôž}ž¹g›göí *
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_33_6.dat b/lib/phpqrcode/cache/mask_6/mask_33_6.dat
deleted file mode 100644
index 8de4ba5c9..000000000
Binary files a/lib/phpqrcode/cache/mask_6/mask_33_6.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_6/mask_37_6.dat b/lib/phpqrcode/cache/mask_6/mask_37_6.dat
deleted file mode 100644
index b37ff0ab6..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_37_6.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚí”AÀ &ýÿçÚT `½ôèj_Ý`åÃî8¦Ž¹€GÁ1“œ`–B”Ý`;»ù+ØÂì}åÄÌØ&s£ÒçŒ]<§J…QF=mb3 UŒF'ÚØ6¶Æ–á„E âü€¹5õJa÷wZØÖù60¢¬
-ß[¹·ë¶9¡±ý9¶”ì{Á–SšÛ\Ýž8Õ`k&Áœos}{â[Rß¾ý[¥+—þwðºÕO‹èd^jW
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_61_6.dat b/lib/phpqrcode/cache/mask_6/mask_61_6.dat
deleted file mode 100644
index f2d3f10df..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_61_6.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚí—KÀ D÷s¸ÿåÚ¤µE~Ý‚ihÌÄ'™
-ÑŽÍÀòNÏ'oVWßéà£jspèÚCzÓþìÑο©¥ÃaÌÏg!«…#WD%~Ü˃Y?±JÛfŒÚåR€E¸¢ŽÁKoæͼ™Ç˜§ü|Ƀˎ*ÌOÿP7 Šž‡åÛn¾ë¼½¥™7ósã†`ž½ïÌÍÖÀõsúåçdôD¾Ÿÿ¹Ÿsé~>ý<ßiÌK'Žl'¸×9¥ûÐ%.ÆîÄ7
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_65_6.dat b/lib/phpqrcode/cache/mask_6/mask_65_6.dat
deleted file mode 100644
index 550fc8fe7..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_65_6.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚíWQÅ ûïiäþ—{KžNLk?˜e$ŒQ´ikÝìÆÚ4¸çö1{˜á‰ð×`+®!úÚ®ºM
Á?áû “’°È1b°8†ž£·¦.ŒÞ^ƒwÌÞò¹ìèsn²ÁFjè5¹…EaQX|‹=wä¼@°2v<òÅ‹Åž»‰–|4w»êê\ÔUXÇBQz+óÊT±ÈTǹÖcøBÓzž/4ç8Õë,‘»5Ý`¡¥¨»ý¹È± üOV$
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_69_6.dat b/lib/phpqrcode/cache/mask_6/mask_69_6.dat
deleted file mode 100644
index a3e4fa0f2..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_69_6.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚí˜KÄ @÷œî¹™dThÃðí¦ hLSSEžq eY@<ã¯+Þ*£|ß窮%‹®‹>¥¡¨®‹¹zÃ*7ë–Åe´¤öÆ6ãQ¶½©S`šÞ.²¯>»sEË'¨%@[‘Ž6°@PË0Ãh
£aôFÕxtpl²2§Âóý‡Q-g1N†feo^ßøÑüë†Ñ0F¯dT>N_ÕOö’‘wË‹G3ìùªu†åœÁ»gˆå{‘3<Ê[žÔºb?Â'6ï^ºŠ
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_73_6.dat b/lib/phpqrcode/cache/mask_6/mask_73_6.dat
deleted file mode 100644
index ab71b70ae..000000000
Binary files a/lib/phpqrcode/cache/mask_6/mask_73_6.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_6/mask_77_6.dat b/lib/phpqrcode/cache/mask_6/mask_77_6.dat
deleted file mode 100644
index ad5a660e3..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_77_6.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚí˜Ñà EßùøÿŸÛ²i‹ÙÅVäaË.š¦±F©§pST›YÖô4q÷ú~´z…«=Ÿä:öÍ’
û6îøÍüôm8‘¾:#0PضiDy:2Å '§ùZs±Š&}Ïôç滜\r‘0\¥Åš•˜Xw¬Â;iP¬äàÈ”Lœ)ÒS¬±£eÔ•Ü{hˆDu9÷L‘žb½•©JÞÒS÷ŒSÆ)™’)™ÞgZš{÷þeÜøŸé)ã”qJ¦dúLw+ƒ#Ó3-V0ÅÕ·lîjƒ¹™ýÚ ×S-ÕS
ê½9=ݯ÷¦5ÁPPïõq1Mõ?ågÓ
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_81_6.dat b/lib/phpqrcode/cache/mask_6/mask_81_6.dat
deleted file mode 100644
index 28a6d0752..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_81_6.dat
+++ /dev/null
@@ -1,3 +0,0 @@
-xÚí™Q„0Dÿ9
Üÿr»ÉÚR³LÕvök‡šÆ`´¤¯0 º;æi6ÜûçÑÚ\|ñí_¿êccÔ1«¢h¾ýuŒ§½ioÞó#2ƒ¬}x*.YûtÃ&¸±
-Ö°¶ÀÖq/K‚;3ÌväeÐ̢Ȋ҂AÛH±ë?`]é5ÒðK¿¡Êü´†w¿!}{Zû߲žW
-Œ”yâ·¾Àž^§_y¼k±k±–^K¯•×ªáb-ÖbÝYSÚ¸'ÖœNóÈuÃ×õšÕ#M½fõHS¯Q?|]¯IýðA¯ÆÚi™Mû÷‘yíì¤yuWà
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_6/mask_85_6.dat b/lib/phpqrcode/cache/mask_6/mask_85_6.dat
deleted file mode 100644
index d5403e49a..000000000
Binary files a/lib/phpqrcode/cache/mask_6/mask_85_6.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_6/mask_89_6.dat b/lib/phpqrcode/cache/mask_6/mask_89_6.dat
deleted file mode 100644
index eeeb5d197..000000000
Binary files a/lib/phpqrcode/cache/mask_6/mask_89_6.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_6/mask_93_6.dat b/lib/phpqrcode/cache/mask_6/mask_93_6.dat
deleted file mode 100644
index 6ff38db68..000000000
Binary files a/lib/phpqrcode/cache/mask_6/mask_93_6.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_6/mask_97_6.dat b/lib/phpqrcode/cache/mask_6/mask_97_6.dat
deleted file mode 100644
index 3a2072efd..000000000
--- a/lib/phpqrcode/cache/mask_6/mask_97_6.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚíšaƒ0…ÿs¸ÿå¶dÅêÒÒFx[²=4ÆH–ùŠoŠj3«4í&§s}¹*ŽÃž—÷aV¸cˆ&3žêÜ5‰arWç^aþ«÷LClÉÒzžqì,ÝÌÑ1†xî
µ‰SQ»N»ô»]·¢/GiuÄ`&æ ¢–wƒ%‚,‘%²D–ÈYú"K½t¸¤+åHE'|R2Ï(v1¨öv–¢ÿqiëëŸqd‰,‘%²D–~€¥è%Ø»Jjï}íͺĺÄgY"Kd‰,ý+Kñö
-–]W–të+sF/)ü]¥.zNòÚÝ'`°>®½1='#–`+bƒ¥l]Z±”¶¬ýð
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_101_7.dat b/lib/phpqrcode/cache/mask_7/mask_101_7.dat
deleted file mode 100644
index 1f6bc5129..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_101_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚíšQà Cÿ}rÿËm“Ê`éÚÊfªjòTé#±¥ÔäÞ54'tûí…îf¼aÈЇo°–$±c<ÙËêãÝÓÕñHÝ Ìh8„lÕÛûþÁëo=½Ä„ŽÅ§àHvº©;‹z€¤!ƒ|/‹FŽÐ3cfÌŒ‰S×Ê…±±ã‚¼êñ8©KŽ)4©9 ”Qç1ç1×J3fÆÌØÅ›S+ÅwÖcçõ˜ó˜ó˜k¥3cf캌ùîâ¾zÌyÌy̵Ҍ™±1¦{¨²bL÷¶çÍX™S+óï.to{>ô˜îmO§ÇJ2²û3cÄ<6ãXn0F´
)
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_105_7.dat b/lib/phpqrcode/cache/mask_7/mask_105_7.dat
deleted file mode 100644
index 6b0cacfe9..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_105_7.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚíšA
-Ä0E÷žFï¹a MÒ™˜N¾Px)¸pQ£¼è_è~ž|ñ(b¿F’„šç$.Ÿa¿o“ÝòWÿGNÚPæUÇ–·‰Mþ%{‡ëoôHQôÙUñl¯Ö´¿¬L^>+Éçm“#{°{eo&Y2sÛoM•)gncO9s›ßZŠ³´3wÇo™„Ú+Âè{ô=f.ìÁìÁz½‡Þ£ïÑ÷˜¹°{°{è=ôz¾GßcæÂìÁÞsÙkCQÏžpÓíÊ^¶€&Ñ{^£÷¼NïÊ·UïÕìï
ìe5°ç}¯æE‰wGûßn+o
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_109_7.dat b/lib/phpqrcode/cache/mask_7/mask_109_7.dat
deleted file mode 100644
index 9875cbe8c..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_109_7.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚíšA
-…0D÷9MrÿË}µÚ*˜_x-d˜ú:Î"îÇŠ¢Ý-kÅ"Šâ¨š¢œ•dŒ{›¿Õ»ü¤·ñã¯ó³ÞÊגɬ|'ƒÒÚràQ5+ sûŒ¡)Ûc•Õê7úÕ-ÑÕó»1nní–ºqÿÉ”–ÔÍJtgô¬^îʉwÿ̘Ň-ùƒ?ÿ*š&Mmý@ee5éø^Ñ
-c¢”°
-«°
-«ÀªÒ,¬¶ýªïbï\1¿×3ýjõ4óØT¿ZžfÅ¢·»oé¯ «è*º
-«°
-«°
-«°:›Uüêt¿*ü¿ú½¹ºŠ®¢«°
-«°
-«°
-«“Xů²0<·BWÑUtVaVaVƒYÕl
-Þ°ªÙkýf5éýª_Ö ¿ªÙkýáW5{«µ€ä–5pnõC¬éªZ:¬Å bv
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_117_7.dat b/lib/phpqrcode/cache/mask_7/mask_117_7.dat
deleted file mode 100644
index cde78c10d..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_117_7.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚí›Yà Dÿç4pÿËU•²ÈêIª>"ù%6æed‘Ò8rðSÍNsŽµU¯ánëk5¦Xeøjѻު®u—Ûî¦ô¿ö±VÛXgøê,l`øøîuÝÊÀî÷£!‚h‰XZù\VãlM±ìë|[ͬÝÂ0Ã0Ã0ÿÃí–#hF'ëøc]²±ž¾¦iéí>ìúŽûHÐat†a†a†a~<ÃÔÆzØyÆqkO‡£Ãè0Ã0Ã0ÃðææŒãªžF‡Ña†a†aþ)†§2ÇË°éfÃ’áþ%ƒÀz8ùëátO=¼žâ€3ÿ=Ž‚áÖî3œÜ:ìÿcw‘
-ûV$¢
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_121_7.dat b/lib/phpqrcode/cache/mask_7/mask_121_7.dat
deleted file mode 100644
index d5d577f7e..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_121_7.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚí›[
-Ä Eÿ³šdÿ›ú°ŒÆi;^az,ø#6Æž^rÝׂ§h¶ŽôµÈêÐ&Ýì¨çÜ^amýËÀ•YŸ9×_Òغô5C·r–6ë®ðt^ù^ÅWlûÅÐEä˜ôز~É¿|èM®èmýÁåÛmSò}÷¶Ó(
Û°
Û°
Û°}ŽmQ½]ŒZ§Vüq½]¼ÓvËѲ"™M¹1fÙúGÔÛÛ,q½½ÍB·Ñmt¶a¶a¶a¶ÂöÄz»eF²3»cxI¹—D·Ñmt¶a¶a¶a¶ÿŸmÎnð’ý$ºn£Û°
Û°
Û°
Ûa[}ï¦`[yëæÀö–°¾Þ–Þ»)Ïn<¹æ4ÜKú/éó¼¤O¢»s§l¨nçlÔmŸµÝ/GëÙ
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_125_7.dat b/lib/phpqrcode/cache/mask_7/mask_125_7.dat
deleted file mode 100644
index f9ec0887b..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_125_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_129_7.dat b/lib/phpqrcode/cache/mask_7/mask_129_7.dat
deleted file mode 100644
index 9bf51d529..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_129_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_133_7.dat b/lib/phpqrcode/cache/mask_7/mask_133_7.dat
deleted file mode 100644
index b643ffeda..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_133_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_137_7.dat b/lib/phpqrcode/cache/mask_7/mask_137_7.dat
deleted file mode 100644
index 11d212bf4..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_137_7.dat
+++ /dev/null
@@ -1,5 +0,0 @@
-xÚíœÝ
-Ã Fïó4úþ/·
úc§‹«_Ç‚+¸{üSÚK<ŸÚÎo[l
-ìÀìÀΟ²Ó
-©ý0û¡7Ö‰µVÆl;b¶–ëüè™7æõfM¾S´†î ;è1ìÀìÀìÀìL³C¾<ßQíïœ[+@wÐt‡˜
v`v`v`v&Ù!ß ›ï°7ÚX+@wÐt‡˜
v`v`v`v8ÊYP΂¢;èºCÌ;°;°;°saG{™Ä;Ú»>vRœ|ÇžåùŽö®K¾£½ë£ØMÎðHÖ
-‚³#Ð(S›ËÎòúqÌçd
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_141_7.dat b/lib/phpqrcode/cache/mask_7/mask_141_7.dat
deleted file mode 100644
index 98dffab00..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_141_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚíœA„ E÷=
Üÿr“IëŒTY@¿ÉÄÅ0!µøø|1”²—št¹bG0µæԗѤ…s¡2Z/îç¿oa‚ìøÜ\ÿq¬ãzÜÛOnÒ‹MºÏñÞn™šñt„áX"Kÿ—m‘eM}çÚòCpµíÄP™L^¾µŒ„S0S0S0S£L ø)Ç”‚ŸÚ˜êYß¾%žÔbÑý,õS©l?ÕzC§Ð)tŠµLÁLÁLÁLI2…ŸzŸŠRX¶h¾£@§Ð)tŠµLÁLÁLÁLI1…Ÿz‘ŸbÏ·óŽB§Ð)Ö~0S0S0S0Å7´ø)ö|ù†B§Ð)˜‚)˜‚)˜‚©÷3Õ–«L%Ÿtfª¬wM±Ÿ*:~ªhù©»¡Zºç«sn’cª÷$1UTtJgÆ8‹ÌÕOYºE
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_145_7.dat b/lib/phpqrcode/cache/mask_7/mask_145_7.dat
deleted file mode 100644
index 4aa2bac11..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_145_7.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚíœÑ
-à Eßó5úÿ?W6Zµ ¦-›^é±àƒ2‰q§×ÄbG‰Ÿ¢X6(ƉuÍ"“LbÑbÝGuû÷ŽÎ¼®··Gkø¨:HwA[¿jšÔm¯øH¢ø¬Ýžï3ïŬýîßâOðkQ{l·|ê»èT›†EmÇJfÙLÊ?ŸÚ2"&Á¬Á¬Á¬Á¬ÁÚ¬)Äk©ÝRf¢—µÙcï“Ñ̉ÓåFŠÑ,§“z©¦=躆®±‡„5Xƒ5Xƒ5Xƒµ7±F¼¶\¼¦p–ÚUs#躆®±‡„5Xƒ5Xƒ5Xƒµ°F¼¶d¼ÆYö•Üº†®¡kì!a
Ö`
Ö`
Ö`o‰×8ËæÛct
]C×ØC¬Á¬Á¬
gMå‚5…[´N¬%éÄk÷h•ñZp®?›¯IÜ£•Ï²ƒ^n$ˆÑæÞY7A×ÖÆëZP[¶
fȓ0
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_149_7.dat b/lib/phpqrcode/cache/mask_7/mask_149_7.dat
deleted file mode 100644
index 809f00554..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_149_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚíÜÑnà …á{?
¼ÿËu“Ú†…´2»ÕG$nˆˆcççÈF¡µKëÉ×Ðb3ª÷ôþÖªt³îûªPcçÌ¥Ó7[¢?9:ñÕý['éÁë9'¾*Ó–àGæÜa°½hÖ_¿¹/«zÁ+Î6XB‡>ê˜2ôqYÀJ…0Êù黚BfaƒÄ 1ˆÁªÈ‡9c7Gë ùOl©ô,Å^¥ßÅ꽓òÁ3ƒÕòA:Hé Ä 1ˆAbƒÄàÿ0X4œ%Ù«½û#ÇÔd>¢&Cé ¤ƒÄ 1ˆAbƒ<šA{ôo¿G¯&óLM†ÒA:H1ˆAbƒÄ 1è¿ {ôj2þ› ƒtbƒÄ 1ˆA&1Xç`¼_Ö9ÛðÊ`«™®B˜¶G_çlÃ5™:g5™¶ajMæÍLÔÁŠËèƒIý <|r.
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_153_7.dat b/lib/phpqrcode/cache/mask_7/mask_153_7.dat
deleted file mode 100644
index c1ab27664..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_153_7.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚíÜQ‚0„á÷=
½ÿ匉B5ˆ
-ю惤/ͲåïØIÙiº^-àî®Zkm|»YDhë9›ÎêÃ\{’KÇƶ·{Ÿy—³Ç3ßv†¶Ì»œE]u`RÚÇrý"›ß}ÛY½ëeÂ2{ÛVV8][×.n:+2_ç¶ÊÂBÃ&6±‰Mlb›ØÄ&6ß`3i¿9Y³³åΌ諡yÙúU}ÔŸ82f-vÚ–Õ6 nÒMºI7±‰Mlb›ØÄ&6±ùólæî7ãÎð‚þÕ¢›t“nÒMlb›ØÄ&6±‰Mlþ2›ÎüÍÙ^Ð/ˆnÒMºI7±‰Mlb›ØÄ&6±é;gxA¾C¡›t“núO‹Mlb›ØÄ&6±y€Íy•ÇfP¥Õ[6Ÿ4ºßÌ«Ùk`v^Ð+Ó9ÄʬOÛ±ùð}Ï攨›™+ZXíè®=:iWE
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_157_7.dat b/lib/phpqrcode/cache/mask_7/mask_157_7.dat
deleted file mode 100644
index 2db27f685..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_157_7.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚíÜM
-ƒ0Eáù[M²ÿÍ•‚ü£s¡_„ž‰ÇÛã }F¹†Qks½‡Ì{Ý%¶WqÛ÷×îø.ž¬Ýþϯ]Ü8evV½ßbvV}è®_µÜEÌ»n3W^KÃ\Ÿ`äÖV캽çZl³˜Å,f1‹YÌþ;³af±Ôkž·Þ¨×úiàè“ÁÄzÍôÖËz?urVÎÊY9‹YÌb³˜Å,fù,Ÿå³|VÎÊY9+g1‹YÌb³˜Å,Ÿå³|–ÏÊY9+gý7Æ,f1‹YÌb³|–ÏòY>+g嬜Å,f1‹YÌb³|–ÏòY>+g嬜•³˜Å,f1‹YÌþÈlâùƳi§o˜ý.\¦ÏÆo<úl;9º:Âg[®Ï¶lŸmÁÔ^œI>=gÏ™œ³-yk_TAµ
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_161_7.dat b/lib/phpqrcode/cache/mask_7/mask_161_7.dat
deleted file mode 100644
index 35ba8ff48..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_161_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚíÜÑŽÂ …áûyšòþ/皨E)Æ®›î1~4áÂœý93,˵´ «+µØZT=Zeâ¶C»¹ú.~ißµ§¯ÊÞÖ&>Œ,–ÿÔï´6eù˜·í•Ö~,láW]ì
®»º2Íê꺱Ý\Ñþ;×µ2j"–±Œe,ËrXŒÝµVÓ(ícìµµZÓ–1‘™§8Þ©í§‰±/,'ÇØt™.ÓeºŒe,cËXÆ2–±Œåß±,_þŠ|ytõüç£ï|ÎÜ]¦Ët™.cËXÆ2–±Œe,cyËòå/É—ysî‹.ÓeºL—±Œe,cËXÆ2–±lo…|ÙZ{+è2]¦Ëbl,cËXÆ2–±Œe{+äËÖŠØ[A—é2]¦ËXÆ2–±Œe,c9åÌCÐXÎ<ëþÆò’Ÿ/owsP¾œyÖý]¾œyÖ}·VdÙìæ°¹¯d9J—Ó‡ì)Ë1õ jI2ë
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_165_7.dat b/lib/phpqrcode/cache/mask_7/mask_165_7.dat
deleted file mode 100644
index e27fb8edf..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_165_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚíÝQŽ‚0Ðÿ·š²ÿÍM&A,NĘ̈!—x0é‡&XZׇZ»-KØ«[êÞÉeÉj‡½Œëæx,ƒ§¼ú.ï·g}ë`;ÿþþ+k{ËÑ~1ŸŽÿ}á+k{ËØ¥ž™¾SGùWãgî}‡Ý¬@Û?_µö8í¾o+·k][·hô”Wü8~·u·ÜMÆgœqÆg|j<õ·ú¶¶Ú*ßq=<¯”Ïü¤æÛ“RwÆ“ëñÕøøÌüÄÌéŸÈq9.Çå8ãŒ3Î8ãŒ3Î8ãIÆÕãUGÿ?~µsnr\ŽËq9Î8ãŒ3Î8ãŒ3Îx€qõøÇÕã®yç979.Çå¸gœqÆgœqÆgÜ=)êq×À¸'EŽËq9.ÇgœqÆgœqÆwOŠzÜ50îI‘ãr\ŽûÎ8ãŒ3Î8ãŒ_ÆøVvd}²ÇÞøü¡aõx˯ÇÛ5êñã)¹&ÿ9)ñÙÞf¼¥çxþ3øYH]ûS^*/
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_169_7.dat b/lib/phpqrcode/cache/mask_7/mask_169_7.dat
deleted file mode 100644
index ef1a181f2..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_169_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_173_7.dat b/lib/phpqrcode/cache/mask_7/mask_173_7.dat
deleted file mode 100644
index 3b5137125..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_173_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚíÝÝjÃ0Ð{=Mòþ/·
RbÖH¬û«´rj\Ç=ý,ºm·coúZŽ8;»ïmÏ÷½mÛÝë±0b÷ƒ_ßšt$~Wu5ÛÇšNnÜ'?dÕf2¶í(oÁïßGÚ,Løþù÷õ6_{»zÅÑ÷Æ?
Ë9úwq9Ç
àS!ÆŒëÛ9Îoë€î2 L`˜˜pµŒ¬––O»Enï¶v8L˜²v8L¸º UáY×"ûd}ê K›r‚œ 'È ÖL`˜À&0 L`B'fÕ:ïO8ÛTcTc\kŒr‚œ 'È ÖL`˜À&0 L`BìY²gIñ§kŒr‚œ 'È ÖL`˜À&0 L`‚ç"íYRcô\¤œ 'È r˜À&0 L`˜ÀÏEÚ³¤Æè¹H9ANä&0 L`˜À&ü'úÿ!Ø;êÅq+¶Yõ„l*´Ü³´þ=Ø€ã9¶jŒ[2ÚÖÿ€ Ms¤Ÿ‡Ô„–çë*Ø
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_177_7.dat b/lib/phpqrcode/cache/mask_7/mask_177_7.dat
deleted file mode 100644
index 068477c92..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_177_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_21_7.dat b/lib/phpqrcode/cache/mask_7/mask_21_7.dat
deleted file mode 100644
index 4f9f1386d..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_21_7.dat
+++ /dev/null
@@ -1,4 +0,0 @@
-xÚQ
-À0Bÿ=Þÿr]š˜-?]Rl‡ä݃2•¦¹nc
-ð[Ž¹öÝnùAÃ".–j+êi
-~‹x3<úaXÚ{H†ÖC1xÉÀ)â„á¤üSå
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_25_7.dat b/lib/phpqrcode/cache/mask_7/mask_25_7.dat
deleted file mode 100644
index cefe1b972..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_25_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚQAÀ »÷5ôÿŸ[F@©àaƒ„ÄÔÖZ̲…
>;’ÐÀQ±ÊIÖÀQH8Rÿ¼ñÒˆGÉ"èz,ù½&‡ñþ;±Ð'oñ»97”%P8%÷6oǽ;]ÞúNWnÝ[äf7¹ÌÕvÔ
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_29_7.dat b/lib/phpqrcode/cache/mask_7/mask_29_7.dat
deleted file mode 100644
index e3d7391b7..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_29_7.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚÕR9À ÛýšøÿŸ«ŠÈQpX˜$læŲf!I2pgSãªêªMZj·ºóÌÃÂ"útŠðï¡e0¾¿#Ô›`_Ë1-±ÞóŽé´câÝÍ÷òha÷~/¡Eh™4¦Åæ"ä˜~Ï
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_37_7.dat b/lib/phpqrcode/cache/mask_7/mask_37_7.dat
deleted file mode 100644
index 87d9a1a9d..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_37_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_41_7.dat b/lib/phpqrcode/cache/mask_7/mask_41_7.dat
deleted file mode 100644
index 8acec04f0..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_41_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚíTAÀ »÷5ôÿŸ[fDYæ(O’^¬ÅbR3/~t/L"¹Ä7SQQ5…jÔ\S—šiíñÎb£ß#Õ†ÈÂ×+Ç£¤w#æzõx?Þ㽧A-ëšw•u曑Y7$b.%AËÇ;•w«Rµ÷ñï•œoxG}?ƒ
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_45_7.dat b/lib/phpqrcode/cache/mask_7/mask_45_7.dat
deleted file mode 100644
index dbba31d0b..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_45_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_49_7.dat b/lib/phpqrcode/cache/mask_7/mask_49_7.dat
deleted file mode 100644
index be5dce8b7..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_49_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚíVË€0»÷kàÿÎhœC-X.žÆ<ì¨h6Ì‹3À½ð,B
Ô”ó,ç@’Ï€d5$K¸"T|p•%9"¼ypæ,ïâæ¡=<ÆÉm¡•÷˜Ô‰!‹«?¸¦÷DÀW"˜²(®¸Aó-Ö\-
J\©{0p¥lÁWW]ƒÒŒ4ºž?4h=
Z_ƒÖd+ýg(æ*ã*+붵(ÏÇæ
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_53_7.dat b/lib/phpqrcode/cache/mask_7/mask_53_7.dat
deleted file mode 100644
index 7028ef6d7..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_53_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚí–KÀ D÷s¼ÿåš&´Råkºiª&,H)øtD×jÁ=¨µÐÎQa˜ž«P"d¹s1ZyC®|heyüCvéaH°›7ø‰+ùO…Åu¥QÎsZtb…°Íð7µvãúÀŠh™VµÌµ~èùà·1#ÿ~‡[Ëf˜†ùÙæfHkZ¶JtµœŸmZÎÏ6½—ÉsÕúዃw¸rÍ&C×߶f
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_57_7.dat b/lib/phpqrcode/cache/mask_7/mask_57_7.dat
deleted file mode 100644
index ee3107a3c..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_57_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚí—A€0ïûšöÿŸ3&•ÒH)Kb¼Ð&ˆqÅÖžÕ[-ÌÀÞÏÖŒ…Ú9Ér¡Ys×.«ÎiÝÓ¾`´ìòØú~—ëGé{cœiƒÕ‚»\Y<˜.©|·Åì2´ØÛŸÙ2š ŠQQ[[÷^N·ë€88½líÏÃÁ[}[šPl?g+o*Ï–˜4W¶û1 ü Õ33˜Ò[¿\Gosóbkèm”mËômÿÊ^¬¢hë
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_61_7.dat b/lib/phpqrcode/cache/mask_7/mask_61_7.dat
deleted file mode 100644
index 76f8d7271..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_61_7.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-xÚí—K
-À D÷sšäþ—+-µ*5ÿm²¤cŸaT¢1Ø9—YÌ쌧êL9Â糶¬²çísù//i‡‡Ê\„éb®ö©æÂÄ«âÞë-"^²DŒH-iÝ;bnA¢¼™7ófîet¶7Ù·yÌ£E:r”<4ß6ó(üu÷y{K3oæ"óÌý|a½oÌ?ᜟ‡ïç«Ÿ“ò´pù9åýœj~NêÆ›Èìs¹ÑçTYú¡Âu
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_65_7.dat b/lib/phpqrcode/cache/mask_7/mask_65_7.dat
deleted file mode 100644
index d8b920626..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_65_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚí—A€ ïûøÿçŒI‘*í6^L!é…°¶¸i)mTÇT] VW\ï9e@—4Ku^Â#N%:ö,ÖÙmYÈÂJNã„è9¯“Šà¶©ˆvAè2úþÑÏœ”HÉ"YüšÅÜö+?`ýBXDüBX̽{¿‹Á.³Ëw‘ÿ¨d‘,~΂k’,¸^ïbQâ~±.Ãà\¯wó®×ë^«Ï÷îOY˜ÞEôJmXâÑÏ"%
\ No newline at end of file
diff --git a/lib/phpqrcode/cache/mask_7/mask_69_7.dat b/lib/phpqrcode/cache/mask_7/mask_69_7.dat
deleted file mode 100644
index c2db0204a..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_69_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_73_7.dat b/lib/phpqrcode/cache/mask_7/mask_73_7.dat
deleted file mode 100644
index f414e4a58..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_73_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_77_7.dat b/lib/phpqrcode/cache/mask_7/mask_77_7.dat
deleted file mode 100644
index 3e52bfd3f..000000000
Binary files a/lib/phpqrcode/cache/mask_7/mask_77_7.dat and /dev/null differ
diff --git a/lib/phpqrcode/cache/mask_7/mask_81_7.dat b/lib/phpqrcode/cache/mask_7/mask_81_7.dat
deleted file mode 100644
index 78e08dfc6..000000000
--- a/lib/phpqrcode/cache/mask_7/mask_81_7.dat
+++ /dev/null
@@ -1 +0,0 @@
-xÚí™ÁÄ Dïó5ðÿ?×lÒ"ÍŠÝ•¹u4áÀa„>ukv
oÌ40Ý÷ãT±%9¯‘Ô6²ü÷ªU5‹*sI{`¹ªÿ™_²>S?ç}(:yâTïlï{G&E\”Ö6¨õ}"A’¤X‹õXϬ«²³Ç<Âmwx°fÜá‘G”
\ No newline at end of file
diff --git a/lib/phpqrcode/index.php b/lib/phpqrcode/index.php
deleted file mode 100644
index 9e14b7eaa..000000000
--- a/lib/phpqrcode/index.php
+++ /dev/null
@@ -1,94 +0,0 @@
-
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- echo "PHP QR Code
";
-
- //set it to writable location, a place for temp generated PNG files
- $PNG_TEMP_DIR = dirname(__FILE__).DIRECTORY_SEPARATOR.'temp'.DIRECTORY_SEPARATOR;
-
- //html PNG location prefix
- $PNG_WEB_DIR = 'temp/';
-
- include "qrlib.php";
-
- //ofcourse we need rights to create temp dir
- if (!file_exists($PNG_TEMP_DIR))
- mkdir($PNG_TEMP_DIR);
-
-
- $filename = $PNG_TEMP_DIR.'test.png';
-
- //processing form input
- //remember to sanitize user input in real-life solution !!!
- $errorCorrectionLevel = 'L';
- if (isset($_REQUEST['level']) && in_array($_REQUEST['level'], array('L','M','Q','H')))
- $errorCorrectionLevel = $_REQUEST['level'];
-
- $matrixPointSize = 4;
- if (isset($_REQUEST['size']))
- $matrixPointSize = min(max((int)$_REQUEST['size'], 1), 10);
-
-
- if (isset($_REQUEST['data'])) {
-
- //it's very important!
- if (trim($_REQUEST['data']) == '')
- die('data cannot be empty! back');
-
- // user data
- $filename = $PNG_TEMP_DIR.'test'.md5($_REQUEST['data'].'|'.$errorCorrectionLevel.'|'.$matrixPointSize).'.png';
- QRcode::png($_REQUEST['data'], $filename, $errorCorrectionLevel, $matrixPointSize, 2);
-
- } else {
-
- //default data
- echo 'You can provide data in GET parameter: like that
';
- QRcode::png('PHP QR Code :)', $filename, $errorCorrectionLevel, $matrixPointSize, 2);
-
- }
-
- //display generated file
- echo '
';
-
- //config form
- echo '
';
-
- // benchmark
- QRtools::timeBenchmark();
-
-
\ No newline at end of file
diff --git a/lib/phpqrcode/phpqrcode.php b/lib/phpqrcode/phpqrcode.php
deleted file mode 100644
index 02b877639..000000000
--- a/lib/phpqrcode/phpqrcode.php
+++ /dev/null
@@ -1,3312 +0,0 @@
-
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-
-/*
- * Version: 1.1.4
- * Build: 2010100721
- */
-
-
-
-//---- qrconst.php -----------------------------
-
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Common constants
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- // Encoding modes
-
- define('QR_MODE_NUL', -1);
- define('QR_MODE_NUM', 0);
- define('QR_MODE_AN', 1);
- define('QR_MODE_8', 2);
- define('QR_MODE_KANJI', 3);
- define('QR_MODE_STRUCTURE', 4);
-
- // Levels of error correction.
-
- define('QR_ECLEVEL_L', 0);
- define('QR_ECLEVEL_M', 1);
- define('QR_ECLEVEL_Q', 2);
- define('QR_ECLEVEL_H', 3);
-
- // Supported output formats
-
- define('QR_FORMAT_TEXT', 0);
- define('QR_FORMAT_PNG', 1);
-
- class qrstr {
- public static function set(&$srctab, $x, $y, $repl, $replLen = false) {
- $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl));
- }
- }
-
-
-
-//---- merged_config.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Config file, tuned-up for merged verion
- */
-
- define('QR_CACHEABLE', false); // use cache - more disk reads but less CPU power, masks and format templates are stored there
- define('QR_CACHE_DIR', false); // used when QR_CACHEABLE === true
- define('QR_LOG_DIR', false); // default error logs dir
-
- define('QR_FIND_BEST_MASK', true); // if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code
- define('QR_FIND_FROM_RANDOM', 2); // if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly
- define('QR_DEFAULT_MASK', 2); // when QR_FIND_BEST_MASK === false
-
- define('QR_PNG_MAXIMUM_SIZE', 1024); // maximum allowed png image width (in pixels), tune to make sure GD and PHP can handle such big images
-
-
-
-
-//---- qrtools.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Toolset, handy and debug utilites.
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- class QRtools {
-
- //----------------------------------------------------------------------
- public static function binarize($frame)
- {
- $len = count($frame);
- foreach ($frame as &$frameLine) {
-
- for($i=0; $i<$len; $i++) {
- $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0';
- }
- }
-
- return $frame;
- }
-
- //----------------------------------------------------------------------
- public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037')
- {
- $barcode_array = array();
-
- if (!is_array($mode))
- $mode = explode(',', $mode);
-
- $eccLevel = 'L';
-
- if (count($mode) > 1) {
- $eccLevel = $mode[1];
- }
-
- $qrTab = QRcode::text($code, false, $eccLevel);
- $size = count($qrTab);
-
- $barcode_array['num_rows'] = $size;
- $barcode_array['num_cols'] = $size;
- $barcode_array['bcode'] = array();
-
- foreach ($qrTab as $line) {
- $arrAdd = array();
- foreach(str_split($line) as $char)
- $arrAdd[] = ($char=='1')?1:0;
- $barcode_array['bcode'][] = $arrAdd;
- }
-
- return $barcode_array;
- }
-
- //----------------------------------------------------------------------
- public static function clearCache()
- {
- self::$frames = array();
- }
-
- //----------------------------------------------------------------------
- public static function buildCache()
- {
- QRtools::markTime('before_build_cache');
-
- $mask = new QRmask();
- for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) {
- $frame = QRspec::newFrame($a);
- if (QR_IMAGE) {
- $fileName = QR_CACHE_DIR.'frame_'.$a.'.png';
- QRimage::png(self::binarize($frame), $fileName, 1, 0);
- }
-
- $width = count($frame);
- $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
- for ($maskNo=0; $maskNo<8; $maskNo++)
- $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);
- }
-
- QRtools::markTime('after_build_cache');
- }
-
- //----------------------------------------------------------------------
- public static function log($outfile, $err)
- {
- if (QR_LOG_DIR !== false) {
- if ($err != '') {
- if ($outfile !== false) {
- file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
- } else {
- file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
- }
- }
- }
- }
-
- //----------------------------------------------------------------------
- public static function dumpMask($frame)
- {
- $width = count($frame);
- for($y=0;$y<$width;$y++) {
- for($x=0;$x<$width;$x++) {
- echo ord($frame[$y][$x]).',';
- }
- }
- }
-
- //----------------------------------------------------------------------
- public static function markTime($markerId)
- {
- list($usec, $sec) = explode(" ", microtime());
- $time = ((float)$usec + (float)$sec);
-
- if (!isset($GLOBALS['qr_time_bench']))
- $GLOBALS['qr_time_bench'] = array();
-
- $GLOBALS['qr_time_bench'][$markerId] = $time;
- }
-
- //----------------------------------------------------------------------
- public static function timeBenchmark()
- {
- self::markTime('finish');
-
- $lastTime = 0;
- $startTime = 0;
- $p = 0;
-
- echo '
- BENCHMARK |
- ';
-
- foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {
- if ($p > 0) {
- echo 'till '.$markerId.': | '.number_format($thisTime-$lastTime, 6).'s |
';
- } else {
- $startTime = $thisTime;
- }
-
- $p++;
- $lastTime = $thisTime;
- }
-
- echo '
- TOTAL: | '.number_format($lastTime-$startTime, 6).'s |
-
-
';
- }
-
- }
-
- //##########################################################################
-
- QRtools::markTime('start');
-
-
-
-
-//---- qrspec.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * QR Code specifications
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * The following data / specifications are taken from
- * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
- * or
- * "Automatic identification and data capture techniques --
- * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- define('QRSPEC_VERSION_MAX', 40);
- define('QRSPEC_WIDTH_MAX', 177);
-
- define('QRCAP_WIDTH', 0);
- define('QRCAP_WORDS', 1);
- define('QRCAP_REMINDER', 2);
- define('QRCAP_EC', 3);
-
- class QRspec {
-
- public static $capacity = array(
- array( 0, 0, 0, array( 0, 0, 0, 0)),
- array( 21, 26, 0, array( 7, 10, 13, 17)), // 1
- array( 25, 44, 7, array( 10, 16, 22, 28)),
- array( 29, 70, 7, array( 15, 26, 36, 44)),
- array( 33, 100, 7, array( 20, 36, 52, 64)),
- array( 37, 134, 7, array( 26, 48, 72, 88)), // 5
- array( 41, 172, 7, array( 36, 64, 96, 112)),
- array( 45, 196, 0, array( 40, 72, 108, 130)),
- array( 49, 242, 0, array( 48, 88, 132, 156)),
- array( 53, 292, 0, array( 60, 110, 160, 192)),
- array( 57, 346, 0, array( 72, 130, 192, 224)), //10
- array( 61, 404, 0, array( 80, 150, 224, 264)),
- array( 65, 466, 0, array( 96, 176, 260, 308)),
- array( 69, 532, 0, array( 104, 198, 288, 352)),
- array( 73, 581, 3, array( 120, 216, 320, 384)),
- array( 77, 655, 3, array( 132, 240, 360, 432)), //15
- array( 81, 733, 3, array( 144, 280, 408, 480)),
- array( 85, 815, 3, array( 168, 308, 448, 532)),
- array( 89, 901, 3, array( 180, 338, 504, 588)),
- array( 93, 991, 3, array( 196, 364, 546, 650)),
- array( 97, 1085, 3, array( 224, 416, 600, 700)), //20
- array(101, 1156, 4, array( 224, 442, 644, 750)),
- array(105, 1258, 4, array( 252, 476, 690, 816)),
- array(109, 1364, 4, array( 270, 504, 750, 900)),
- array(113, 1474, 4, array( 300, 560, 810, 960)),
- array(117, 1588, 4, array( 312, 588, 870, 1050)), //25
- array(121, 1706, 4, array( 336, 644, 952, 1110)),
- array(125, 1828, 4, array( 360, 700, 1020, 1200)),
- array(129, 1921, 3, array( 390, 728, 1050, 1260)),
- array(133, 2051, 3, array( 420, 784, 1140, 1350)),
- array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30
- array(141, 2323, 3, array( 480, 868, 1290, 1530)),
- array(145, 2465, 3, array( 510, 924, 1350, 1620)),
- array(149, 2611, 3, array( 540, 980, 1440, 1710)),
- array(153, 2761, 3, array( 570, 1036, 1530, 1800)),
- array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35
- array(161, 3034, 0, array( 600, 1120, 1680, 1980)),
- array(165, 3196, 0, array( 630, 1204, 1770, 2100)),
- array(169, 3362, 0, array( 660, 1260, 1860, 2220)),
- array(173, 3532, 0, array( 720, 1316, 1950, 2310)),
- array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40
- );
-
- //----------------------------------------------------------------------
- public static function getDataLength($version, $level)
- {
- return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];
- }
-
- //----------------------------------------------------------------------
- public static function getECCLength($version, $level)
- {
- return self::$capacity[$version][QRCAP_EC][$level];
- }
-
- //----------------------------------------------------------------------
- public static function getWidth($version)
- {
- return self::$capacity[$version][QRCAP_WIDTH];
- }
-
- //----------------------------------------------------------------------
- public static function getRemainder($version)
- {
- return self::$capacity[$version][QRCAP_REMINDER];
- }
-
- //----------------------------------------------------------------------
- public static function getMinimumVersion($size, $level)
- {
-
- for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) {
- $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];
- if($words >= $size)
- return $i;
- }
-
- return -1;
- }
-
- //######################################################################
-
- public static $lengthTableBits = array(
- array(10, 12, 14),
- array( 9, 11, 13),
- array( 8, 16, 16),
- array( 8, 10, 12)
- );
-
- //----------------------------------------------------------------------
- public static function lengthIndicator($mode, $version)
- {
- if ($mode == QR_MODE_STRUCTURE)
- return 0;
-
- if ($version <= 9) {
- $l = 0;
- } else if ($version <= 26) {
- $l = 1;
- } else {
- $l = 2;
- }
-
- return self::$lengthTableBits[$mode][$l];
- }
-
- //----------------------------------------------------------------------
- public static function maximumWords($mode, $version)
- {
- if($mode == QR_MODE_STRUCTURE)
- return 3;
-
- if($version <= 9) {
- $l = 0;
- } else if($version <= 26) {
- $l = 1;
- } else {
- $l = 2;
- }
-
- $bits = self::$lengthTableBits[$mode][$l];
- $words = (1 << $bits) - 1;
-
- if($mode == QR_MODE_KANJI) {
- $words *= 2; // the number of bytes is required
- }
-
- return $words;
- }
-
- // Error correction code -----------------------------------------------
- // Table of the error correction code (Reed-Solomon block)
- // See Table 12-16 (pp.30-36), JIS X0510:2004.
-
- public static $eccTable = array(
- array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)),
- array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1
- array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)),
- array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)),
- array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)),
- array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5
- array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)),
- array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)),
- array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)),
- array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)),
- array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10
- array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)),
- array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)),
- array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)),
- array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)),
- array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15
- array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)),
- array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)),
- array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)),
- array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)),
- array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20
- array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)),
- array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)),
- array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)),
- array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)),
- array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), //25
- array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)),
- array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)),
- array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),
- array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)),
- array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30
- array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)),
- array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)),
- array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)),
- array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)),
- array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35
- array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),
- array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)),
- array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),
- array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)),
- array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40
- );
-
- //----------------------------------------------------------------------
- // CACHEABLE!!!
-
- public static function getEccSpec($version, $level, array &$spec)
- {
- if (count($spec) < 5) {
- $spec = array(0,0,0,0,0);
- }
-
- $b1 = self::$eccTable[$version][$level][0];
- $b2 = self::$eccTable[$version][$level][1];
- $data = self::getDataLength($version, $level);
- $ecc = self::getECCLength($version, $level);
-
- if($b2 == 0) {
- $spec[0] = $b1;
- $spec[1] = (int)($data / $b1);
- $spec[2] = (int)($ecc / $b1);
- $spec[3] = 0;
- $spec[4] = 0;
- } else {
- $spec[0] = $b1;
- $spec[1] = (int)($data / ($b1 + $b2));
- $spec[2] = (int)($ecc / ($b1 + $b2));
- $spec[3] = $b2;
- $spec[4] = $spec[1] + 1;
- }
- }
-
- // Alignment pattern ---------------------------------------------------
-
- // Positions of alignment patterns.
- // This array includes only the second and the third position of the
- // alignment patterns. Rest of them can be calculated from the distance
- // between them.
-
- // See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
-
- public static $alignmentPattern = array(
- array( 0, 0),
- array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5
- array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10
- array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15
- array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20
- array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25
- array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30
- array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35
- array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40
- );
-
-
- /** --------------------------------------------------------------------
- * Put an alignment marker.
- * @param frame
- * @param width
- * @param ox,oy center coordinate of the pattern
- */
- public static function putAlignmentMarker(array &$frame, $ox, $oy)
- {
- $finder = array(
- "\xa1\xa1\xa1\xa1\xa1",
- "\xa1\xa0\xa0\xa0\xa1",
- "\xa1\xa0\xa1\xa0\xa1",
- "\xa1\xa0\xa0\xa0\xa1",
- "\xa1\xa1\xa1\xa1\xa1"
- );
-
- $yStart = $oy-2;
- $xStart = $ox-2;
-
- for($y=0; $y<5; $y++) {
- QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]);
- }
- }
-
- //----------------------------------------------------------------------
- public static function putAlignmentPattern($version, &$frame, $width)
- {
- if($version < 2)
- return;
-
- $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];
- if($d < 0) {
- $w = 2;
- } else {
- $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2);
- }
-
- if($w * $w - 3 == 1) {
- $x = self::$alignmentPattern[$version][0];
- $y = self::$alignmentPattern[$version][0];
- self::putAlignmentMarker($frame, $x, $y);
- return;
- }
-
- $cx = self::$alignmentPattern[$version][0];
- for($x=1; $x<$w - 1; $x++) {
- self::putAlignmentMarker($frame, 6, $cx);
- self::putAlignmentMarker($frame, $cx, 6);
- $cx += $d;
- }
-
- $cy = self::$alignmentPattern[$version][0];
- for($y=0; $y<$w-1; $y++) {
- $cx = self::$alignmentPattern[$version][0];
- for($x=0; $x<$w-1; $x++) {
- self::putAlignmentMarker($frame, $cx, $cy);
- $cx += $d;
- }
- $cy += $d;
- }
- }
-
- // Version information pattern -----------------------------------------
-
- // Version information pattern (BCH coded).
- // See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
-
- // size: [QRSPEC_VERSION_MAX - 6]
-
- public static $versionPattern = array(
- 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
- 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
- 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
- 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
- 0x27541, 0x28c69
- );
-
- //----------------------------------------------------------------------
- public static function getVersionPattern($version)
- {
- if($version < 7 || $version > QRSPEC_VERSION_MAX)
- return 0;
-
- return self::$versionPattern[$version -7];
- }
-
- // Format information --------------------------------------------------
- // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)
-
- public static $formatInfo = array(
- array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),
- array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),
- array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),
- array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)
- );
-
- public static function getFormatInfo($mask, $level)
- {
- if($mask < 0 || $mask > 7)
- return 0;
-
- if($level < 0 || $level > 3)
- return 0;
-
- return self::$formatInfo[$level][$mask];
- }
-
- // Frame ---------------------------------------------------------------
- // Cache of initial frames.
-
- public static $frames = array();
-
- /** --------------------------------------------------------------------
- * Put a finder pattern.
- * @param frame
- * @param width
- * @param ox,oy upper-left coordinate of the pattern
- */
- public static function putFinderPattern(&$frame, $ox, $oy)
- {
- $finder = array(
- "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
- "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
- "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
- "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
- "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
- "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
- "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
- );
-
- for($y=0; $y<7; $y++) {
- QRstr::set($frame, $ox, $oy+$y, $finder[$y]);
- }
- }
-
- //----------------------------------------------------------------------
- public static function createFrame($version)
- {
- $width = self::$capacity[$version][QRCAP_WIDTH];
- $frameLine = str_repeat ("\0", $width);
- $frame = array_fill(0, $width, $frameLine);
-
- // Finder pattern
- self::putFinderPattern($frame, 0, 0);
- self::putFinderPattern($frame, $width - 7, 0);
- self::putFinderPattern($frame, 0, $width - 7);
-
- // Separator
- $yOffset = $width - 7;
-
- for($y=0; $y<7; $y++) {
- $frame[$y][7] = "\xc0";
- $frame[$y][$width - 8] = "\xc0";
- $frame[$yOffset][7] = "\xc0";
- $yOffset++;
- }
-
- $setPattern = str_repeat("\xc0", 8);
-
- QRstr::set($frame, 0, 7, $setPattern);
- QRstr::set($frame, $width-8, 7, $setPattern);
- QRstr::set($frame, 0, $width - 8, $setPattern);
-
- // Format info
- $setPattern = str_repeat("\x84", 9);
- QRstr::set($frame, 0, 8, $setPattern);
- QRstr::set($frame, $width - 8, 8, $setPattern, 8);
-
- $yOffset = $width - 8;
-
- for($y=0; $y<8; $y++,$yOffset++) {
- $frame[$y][8] = "\x84";
- $frame[$yOffset][8] = "\x84";
- }
-
- // Timing pattern
-
- for($i=1; $i<$width-15; $i++) {
- $frame[6][7+$i] = chr(0x90 | ($i & 1));
- $frame[7+$i][6] = chr(0x90 | ($i & 1));
- }
-
- // Alignment pattern
- self::putAlignmentPattern($version, $frame, $width);
-
- // Version information
- if($version >= 7) {
- $vinf = self::getVersionPattern($version);
-
- $v = $vinf;
-
- for($x=0; $x<6; $x++) {
- for($y=0; $y<3; $y++) {
- $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1));
- $v = $v >> 1;
- }
- }
-
- $v = $vinf;
- for($y=0; $y<6; $y++) {
- for($x=0; $x<3; $x++) {
- $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1));
- $v = $v >> 1;
- }
- }
- }
-
- // and a little bit...
- $frame[$width - 8][8] = "\x81";
-
- return $frame;
- }
-
- //----------------------------------------------------------------------
- public static function debug($frame, $binary_mode = false)
- {
- if ($binary_mode) {
-
- foreach ($frame as &$frameLine) {
- $frameLine = join(' ', explode('0', $frameLine));
- $frameLine = join('██', explode('1', $frameLine));
- }
-
- ?>
-
-
';
- echo join("
", $frame);
- echo '
';
-
- } else {
-
- foreach ($frame as &$frameLine) {
- $frameLine = join(' ', explode("\xc0", $frameLine));
- $frameLine = join('▒', explode("\xc1", $frameLine));
- $frameLine = join(' ', explode("\xa0", $frameLine));
- $frameLine = join('▒', explode("\xa1", $frameLine));
- $frameLine = join('◇', explode("\x84", $frameLine)); //format 0
- $frameLine = join('◆', explode("\x85", $frameLine)); //format 1
- $frameLine = join('☢', explode("\x81", $frameLine)); //special bit
- $frameLine = join(' ', explode("\x90", $frameLine)); //clock 0
- $frameLine = join('◷', explode("\x91", $frameLine)); //clock 1
- $frameLine = join(' ', explode("\x88", $frameLine)); //version
- $frameLine = join('▒', explode("\x89", $frameLine)); //version
- $frameLine = join('♦', explode("\x01", $frameLine));
- $frameLine = join('⋅', explode("\0", $frameLine));
- }
-
- ?>
-
- ";
- echo join("
", $frame);
- echo "";
-
- }
- }
-
- //----------------------------------------------------------------------
- public static function serial($frame)
- {
- return gzcompress(join("\n", $frame), 9);
- }
-
- //----------------------------------------------------------------------
- public static function unserial($code)
- {
- return explode("\n", gzuncompress($code));
- }
-
- //----------------------------------------------------------------------
- public static function newFrame($version)
- {
- if($version < 1 || $version > QRSPEC_VERSION_MAX)
- return null;
-
- if(!isset(self::$frames[$version])) {
-
- $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat';
-
- if (QR_CACHEABLE) {
- if (file_exists($fileName)) {
- self::$frames[$version] = self::unserial(file_get_contents($fileName));
- } else {
- self::$frames[$version] = self::createFrame($version);
- file_put_contents($fileName, self::serial(self::$frames[$version]));
- }
- } else {
- self::$frames[$version] = self::createFrame($version);
- }
- }
-
- if(is_null(self::$frames[$version]))
- return null;
-
- return self::$frames[$version];
- }
-
- //----------------------------------------------------------------------
- public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; }
- public static function rsBlockNum1($spec) { return $spec[0]; }
- public static function rsDataCodes1($spec) { return $spec[1]; }
- public static function rsEccCodes1($spec) { return $spec[2]; }
- public static function rsBlockNum2($spec) { return $spec[3]; }
- public static function rsDataCodes2($spec) { return $spec[4]; }
- public static function rsEccCodes2($spec) { return $spec[2]; }
- public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); }
- public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; }
-
- }
-
-
-
-//---- qrimage.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Image output of code using GD2
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- define('QR_IMAGE', true);
-
- class QRimage {
-
- //----------------------------------------------------------------------
- public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE)
- {
- $image = self::image($frame, $pixelPerPoint, $outerFrame);
-
- if ($filename === false) {
- Header("Content-type: image/png");
- ImagePng($image);
- } else {
- if($saveandprint===TRUE){
- ImagePng($image, $filename);
- header("Content-type: image/png");
- ImagePng($image);
- }else{
- ImagePng($image, $filename);
- }
- }
-
- ImageDestroy($image);
- }
-
- //----------------------------------------------------------------------
- public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85)
- {
- $image = self::image($frame, $pixelPerPoint, $outerFrame);
-
- if ($filename === false) {
- Header("Content-type: image/jpeg");
- ImageJpeg($image, null, $q);
- } else {
- ImageJpeg($image, $filename, $q);
- }
-
- ImageDestroy($image);
- }
-
- //----------------------------------------------------------------------
- private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4)
- {
- $h = count($frame);
- $w = strlen($frame[0]);
-
- $imgW = $w + 2*$outerFrame;
- $imgH = $h + 2*$outerFrame;
-
- $base_image =ImageCreate($imgW, $imgH);
-
- $col[0] = ImageColorAllocate($base_image,255,255,255);
- $col[1] = ImageColorAllocate($base_image,0,0,0);
-
- imagefill($base_image, 0, 0, $col[0]);
-
- for($y=0; $y<$h; $y++) {
- for($x=0; $x<$w; $x++) {
- if ($frame[$y][$x] == '1') {
- ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]);
- }
- }
- }
-
- $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
- ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
- ImageDestroy($base_image);
-
- return $target_image;
- }
- }
-
-
-
-//---- qrinput.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Input encoding class
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- define('STRUCTURE_HEADER_BITS', 20);
- define('MAX_STRUCTURED_SYMBOLS', 16);
-
- class QRinputItem {
-
- public $mode;
- public $size;
- public $data;
- public $bstream;
-
- public function __construct($mode, $size, $data, $bstream = null)
- {
- $setData = array_slice($data, 0, $size);
-
- if (count($setData) < $size) {
- $setData = array_merge($setData, array_fill(0,$size-count($setData),0));
- }
-
- if(!QRinput::check($mode, $size, $setData)) {
- throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData));
- return null;
- }
-
- $this->mode = $mode;
- $this->size = $size;
- $this->data = $setData;
- $this->bstream = $bstream;
- }
-
- //----------------------------------------------------------------------
- public function encodeModeNum($version)
- {
- try {
-
- $words = (int)($this->size / 3);
- $bs = new QRbitstream();
-
- $val = 0x1;
- $bs->appendNum(4, $val);
- $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size);
-
- for($i=0; $i<$words; $i++) {
- $val = (ord($this->data[$i*3 ]) - ord('0')) * 100;
- $val += (ord($this->data[$i*3+1]) - ord('0')) * 10;
- $val += (ord($this->data[$i*3+2]) - ord('0'));
- $bs->appendNum(10, $val);
- }
-
- if($this->size - $words * 3 == 1) {
- $val = ord($this->data[$words*3]) - ord('0');
- $bs->appendNum(4, $val);
- } else if($this->size - $words * 3 == 2) {
- $val = (ord($this->data[$words*3 ]) - ord('0')) * 10;
- $val += (ord($this->data[$words*3+1]) - ord('0'));
- $bs->appendNum(7, $val);
- }
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function encodeModeAn($version)
- {
- try {
- $words = (int)($this->size / 2);
- $bs = new QRbitstream();
-
- $bs->appendNum(4, 0x02);
- $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size);
-
- for($i=0; $i<$words; $i++) {
- $val = (int)QRinput::lookAnTable(ord($this->data[$i*2 ])) * 45;
- $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1]));
-
- $bs->appendNum(11, $val);
- }
-
- if($this->size & 1) {
- $val = QRinput::lookAnTable(ord($this->data[$words * 2]));
- $bs->appendNum(6, $val);
- }
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function encodeMode8($version)
- {
- try {
- $bs = new QRbitstream();
-
- $bs->appendNum(4, 0x4);
- $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size);
-
- for($i=0; $i<$this->size; $i++) {
- $bs->appendNum(8, ord($this->data[$i]));
- }
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function encodeModeKanji($version)
- {
- try {
-
- $bs = new QRbitrtream();
-
- $bs->appendNum(4, 0x8);
- $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2));
-
- for($i=0; $i<$this->size; $i+=2) {
- $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]);
- if($val <= 0x9ffc) {
- $val -= 0x8140;
- } else {
- $val -= 0xc140;
- }
-
- $h = ($val >> 8) * 0xc0;
- $val = ($val & 0xff) + $h;
-
- $bs->appendNum(13, $val);
- }
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function encodeModeStructure()
- {
- try {
- $bs = new QRbitstream();
-
- $bs->appendNum(4, 0x03);
- $bs->appendNum(4, ord($this->data[1]) - 1);
- $bs->appendNum(4, ord($this->data[0]) - 1);
- $bs->appendNum(8, ord($this->data[2]));
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function estimateBitStreamSizeOfEntry($version)
- {
- $bits = 0;
-
- if($version == 0)
- $version = 1;
-
- switch($this->mode) {
- case QR_MODE_NUM: $bits = QRinput::estimateBitsModeNum($this->size); break;
- case QR_MODE_AN: $bits = QRinput::estimateBitsModeAn($this->size); break;
- case QR_MODE_8: $bits = QRinput::estimateBitsMode8($this->size); break;
- case QR_MODE_KANJI: $bits = QRinput::estimateBitsModeKanji($this->size);break;
- case QR_MODE_STRUCTURE: return STRUCTURE_HEADER_BITS;
- default:
- return 0;
- }
-
- $l = QRspec::lengthIndicator($this->mode, $version);
- $m = 1 << $l;
- $num = (int)(($this->size + $m - 1) / $m);
-
- $bits += $num * (4 + $l);
-
- return $bits;
- }
-
- //----------------------------------------------------------------------
- public function encodeBitStream($version)
- {
- try {
-
- unset($this->bstream);
- $words = QRspec::maximumWords($this->mode, $version);
-
- if($this->size > $words) {
-
- $st1 = new QRinputItem($this->mode, $words, $this->data);
- $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words));
-
- $st1->encodeBitStream($version);
- $st2->encodeBitStream($version);
-
- $this->bstream = new QRbitstream();
- $this->bstream->append($st1->bstream);
- $this->bstream->append($st2->bstream);
-
- unset($st1);
- unset($st2);
-
- } else {
-
- $ret = 0;
-
- switch($this->mode) {
- case QR_MODE_NUM: $ret = $this->encodeModeNum($version); break;
- case QR_MODE_AN: $ret = $this->encodeModeAn($version); break;
- case QR_MODE_8: $ret = $this->encodeMode8($version); break;
- case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break;
- case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure(); break;
-
- default:
- break;
- }
-
- if($ret < 0)
- return -1;
- }
-
- return $this->bstream->size();
-
- } catch (Exception $e) {
- return -1;
- }
- }
- };
-
- //##########################################################################
-
- class QRinput {
-
- public $items;
-
- private $version;
- private $level;
-
- //----------------------------------------------------------------------
- public function __construct($version = 0, $level = QR_ECLEVEL_L)
- {
- if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) {
- throw new Exception('Invalid version no');
- return NULL;
- }
-
- $this->version = $version;
- $this->level = $level;
- }
-
- //----------------------------------------------------------------------
- public function getVersion()
- {
- return $this->version;
- }
-
- //----------------------------------------------------------------------
- public function setVersion($version)
- {
- if($version < 0 || $version > QRSPEC_VERSION_MAX) {
- throw new Exception('Invalid version no');
- return -1;
- }
-
- $this->version = $version;
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function getErrorCorrectionLevel()
- {
- return $this->level;
- }
-
- //----------------------------------------------------------------------
- public function setErrorCorrectionLevel($level)
- {
- if($level > QR_ECLEVEL_H) {
- throw new Exception('Invalid ECLEVEL');
- return -1;
- }
-
- $this->level = $level;
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function appendEntry(QRinputItem $entry)
- {
- $this->items[] = $entry;
- }
-
- //----------------------------------------------------------------------
- public function append($mode, $size, $data)
- {
- try {
- $entry = new QRinputItem($mode, $size, $data);
- $this->items[] = $entry;
- return 0;
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
-
- public function insertStructuredAppendHeader($size, $index, $parity)
- {
- if( $size > MAX_STRUCTURED_SYMBOLS ) {
- throw new Exception('insertStructuredAppendHeader wrong size');
- }
-
- if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) {
- throw new Exception('insertStructuredAppendHeader wrong index');
- }
-
- $buf = array($size, $index, $parity);
-
- try {
- $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf);
- array_unshift($this->items, $entry);
- return 0;
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function calcParity()
- {
- $parity = 0;
-
- foreach($this->items as $item) {
- if($item->mode != QR_MODE_STRUCTURE) {
- for($i=$item->size-1; $i>=0; $i--) {
- $parity ^= $item->data[$i];
- }
- }
- }
-
- return $parity;
- }
-
- //----------------------------------------------------------------------
- public static function checkModeNum($size, $data)
- {
- for($i=0; $i<$size; $i++) {
- if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){
- return false;
- }
- }
-
- return true;
- }
-
- //----------------------------------------------------------------------
- public static function estimateBitsModeNum($size)
- {
- $w = (int)$size / 3;
- $bits = $w * 10;
-
- switch($size - $w * 3) {
- case 1:
- $bits += 4;
- break;
- case 2:
- $bits += 7;
- break;
- default:
- break;
- }
-
- return $bits;
- }
-
- //----------------------------------------------------------------------
- public static $anTable = array(
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
- );
-
- //----------------------------------------------------------------------
- public static function lookAnTable($c)
- {
- return (($c > 127)?-1:self::$anTable[$c]);
- }
-
- //----------------------------------------------------------------------
- public static function checkModeAn($size, $data)
- {
- for($i=0; $i<$size; $i++) {
- if (self::lookAnTable(ord($data[$i])) == -1) {
- return false;
- }
- }
-
- return true;
- }
-
- //----------------------------------------------------------------------
- public static function estimateBitsModeAn($size)
- {
- $w = (int)($size / 2);
- $bits = $w * 11;
-
- if($size & 1) {
- $bits += 6;
- }
-
- return $bits;
- }
-
- //----------------------------------------------------------------------
- public static function estimateBitsMode8($size)
- {
- return $size * 8;
- }
-
- //----------------------------------------------------------------------
- public function estimateBitsModeKanji($size)
- {
- return (int)(($size / 2) * 13);
- }
-
- //----------------------------------------------------------------------
- public static function checkModeKanji($size, $data)
- {
- if($size & 1)
- return false;
-
- for($i=0; $i<$size; $i+=2) {
- $val = (ord($data[$i]) << 8) | ord($data[$i+1]);
- if( $val < 0x8140
- || ($val > 0x9ffc && $val < 0xe040)
- || $val > 0xebbf) {
- return false;
- }
- }
-
- return true;
- }
-
- /***********************************************************************
- * Validation
- **********************************************************************/
-
- public static function check($mode, $size, $data)
- {
- if($size <= 0)
- return false;
-
- switch($mode) {
- case QR_MODE_NUM: return self::checkModeNum($size, $data); break;
- case QR_MODE_AN: return self::checkModeAn($size, $data); break;
- case QR_MODE_KANJI: return self::checkModeKanji($size, $data); break;
- case QR_MODE_8: return true; break;
- case QR_MODE_STRUCTURE: return true; break;
-
- default:
- break;
- }
-
- return false;
- }
-
-
- //----------------------------------------------------------------------
- public function estimateBitStreamSize($version)
- {
- $bits = 0;
-
- foreach($this->items as $item) {
- $bits += $item->estimateBitStreamSizeOfEntry($version);
- }
-
- return $bits;
- }
-
- //----------------------------------------------------------------------
- public function estimateVersion()
- {
- $version = 0;
- $prev = 0;
- do {
- $prev = $version;
- $bits = $this->estimateBitStreamSize($prev);
- $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
- if ($version < 0) {
- return -1;
- }
- } while ($version > $prev);
-
- return $version;
- }
-
- //----------------------------------------------------------------------
- public static function lengthOfCode($mode, $version, $bits)
- {
- $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);
- switch($mode) {
- case QR_MODE_NUM:
- $chunks = (int)($payload / 10);
- $remain = $payload - $chunks * 10;
- $size = $chunks * 3;
- if($remain >= 7) {
- $size += 2;
- } else if($remain >= 4) {
- $size += 1;
- }
- break;
- case QR_MODE_AN:
- $chunks = (int)($payload / 11);
- $remain = $payload - $chunks * 11;
- $size = $chunks * 2;
- if($remain >= 6)
- $size++;
- break;
- case QR_MODE_8:
- $size = (int)($payload / 8);
- break;
- case QR_MODE_KANJI:
- $size = (int)(($payload / 13) * 2);
- break;
- case QR_MODE_STRUCTURE:
- $size = (int)($payload / 8);
- break;
- default:
- $size = 0;
- break;
- }
-
- $maxsize = QRspec::maximumWords($mode, $version);
- if($size < 0) $size = 0;
- if($size > $maxsize) $size = $maxsize;
-
- return $size;
- }
-
- //----------------------------------------------------------------------
- public function createBitStream()
- {
- $total = 0;
-
- foreach($this->items as $item) {
- $bits = $item->encodeBitStream($this->version);
-
- if($bits < 0)
- return -1;
-
- $total += $bits;
- }
-
- return $total;
- }
-
- //----------------------------------------------------------------------
- public function convertData()
- {
- $ver = $this->estimateVersion();
- if($ver > $this->getVersion()) {
- $this->setVersion($ver);
- }
-
- for(;;) {
- $bits = $this->createBitStream();
-
- if($bits < 0)
- return -1;
-
- $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
- if($ver < 0) {
- throw new Exception('WRONG VERSION');
- return -1;
- } else if($ver > $this->getVersion()) {
- $this->setVersion($ver);
- } else {
- break;
- }
- }
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function appendPaddingBit(&$bstream)
- {
- $bits = $bstream->size();
- $maxwords = QRspec::getDataLength($this->version, $this->level);
- $maxbits = $maxwords * 8;
-
- if ($maxbits == $bits) {
- return 0;
- }
-
- if ($maxbits - $bits < 5) {
- return $bstream->appendNum($maxbits - $bits, 0);
- }
-
- $bits += 4;
- $words = (int)(($bits + 7) / 8);
-
- $padding = new QRbitstream();
- $ret = $padding->appendNum($words * 8 - $bits + 4, 0);
-
- if($ret < 0)
- return $ret;
-
- $padlen = $maxwords - $words;
-
- if($padlen > 0) {
-
- $padbuf = array();
- for($i=0; $i<$padlen; $i++) {
- $padbuf[$i] = ($i&1)?0x11:0xec;
- }
-
- $ret = $padding->appendBytes($padlen, $padbuf);
-
- if($ret < 0)
- return $ret;
-
- }
-
- $ret = $bstream->append($padding);
-
- return $ret;
- }
-
- //----------------------------------------------------------------------
- public function mergeBitStream()
- {
- if($this->convertData() < 0) {
- return null;
- }
-
- $bstream = new QRbitstream();
-
- foreach($this->items as $item) {
- $ret = $bstream->append($item->bstream);
- if($ret < 0) {
- return null;
- }
- }
-
- return $bstream;
- }
-
- //----------------------------------------------------------------------
- public function getBitStream()
- {
-
- $bstream = $this->mergeBitStream();
-
- if($bstream == null) {
- return null;
- }
-
- $ret = $this->appendPaddingBit($bstream);
- if($ret < 0) {
- return null;
- }
-
- return $bstream;
- }
-
- //----------------------------------------------------------------------
- public function getByteStream()
- {
- $bstream = $this->getBitStream();
- if($bstream == null) {
- return null;
- }
-
- return $bstream->toByte();
- }
- }
-
-
-
-
-
-
-//---- qrbitstream.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Bitstream class
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- class QRbitstream {
-
- public $data = array();
-
- //----------------------------------------------------------------------
- public function size()
- {
- return count($this->data);
- }
-
- //----------------------------------------------------------------------
- public function allocate($setLength)
- {
- $this->data = array_fill(0, $setLength, 0);
- return 0;
- }
-
- //----------------------------------------------------------------------
- public static function newFromNum($bits, $num)
- {
- $bstream = new QRbitstream();
- $bstream->allocate($bits);
-
- $mask = 1 << ($bits - 1);
- for($i=0; $i<$bits; $i++) {
- if($num & $mask) {
- $bstream->data[$i] = 1;
- } else {
- $bstream->data[$i] = 0;
- }
- $mask = $mask >> 1;
- }
-
- return $bstream;
- }
-
- //----------------------------------------------------------------------
- public static function newFromBytes($size, $data)
- {
- $bstream = new QRbitstream();
- $bstream->allocate($size * 8);
- $p=0;
-
- for($i=0; $i<$size; $i++) {
- $mask = 0x80;
- for($j=0; $j<8; $j++) {
- if($data[$i] & $mask) {
- $bstream->data[$p] = 1;
- } else {
- $bstream->data[$p] = 0;
- }
- $p++;
- $mask = $mask >> 1;
- }
- }
-
- return $bstream;
- }
-
- //----------------------------------------------------------------------
- public function append(QRbitstream $arg)
- {
- if (is_null($arg)) {
- return -1;
- }
-
- if($arg->size() == 0) {
- return 0;
- }
-
- if($this->size() == 0) {
- $this->data = $arg->data;
- return 0;
- }
-
- $this->data = array_values(array_merge($this->data, $arg->data));
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function appendNum($bits, $num)
- {
- if ($bits == 0)
- return 0;
-
- $b = QRbitstream::newFromNum($bits, $num);
-
- if(is_null($b))
- return -1;
-
- $ret = $this->append($b);
- unset($b);
-
- return $ret;
- }
-
- //----------------------------------------------------------------------
- public function appendBytes($size, $data)
- {
- if ($size == 0)
- return 0;
-
- $b = QRbitstream::newFromBytes($size, $data);
-
- if(is_null($b))
- return -1;
-
- $ret = $this->append($b);
- unset($b);
-
- return $ret;
- }
-
- //----------------------------------------------------------------------
- public function toByte()
- {
-
- $size = $this->size();
-
- if($size == 0) {
- return array();
- }
-
- $data = array_fill(0, (int)(($size + 7) / 8), 0);
- $bytes = (int)($size / 8);
-
- $p = 0;
-
- for($i=0; $i<$bytes; $i++) {
- $v = 0;
- for($j=0; $j<8; $j++) {
- $v = $v << 1;
- $v |= $this->data[$p];
- $p++;
- }
- $data[$i] = $v;
- }
-
- if($size & 7) {
- $v = 0;
- for($j=0; $j<($size & 7); $j++) {
- $v = $v << 1;
- $v |= $this->data[$p];
- $p++;
- }
- $data[$bytes] = $v;
- }
-
- return $data;
- }
-
- }
-
-
-
-
-//---- qrsplit.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Input splitting classes
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * The following data / specifications are taken from
- * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
- * or
- * "Automatic identification and data capture techniques --
- * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- class QRsplit {
-
- public $dataStr = '';
- public $input;
- public $modeHint;
-
- //----------------------------------------------------------------------
- public function __construct($dataStr, $input, $modeHint)
- {
- $this->dataStr = $dataStr;
- $this->input = $input;
- $this->modeHint = $modeHint;
- }
-
- //----------------------------------------------------------------------
- public static function isdigitat($str, $pos)
- {
- if ($pos >= strlen($str))
- return false;
-
- return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9')));
- }
-
- //----------------------------------------------------------------------
- public static function isalnumat($str, $pos)
- {
- if ($pos >= strlen($str))
- return false;
-
- return (QRinput::lookAnTable(ord($str[$pos])) >= 0);
- }
-
- //----------------------------------------------------------------------
- public function identifyMode($pos)
- {
- if ($pos >= strlen($this->dataStr))
- return QR_MODE_NUL;
-
- $c = $this->dataStr[$pos];
-
- if(self::isdigitat($this->dataStr, $pos)) {
- return QR_MODE_NUM;
- } else if(self::isalnumat($this->dataStr, $pos)) {
- return QR_MODE_AN;
- } else if($this->modeHint == QR_MODE_KANJI) {
-
- if ($pos+1 < strlen($this->dataStr))
- {
- $d = $this->dataStr[$pos+1];
- $word = (ord($c) << 8) | ord($d);
- if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {
- return QR_MODE_KANJI;
- }
- }
- }
-
- return QR_MODE_8;
- }
-
- //----------------------------------------------------------------------
- public function eatNum()
- {
- $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
- $p = 0;
- while(self::isdigitat($this->dataStr, $p)) {
- $p++;
- }
-
- $run = $p;
- $mode = $this->identifyMode($p);
-
- if($mode == QR_MODE_8) {
- $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
- + QRinput::estimateBitsMode8(1) // + 4 + l8
- - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
- if($dif > 0) {
- return $this->eat8();
- }
- }
- if($mode == QR_MODE_AN) {
- $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
- + QRinput::estimateBitsModeAn(1) // + 4 + la
- - QRinput::estimateBitsModeAn($run + 1);// - 4 - la
- if($dif > 0) {
- return $this->eatAn();
- }
- }
-
- $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));
- if($ret < 0)
- return -1;
-
- return $run;
- }
-
- //----------------------------------------------------------------------
- public function eatAn()
- {
- $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
- $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
- $p = 0;
-
- while(self::isalnumat($this->dataStr, $p)) {
- if(self::isdigitat($this->dataStr, $p)) {
- $q = $p;
- while(self::isdigitat($this->dataStr, $q)) {
- $q++;
- }
-
- $dif = QRinput::estimateBitsModeAn($p) // + 4 + la
- + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
- - QRinput::estimateBitsModeAn($q); // - 4 - la
-
- if($dif < 0) {
- break;
- } else {
- $p = $q;
- }
- } else {
- $p++;
- }
- }
-
- $run = $p;
-
- if(!self::isalnumat($this->dataStr, $p)) {
- $dif = QRinput::estimateBitsModeAn($run) + 4 + $la
- + QRinput::estimateBitsMode8(1) // + 4 + l8
- - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
- if($dif > 0) {
- return $this->eat8();
- }
- }
-
- $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));
- if($ret < 0)
- return -1;
-
- return $run;
- }
-
- //----------------------------------------------------------------------
- public function eatKanji()
- {
- $p = 0;
-
- while($this->identifyMode($p) == QR_MODE_KANJI) {
- $p += 2;
- }
-
- $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));
- if($ret < 0)
- return -1;
-
- return $run;
- }
-
- //----------------------------------------------------------------------
- public function eat8()
- {
- $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
- $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
- $p = 1;
- $dataStrLen = strlen($this->dataStr);
-
- while($p < $dataStrLen) {
-
- $mode = $this->identifyMode($p);
- if($mode == QR_MODE_KANJI) {
- break;
- }
- if($mode == QR_MODE_NUM) {
- $q = $p;
- while(self::isdigitat($this->dataStr, $q)) {
- $q++;
- }
- $dif = QRinput::estimateBitsMode8($p) // + 4 + l8
- + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
- - QRinput::estimateBitsMode8($q); // - 4 - l8
- if($dif < 0) {
- break;
- } else {
- $p = $q;
- }
- } else if($mode == QR_MODE_AN) {
- $q = $p;
- while(self::isalnumat($this->dataStr, $q)) {
- $q++;
- }
- $dif = QRinput::estimateBitsMode8($p) // + 4 + l8
- + QRinput::estimateBitsModeAn($q - $p) + 4 + $la
- - QRinput::estimateBitsMode8($q); // - 4 - l8
- if($dif < 0) {
- break;
- } else {
- $p = $q;
- }
- } else {
- $p++;
- }
- }
-
- $run = $p;
- $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));
-
- if($ret < 0)
- return -1;
-
- return $run;
- }
-
- //----------------------------------------------------------------------
- public function splitString()
- {
- while (strlen($this->dataStr) > 0)
- {
- if($this->dataStr == '')
- return 0;
-
- $mode = $this->identifyMode(0);
-
- switch ($mode) {
- case QR_MODE_NUM: $length = $this->eatNum(); break;
- case QR_MODE_AN: $length = $this->eatAn(); break;
- case QR_MODE_KANJI:
- if ($this->modeHint == QR_MODE_KANJI)
- $length = $this->eatKanji();
- else $length = $this->eat8();
- break;
- default: $length = $this->eat8(); break;
-
- }
-
- if($length == 0) return 0;
- if($length < 0) return -1;
-
- $this->dataStr = substr($this->dataStr, $length);
- }
- }
-
- //----------------------------------------------------------------------
- public function toUpper()
- {
- $stringLen = strlen($this->dataStr);
- $p = 0;
-
- while ($p<$stringLen) {
- $mode = self::identifyMode(substr($this->dataStr, $p));
- if($mode == QR_MODE_KANJI) {
- $p += 2;
- } else {
- if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) {
- $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
- }
- $p++;
- }
- }
-
- return $this->dataStr;
- }
-
- //----------------------------------------------------------------------
- public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)
- {
- if(is_null($string) || $string == '\0' || $string == '') {
- throw new Exception('empty string!!!');
- }
-
- $split = new QRsplit($string, $input, $modeHint);
-
- if(!$casesensitive)
- $split->toUpper();
-
- return $split->splitString();
- }
- }
-
-
-
-//---- qrrscode.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Reed-Solomon error correction support
- *
- * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
- * (libfec is released under the GNU Lesser General Public License.)
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- class QRrsItem {
-
- public $mm; // Bits per symbol
- public $nn; // Symbols per block (= (1<= $this->nn) {
- $x -= $this->nn;
- $x = ($x >> $this->mm) + ($x & $this->nn);
- }
-
- return $x;
- }
-
- //----------------------------------------------------------------------
- public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
- {
- // Common code for intializing a Reed-Solomon control block (char or int symbols)
- // Copyright 2004 Phil Karn, KA9Q
- // May be used under the terms of the GNU Lesser General Public License (LGPL)
-
- $rs = null;
-
- // Check parameter ranges
- if($symsize < 0 || $symsize > 8) return $rs;
- if($fcr < 0 || $fcr >= (1<<$symsize)) return $rs;
- if($prim <= 0 || $prim >= (1<<$symsize)) return $rs;
- if($nroots < 0 || $nroots >= (1<<$symsize)) return $rs; // Can't have more roots than symbol values!
- if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding
-
- $rs = new QRrsItem();
- $rs->mm = $symsize;
- $rs->nn = (1<<$symsize)-1;
- $rs->pad = $pad;
-
- $rs->alpha_to = array_fill(0, $rs->nn+1, 0);
- $rs->index_of = array_fill(0, $rs->nn+1, 0);
-
- // PHP style macro replacement ;)
- $NN =& $rs->nn;
- $A0 =& $NN;
-
- // Generate Galois field lookup tables
- $rs->index_of[0] = $A0; // log(zero) = -inf
- $rs->alpha_to[$A0] = 0; // alpha**-inf = 0
- $sr = 1;
-
- for($i=0; $i<$rs->nn; $i++) {
- $rs->index_of[$sr] = $i;
- $rs->alpha_to[$i] = $sr;
- $sr <<= 1;
- if($sr & (1<<$symsize)) {
- $sr ^= $gfpoly;
- }
- $sr &= $rs->nn;
- }
-
- if($sr != 1){
- // field generator polynomial is not primitive!
- $rs = NULL;
- return $rs;
- }
-
- /* Form RS code generator polynomial from its roots */
- $rs->genpoly = array_fill(0, $nroots+1, 0);
-
- $rs->fcr = $fcr;
- $rs->prim = $prim;
- $rs->nroots = $nroots;
- $rs->gfpoly = $gfpoly;
-
- /* Find prim-th root of 1, used in decoding */
- for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn)
- ; // intentional empty-body loop!
-
- $rs->iprim = (int)($iprim / $prim);
- $rs->genpoly[0] = 1;
-
- for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) {
- $rs->genpoly[$i+1] = 1;
-
- // Multiply rs->genpoly[] by @**(root + x)
- for ($j = $i; $j > 0; $j--) {
- if ($rs->genpoly[$j] != 0) {
- $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)];
- } else {
- $rs->genpoly[$j] = $rs->genpoly[$j-1];
- }
- }
- // rs->genpoly[0] can never be zero
- $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)];
- }
-
- // convert rs->genpoly[] to index form for quicker encoding
- for ($i = 0; $i <= $nroots; $i++)
- $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]];
-
- return $rs;
- }
-
- //----------------------------------------------------------------------
- public function encode_rs_char($data, &$parity)
- {
- $MM =& $this->mm;
- $NN =& $this->nn;
- $ALPHA_TO =& $this->alpha_to;
- $INDEX_OF =& $this->index_of;
- $GENPOLY =& $this->genpoly;
- $NROOTS =& $this->nroots;
- $FCR =& $this->fcr;
- $PRIM =& $this->prim;
- $IPRIM =& $this->iprim;
- $PAD =& $this->pad;
- $A0 =& $NN;
-
- $parity = array_fill(0, $NROOTS, 0);
-
- for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) {
-
- $feedback = $INDEX_OF[$data[$i] ^ $parity[0]];
- if($feedback != $A0) {
- // feedback term is non-zero
-
- // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
- // always be for the polynomials constructed by init_rs()
- $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback);
-
- for($j=1;$j<$NROOTS;$j++) {
- $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])];
- }
- }
-
- // Shift
- array_shift($parity);
- if($feedback != $A0) {
- array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]);
- } else {
- array_push($parity, 0);
- }
- }
- }
- }
-
- //##########################################################################
-
- class QRrs {
-
- public static $items = array();
-
- //----------------------------------------------------------------------
- public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
- {
- foreach(self::$items as $rs) {
- if($rs->pad != $pad) continue;
- if($rs->nroots != $nroots) continue;
- if($rs->mm != $symsize) continue;
- if($rs->gfpoly != $gfpoly) continue;
- if($rs->fcr != $fcr) continue;
- if($rs->prim != $prim) continue;
-
- return $rs;
- }
-
- $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
- array_unshift(self::$items, $rs);
-
- return $rs;
- }
- }
-
-
-
-//---- qrmask.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Masking
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- define('N1', 3);
- define('N2', 3);
- define('N3', 40);
- define('N4', 10);
-
- class QRmask {
-
- public $runLength = array();
-
- //----------------------------------------------------------------------
- public function __construct()
- {
- $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);
- }
-
- //----------------------------------------------------------------------
- public function writeFormatInformation($width, &$frame, $mask, $level)
- {
- $blacks = 0;
- $format = QRspec::getFormatInfo($mask, $level);
-
- for($i=0; $i<8; $i++) {
- if($format & 1) {
- $blacks += 2;
- $v = 0x85;
- } else {
- $v = 0x84;
- }
-
- $frame[8][$width - 1 - $i] = chr($v);
- if($i < 6) {
- $frame[$i][8] = chr($v);
- } else {
- $frame[$i + 1][8] = chr($v);
- }
- $format = $format >> 1;
- }
-
- for($i=0; $i<7; $i++) {
- if($format & 1) {
- $blacks += 2;
- $v = 0x85;
- } else {
- $v = 0x84;
- }
-
- $frame[$width - 7 + $i][8] = chr($v);
- if($i == 0) {
- $frame[8][7] = chr($v);
- } else {
- $frame[8][6 - $i] = chr($v);
- }
-
- $format = $format >> 1;
- }
-
- return $blacks;
- }
-
- //----------------------------------------------------------------------
- public function mask0($x, $y) { return ($x+$y)&1; }
- public function mask1($x, $y) { return ($y&1); }
- public function mask2($x, $y) { return ($x%3); }
- public function mask3($x, $y) { return ($x+$y)%3; }
- public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; }
- public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3; }
- public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1; }
- public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1; }
-
- //----------------------------------------------------------------------
- private function generateMaskNo($maskNo, $width, $frame)
- {
- $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
-
- for($y=0; $y<$width; $y++) {
- for($x=0; $x<$width; $x++) {
- if(ord($frame[$y][$x]) & 0x80) {
- $bitMask[$y][$x] = 0;
- } else {
- $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y);
- $bitMask[$y][$x] = ($maskFunc == 0)?1:0;
- }
-
- }
- }
-
- return $bitMask;
- }
-
- //----------------------------------------------------------------------
- public static function serial($bitFrame)
- {
- $codeArr = array();
-
- foreach ($bitFrame as $line)
- $codeArr[] = join('', $line);
-
- return gzcompress(join("\n", $codeArr), 9);
- }
-
- //----------------------------------------------------------------------
- public static function unserial($code)
- {
- $codeArr = array();
-
- $codeLines = explode("\n", gzuncompress($code));
- foreach ($codeLines as $line)
- $codeArr[] = str_split($line);
-
- return $codeArr;
- }
-
- //----------------------------------------------------------------------
- public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false)
- {
- $b = 0;
- $bitMask = array();
-
- $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat';
-
- if (QR_CACHEABLE) {
- if (file_exists($fileName)) {
- $bitMask = self::unserial(file_get_contents($fileName));
- } else {
- $bitMask = $this->generateMaskNo($maskNo, $width, $s);
- if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo))
- mkdir(QR_CACHE_DIR.'mask_'.$maskNo);
- file_put_contents($fileName, self::serial($bitMask));
- }
- } else {
- $bitMask = $this->generateMaskNo($maskNo, $width, $s);
- }
-
- if ($maskGenOnly)
- return;
-
- $d = $s;
-
- for($y=0; $y<$width; $y++) {
- for($x=0; $x<$width; $x++) {
- if($bitMask[$y][$x] == 1) {
- $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]);
- }
- $b += (int)(ord($d[$y][$x]) & 1);
- }
- }
-
- return $b;
- }
-
- //----------------------------------------------------------------------
- public function makeMask($width, $frame, $maskNo, $level)
- {
- $masked = array_fill(0, $width, str_repeat("\0", $width));
- $this->makeMaskNo($maskNo, $width, $frame, $masked);
- $this->writeFormatInformation($width, $masked, $maskNo, $level);
-
- return $masked;
- }
-
- //----------------------------------------------------------------------
- public function calcN1N3($length)
- {
- $demerit = 0;
-
- for($i=0; $i<$length; $i++) {
-
- if($this->runLength[$i] >= 5) {
- $demerit += (N1 + ($this->runLength[$i] - 5));
- }
- if($i & 1) {
- if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) {
- $fact = (int)($this->runLength[$i] / 3);
- if(($this->runLength[$i-2] == $fact) &&
- ($this->runLength[$i-1] == $fact) &&
- ($this->runLength[$i+1] == $fact) &&
- ($this->runLength[$i+2] == $fact)) {
- if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) {
- $demerit += N3;
- } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) {
- $demerit += N3;
- }
- }
- }
- }
- }
- return $demerit;
- }
-
- //----------------------------------------------------------------------
- public function evaluateSymbol($width, $frame)
- {
- $head = 0;
- $demerit = 0;
-
- for($y=0; $y<$width; $y++) {
- $head = 0;
- $this->runLength[0] = 1;
-
- $frameY = $frame[$y];
-
- if ($y>0)
- $frameYM = $frame[$y-1];
-
- for($x=0; $x<$width; $x++) {
- if(($x > 0) && ($y > 0)) {
- $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);
- $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);
-
- if(($b22 | ($w22 ^ 1))&1) {
- $demerit += N2;
- }
- }
- if(($x == 0) && (ord($frameY[$x]) & 1)) {
- $this->runLength[0] = -1;
- $head = 1;
- $this->runLength[$head] = 1;
- } else if($x > 0) {
- if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) {
- $head++;
- $this->runLength[$head] = 1;
- } else {
- $this->runLength[$head]++;
- }
- }
- }
-
- $demerit += $this->calcN1N3($head+1);
- }
-
- for($x=0; $x<$width; $x++) {
- $head = 0;
- $this->runLength[0] = 1;
-
- for($y=0; $y<$width; $y++) {
- if($y == 0 && (ord($frame[$y][$x]) & 1)) {
- $this->runLength[0] = -1;
- $head = 1;
- $this->runLength[$head] = 1;
- } else if($y > 0) {
- if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) {
- $head++;
- $this->runLength[$head] = 1;
- } else {
- $this->runLength[$head]++;
- }
- }
- }
-
- $demerit += $this->calcN1N3($head+1);
- }
-
- return $demerit;
- }
-
-
- //----------------------------------------------------------------------
- public function mask($width, $frame, $level)
- {
- $minDemerit = PHP_INT_MAX;
- $bestMaskNum = 0;
- $bestMask = array();
-
- $checked_masks = array(0,1,2,3,4,5,6,7);
-
- if (QR_FIND_FROM_RANDOM !== false) {
-
- $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9);
- for ($i = 0; $i < $howManuOut; $i++) {
- $remPos = rand (0, count($checked_masks)-1);
- unset($checked_masks[$remPos]);
- $checked_masks = array_values($checked_masks);
- }
-
- }
-
- $bestMask = $frame;
-
- foreach($checked_masks as $i) {
- $mask = array_fill(0, $width, str_repeat("\0", $width));
-
- $demerit = 0;
- $blacks = 0;
- $blacks = $this->makeMaskNo($i, $width, $frame, $mask);
- $blacks += $this->writeFormatInformation($width, $mask, $i, $level);
- $blacks = (int)(100 * $blacks / ($width * $width));
- $demerit = (int)((int)(abs($blacks - 50) / 5) * N4);
- $demerit += $this->evaluateSymbol($width, $mask);
-
- if($demerit < $minDemerit) {
- $minDemerit = $demerit;
- $bestMask = $mask;
- $bestMaskNum = $i;
- }
- }
-
- return $bestMask;
- }
-
- //----------------------------------------------------------------------
- }
-
-
-
-
-//---- qrencode.php -----------------------------
-
-
-
-
-/*
- * PHP QR Code encoder
- *
- * Main encoder classes.
- *
- * Based on libqrencode C library distributed under LGPL 2.1
- * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- class QRrsblock {
- public $dataLength;
- public $data = array();
- public $eccLength;
- public $ecc = array();
-
- public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs)
- {
- $rs->encode_rs_char($data, $ecc);
-
- $this->dataLength = $dl;
- $this->data = $data;
- $this->eccLength = $el;
- $this->ecc = $ecc;
- }
- };
-
- //##########################################################################
-
- class QRrawcode {
- public $version;
- public $datacode = array();
- public $ecccode = array();
- public $blocks;
- public $rsblocks = array(); //of RSblock
- public $count;
- public $dataLength;
- public $eccLength;
- public $b1;
-
- //----------------------------------------------------------------------
- public function __construct(QRinput $input)
- {
- $spec = array(0,0,0,0,0);
-
- $this->datacode = $input->getByteStream();
- if(is_null($this->datacode)) {
- throw new Exception('null imput string');
- }
-
- QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
-
- $this->version = $input->getVersion();
- $this->b1 = QRspec::rsBlockNum1($spec);
- $this->dataLength = QRspec::rsDataLength($spec);
- $this->eccLength = QRspec::rsEccLength($spec);
- $this->ecccode = array_fill(0, $this->eccLength, 0);
- $this->blocks = QRspec::rsBlockNum($spec);
-
- $ret = $this->init($spec);
- if($ret < 0) {
- throw new Exception('block alloc error');
- return null;
- }
-
- $this->count = 0;
- }
-
- //----------------------------------------------------------------------
- public function init(array $spec)
- {
- $dl = QRspec::rsDataCodes1($spec);
- $el = QRspec::rsEccCodes1($spec);
- $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
-
-
- $blockNo = 0;
- $dataPos = 0;
- $eccPos = 0;
- for($i=0; $iecccode,$eccPos);
- $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
- $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
-
- $dataPos += $dl;
- $eccPos += $el;
- $blockNo++;
- }
-
- if(QRspec::rsBlockNum2($spec) == 0)
- return 0;
-
- $dl = QRspec::rsDataCodes2($spec);
- $el = QRspec::rsEccCodes2($spec);
- $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
-
- if($rs == NULL) return -1;
-
- for($i=0; $iecccode,$eccPos);
- $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
- $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
-
- $dataPos += $dl;
- $eccPos += $el;
- $blockNo++;
- }
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function getCode()
- {
- $ret = 0;
-
- if($this->count < $this->dataLength) {
- $row = $this->count % $this->blocks;
- $col = $this->count / $this->blocks;
- if($col >= $this->rsblocks[0]->dataLength) {
- $row += $this->b1;
- }
- $ret = $this->rsblocks[$row]->data[$col];
- } else if($this->count < $this->dataLength + $this->eccLength) {
- $row = ($this->count - $this->dataLength) % $this->blocks;
- $col = ($this->count - $this->dataLength) / $this->blocks;
- $ret = $this->rsblocks[$row]->ecc[$col];
- } else {
- return 0;
- }
- $this->count++;
-
- return $ret;
- }
- }
-
- //##########################################################################
-
- class QRcode {
-
- public $version;
- public $width;
- public $data;
-
- //----------------------------------------------------------------------
- public function encodeMask(QRinput $input, $mask)
- {
- if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) {
- throw new Exception('wrong version');
- }
- if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) {
- throw new Exception('wrong level');
- }
-
- $raw = new QRrawcode($input);
-
- QRtools::markTime('after_raw');
-
- $version = $raw->version;
- $width = QRspec::getWidth($version);
- $frame = QRspec::newFrame($version);
-
- $filler = new FrameFiller($width, $frame);
- if(is_null($filler)) {
- return NULL;
- }
-
- // inteleaved data and ecc codes
- for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) {
- $code = $raw->getCode();
- $bit = 0x80;
- for($j=0; $j<8; $j++) {
- $addr = $filler->next();
- $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
- $bit = $bit >> 1;
- }
- }
-
- QRtools::markTime('after_filler');
-
- unset($raw);
-
- // remainder bits
- $j = QRspec::getRemainder($version);
- for($i=0; $i<$j; $i++) {
- $addr = $filler->next();
- $filler->setFrameAt($addr, 0x02);
- }
-
- $frame = $filler->frame;
- unset($filler);
-
-
- // masking
- $maskObj = new QRmask();
- if($mask < 0) {
-
- if (QR_FIND_BEST_MASK) {
- $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
- } else {
- $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());
- }
- } else {
- $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
- }
-
- if($masked == NULL) {
- return NULL;
- }
-
- QRtools::markTime('after_mask');
-
- $this->version = $version;
- $this->width = $width;
- $this->data = $masked;
-
- return $this;
- }
-
- //----------------------------------------------------------------------
- public function encodeInput(QRinput $input)
- {
- return $this->encodeMask($input, -1);
- }
-
- //----------------------------------------------------------------------
- public function encodeString8bit($string, $version, $level)
- {
- if(string == NULL) {
- throw new Exception('empty string!');
- return NULL;
- }
-
- $input = new QRinput($version, $level);
- if($input == NULL) return NULL;
-
- $ret = $input->append(QR_MODE_8, strlen($string), str_split($string));
- if($ret < 0) {
- unset($input);
- return NULL;
- }
- return $this->encodeInput($input);
- }
-
- //----------------------------------------------------------------------
- public function encodeString($string, $version, $level, $hint, $casesensitive)
- {
-
- if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) {
- throw new Exception('bad hint');
- return NULL;
- }
-
- $input = new QRinput($version, $level);
- if($input == NULL) return NULL;
-
- $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive);
- if($ret < 0) {
- return NULL;
- }
-
- return $this->encodeInput($input);
- }
-
- //----------------------------------------------------------------------
- public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false)
- {
- $enc = QRencode::factory($level, $size, $margin);
- return $enc->encodePNG($text, $outfile, $saveandprint=false);
- }
-
- //----------------------------------------------------------------------
- public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4)
- {
- $enc = QRencode::factory($level, $size, $margin);
- return $enc->encode($text, $outfile);
- }
-
- //----------------------------------------------------------------------
- public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4)
- {
- $enc = QRencode::factory($level, $size, $margin);
- return $enc->encodeRAW($text, $outfile);
- }
- }
-
- //##########################################################################
-
- class FrameFiller {
-
- public $width;
- public $frame;
- public $x;
- public $y;
- public $dir;
- public $bit;
-
- //----------------------------------------------------------------------
- public function __construct($width, &$frame)
- {
- $this->width = $width;
- $this->frame = $frame;
- $this->x = $width - 1;
- $this->y = $width - 1;
- $this->dir = -1;
- $this->bit = -1;
- }
-
- //----------------------------------------------------------------------
- public function setFrameAt($at, $val)
- {
- $this->frame[$at['y']][$at['x']] = chr($val);
- }
-
- //----------------------------------------------------------------------
- public function getFrameAt($at)
- {
- return ord($this->frame[$at['y']][$at['x']]);
- }
-
- //----------------------------------------------------------------------
- public function next()
- {
- do {
-
- if($this->bit == -1) {
- $this->bit = 0;
- return array('x'=>$this->x, 'y'=>$this->y);
- }
-
- $x = $this->x;
- $y = $this->y;
- $w = $this->width;
-
- if($this->bit == 0) {
- $x--;
- $this->bit++;
- } else {
- $x++;
- $y += $this->dir;
- $this->bit--;
- }
-
- if($this->dir < 0) {
- if($y < 0) {
- $y = 0;
- $x -= 2;
- $this->dir = 1;
- if($x == 6) {
- $x--;
- $y = 9;
- }
- }
- } else {
- if($y == $w) {
- $y = $w - 1;
- $x -= 2;
- $this->dir = -1;
- if($x == 6) {
- $x--;
- $y -= 8;
- }
- }
- }
- if($x < 0 || $y < 0) return null;
-
- $this->x = $x;
- $this->y = $y;
-
- } while(ord($this->frame[$y][$x]) & 0x80);
-
- return array('x'=>$x, 'y'=>$y);
- }
-
- } ;
-
- //##########################################################################
-
- class QRencode {
-
- public $casesensitive = true;
- public $eightbit = false;
-
- public $version = 0;
- public $size = 3;
- public $margin = 4;
-
- public $structured = 0; // not supported yet
-
- public $level = QR_ECLEVEL_L;
- public $hint = QR_MODE_8;
-
- //----------------------------------------------------------------------
- public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4)
- {
- $enc = new QRencode();
- $enc->size = $size;
- $enc->margin = $margin;
-
- switch ($level.'') {
- case '0':
- case '1':
- case '2':
- case '3':
- $enc->level = $level;
- break;
- case 'l':
- case 'L':
- $enc->level = QR_ECLEVEL_L;
- break;
- case 'm':
- case 'M':
- $enc->level = QR_ECLEVEL_M;
- break;
- case 'q':
- case 'Q':
- $enc->level = QR_ECLEVEL_Q;
- break;
- case 'h':
- case 'H':
- $enc->level = QR_ECLEVEL_H;
- break;
- }
-
- return $enc;
- }
-
- //----------------------------------------------------------------------
- public function encodeRAW($intext, $outfile = false)
- {
- $code = new QRcode();
-
- if($this->eightbit) {
- $code->encodeString8bit($intext, $this->version, $this->level);
- } else {
- $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
- }
-
- return $code->data;
- }
-
- //----------------------------------------------------------------------
- public function encode($intext, $outfile = false)
- {
- $code = new QRcode();
-
- if($this->eightbit) {
- $code->encodeString8bit($intext, $this->version, $this->level);
- } else {
- $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
- }
-
- QRtools::markTime('after_encode');
-
- if ($outfile!== false) {
- file_put_contents($outfile, join("\n", QRtools::binarize($code->data)));
- } else {
- return QRtools::binarize($code->data);
- }
- }
-
- //----------------------------------------------------------------------
- public function encodePNG($intext, $outfile = false,$saveandprint=false)
- {
- try {
-
- ob_start();
- $tab = $this->encode($intext);
- $err = ob_get_contents();
- ob_end_clean();
-
- if ($err != '')
- QRtools::log($outfile, $err);
-
- $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin));
-
- QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint);
-
- } catch (Exception $e) {
-
- QRtools::log($outfile, $e->getMessage());
-
- }
- }
- }
-
-
diff --git a/lib/phpqrcode/qrbitstream.php b/lib/phpqrcode/qrbitstream.php
deleted file mode 100644
index 7d4ec4a6c..000000000
--- a/lib/phpqrcode/qrbitstream.php
+++ /dev/null
@@ -1,180 +0,0 @@
-
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- class QRbitstream {
-
- public $data = array();
-
- //----------------------------------------------------------------------
- public function size()
- {
- return count($this->data);
- }
-
- //----------------------------------------------------------------------
- public function allocate($setLength)
- {
- $this->data = array_fill(0, $setLength, 0);
- return 0;
- }
-
- //----------------------------------------------------------------------
- public static function newFromNum($bits, $num)
- {
- $bstream = new QRbitstream();
- $bstream->allocate($bits);
-
- $mask = 1 << ($bits - 1);
- for($i=0; $i<$bits; $i++) {
- if($num & $mask) {
- $bstream->data[$i] = 1;
- } else {
- $bstream->data[$i] = 0;
- }
- $mask = $mask >> 1;
- }
-
- return $bstream;
- }
-
- //----------------------------------------------------------------------
- public static function newFromBytes($size, $data)
- {
- $bstream = new QRbitstream();
- $bstream->allocate($size * 8);
- $p=0;
-
- for($i=0; $i<$size; $i++) {
- $mask = 0x80;
- for($j=0; $j<8; $j++) {
- if($data[$i] & $mask) {
- $bstream->data[$p] = 1;
- } else {
- $bstream->data[$p] = 0;
- }
- $p++;
- $mask = $mask >> 1;
- }
- }
-
- return $bstream;
- }
-
- //----------------------------------------------------------------------
- public function append(QRbitstream $arg)
- {
- if (is_null($arg)) {
- return -1;
- }
-
- if($arg->size() == 0) {
- return 0;
- }
-
- if($this->size() == 0) {
- $this->data = $arg->data;
- return 0;
- }
-
- $this->data = array_values(array_merge($this->data, $arg->data));
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function appendNum($bits, $num)
- {
- if ($bits == 0)
- return 0;
-
- $b = QRbitstream::newFromNum($bits, $num);
-
- if(is_null($b))
- return -1;
-
- $ret = $this->append($b);
- unset($b);
-
- return $ret;
- }
-
- //----------------------------------------------------------------------
- public function appendBytes($size, $data)
- {
- if ($size == 0)
- return 0;
-
- $b = QRbitstream::newFromBytes($size, $data);
-
- if(is_null($b))
- return -1;
-
- $ret = $this->append($b);
- unset($b);
-
- return $ret;
- }
-
- //----------------------------------------------------------------------
- public function toByte()
- {
-
- $size = $this->size();
-
- if($size == 0) {
- return array();
- }
-
- $data = array_fill(0, (int)(($size + 7) / 8), 0);
- $bytes = (int)($size / 8);
-
- $p = 0;
-
- for($i=0; $i<$bytes; $i++) {
- $v = 0;
- for($j=0; $j<8; $j++) {
- $v = $v << 1;
- $v |= $this->data[$p];
- $p++;
- }
- $data[$i] = $v;
- }
-
- if($size & 7) {
- $v = 0;
- for($j=0; $j<($size & 7); $j++) {
- $v = $v << 1;
- $v |= $this->data[$p];
- $p++;
- }
- $data[$bytes] = $v;
- }
-
- return $data;
- }
-
- }
diff --git a/lib/phpqrcode/qrconfig.php b/lib/phpqrcode/qrconfig.php
deleted file mode 100644
index e53dff8c2..000000000
--- a/lib/phpqrcode/qrconfig.php
+++ /dev/null
@@ -1,17 +0,0 @@
-
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- // Encoding modes
-
- define('QR_MODE_NUL', -1);
- define('QR_MODE_NUM', 0);
- define('QR_MODE_AN', 1);
- define('QR_MODE_8', 2);
- define('QR_MODE_KANJI', 3);
- define('QR_MODE_STRUCTURE', 4);
-
- // Levels of error correction.
-
- define('QR_ECLEVEL_L', 0);
- define('QR_ECLEVEL_M', 1);
- define('QR_ECLEVEL_Q', 2);
- define('QR_ECLEVEL_H', 3);
-
- // Supported output formats
-
- define('QR_FORMAT_TEXT', 0);
- define('QR_FORMAT_PNG', 1);
-
- class qrstr {
- public static function set(&$srctab, $x, $y, $repl, $replLen = false) {
- $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl));
- }
- }
\ No newline at end of file
diff --git a/lib/phpqrcode/qrencode.php b/lib/phpqrcode/qrencode.php
deleted file mode 100644
index 5bdeaec20..000000000
--- a/lib/phpqrcode/qrencode.php
+++ /dev/null
@@ -1,502 +0,0 @@
-
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- class QRrsblock {
- public $dataLength;
- public $data = array();
- public $eccLength;
- public $ecc = array();
-
- public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs)
- {
- $rs->encode_rs_char($data, $ecc);
-
- $this->dataLength = $dl;
- $this->data = $data;
- $this->eccLength = $el;
- $this->ecc = $ecc;
- }
- };
-
- //##########################################################################
-
- class QRrawcode {
- public $version;
- public $datacode = array();
- public $ecccode = array();
- public $blocks;
- public $rsblocks = array(); //of RSblock
- public $count;
- public $dataLength;
- public $eccLength;
- public $b1;
-
- //----------------------------------------------------------------------
- public function __construct(QRinput $input)
- {
- $spec = array(0,0,0,0,0);
-
- $this->datacode = $input->getByteStream();
- if(is_null($this->datacode)) {
- throw new Exception('null imput string');
- }
-
- QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
-
- $this->version = $input->getVersion();
- $this->b1 = QRspec::rsBlockNum1($spec);
- $this->dataLength = QRspec::rsDataLength($spec);
- $this->eccLength = QRspec::rsEccLength($spec);
- $this->ecccode = array_fill(0, $this->eccLength, 0);
- $this->blocks = QRspec::rsBlockNum($spec);
-
- $ret = $this->init($spec);
- if($ret < 0) {
- throw new Exception('block alloc error');
- return null;
- }
-
- $this->count = 0;
- }
-
- //----------------------------------------------------------------------
- public function init(array $spec)
- {
- $dl = QRspec::rsDataCodes1($spec);
- $el = QRspec::rsEccCodes1($spec);
- $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
-
-
- $blockNo = 0;
- $dataPos = 0;
- $eccPos = 0;
- for($i=0; $iecccode,$eccPos);
- $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
- $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
-
- $dataPos += $dl;
- $eccPos += $el;
- $blockNo++;
- }
-
- if(QRspec::rsBlockNum2($spec) == 0)
- return 0;
-
- $dl = QRspec::rsDataCodes2($spec);
- $el = QRspec::rsEccCodes2($spec);
- $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
-
- if($rs == NULL) return -1;
-
- for($i=0; $iecccode,$eccPos);
- $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
- $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
-
- $dataPos += $dl;
- $eccPos += $el;
- $blockNo++;
- }
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function getCode()
- {
- $ret = 0;
-
- if($this->count < $this->dataLength) {
- $row = $this->count % $this->blocks;
- $col = $this->count / $this->blocks;
- if($col >= $this->rsblocks[0]->dataLength) {
- $row += $this->b1;
- }
- $ret = $this->rsblocks[$row]->data[$col];
- } else if($this->count < $this->dataLength + $this->eccLength) {
- $row = ($this->count - $this->dataLength) % $this->blocks;
- $col = ($this->count - $this->dataLength) / $this->blocks;
- $ret = $this->rsblocks[$row]->ecc[$col];
- } else {
- return 0;
- }
- $this->count++;
-
- return $ret;
- }
- }
-
- //##########################################################################
-
- class QRcode {
-
- public $version;
- public $width;
- public $data;
-
- //----------------------------------------------------------------------
- public function encodeMask(QRinput $input, $mask)
- {
- if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) {
- throw new Exception('wrong version');
- }
- if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) {
- throw new Exception('wrong level');
- }
-
- $raw = new QRrawcode($input);
-
- QRtools::markTime('after_raw');
-
- $version = $raw->version;
- $width = QRspec::getWidth($version);
- $frame = QRspec::newFrame($version);
-
- $filler = new FrameFiller($width, $frame);
- if(is_null($filler)) {
- return NULL;
- }
-
- // inteleaved data and ecc codes
- for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) {
- $code = $raw->getCode();
- $bit = 0x80;
- for($j=0; $j<8; $j++) {
- $addr = $filler->next();
- $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
- $bit = $bit >> 1;
- }
- }
-
- QRtools::markTime('after_filler');
-
- unset($raw);
-
- // remainder bits
- $j = QRspec::getRemainder($version);
- for($i=0; $i<$j; $i++) {
- $addr = $filler->next();
- $filler->setFrameAt($addr, 0x02);
- }
-
- $frame = $filler->frame;
- unset($filler);
-
-
- // masking
- $maskObj = new QRmask();
- if($mask < 0) {
-
- if (QR_FIND_BEST_MASK) {
- $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
- } else {
- $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());
- }
- } else {
- $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
- }
-
- if($masked == NULL) {
- return NULL;
- }
-
- QRtools::markTime('after_mask');
-
- $this->version = $version;
- $this->width = $width;
- $this->data = $masked;
-
- return $this;
- }
-
- //----------------------------------------------------------------------
- public function encodeInput(QRinput $input)
- {
- return $this->encodeMask($input, -1);
- }
-
- //----------------------------------------------------------------------
- public function encodeString8bit($string, $version, $level)
- {
- if(string == NULL) {
- throw new Exception('empty string!');
- return NULL;
- }
-
- $input = new QRinput($version, $level);
- if($input == NULL) return NULL;
-
- $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string));
- if($ret < 0) {
- unset($input);
- return NULL;
- }
- return $this->encodeInput($input);
- }
-
- //----------------------------------------------------------------------
- public function encodeString($string, $version, $level, $hint, $casesensitive)
- {
-
- if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) {
- throw new Exception('bad hint');
- return NULL;
- }
-
- $input = new QRinput($version, $level);
- if($input == NULL) return NULL;
-
- $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive);
- if($ret < 0) {
- return NULL;
- }
-
- return $this->encodeInput($input);
- }
-
- //----------------------------------------------------------------------
- public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false)
- {
- $enc = QRencode::factory($level, $size, $margin);
- return $enc->encodePNG($text, $outfile, $saveandprint=false);
- }
-
- //----------------------------------------------------------------------
- public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4)
- {
- $enc = QRencode::factory($level, $size, $margin);
- return $enc->encode($text, $outfile);
- }
-
- //----------------------------------------------------------------------
- public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4)
- {
- $enc = QRencode::factory($level, $size, $margin);
- return $enc->encodeRAW($text, $outfile);
- }
- }
-
- //##########################################################################
-
- class FrameFiller {
-
- public $width;
- public $frame;
- public $x;
- public $y;
- public $dir;
- public $bit;
-
- //----------------------------------------------------------------------
- public function __construct($width, &$frame)
- {
- $this->width = $width;
- $this->frame = $frame;
- $this->x = $width - 1;
- $this->y = $width - 1;
- $this->dir = -1;
- $this->bit = -1;
- }
-
- //----------------------------------------------------------------------
- public function setFrameAt($at, $val)
- {
- $this->frame[$at['y']][$at['x']] = chr($val);
- }
-
- //----------------------------------------------------------------------
- public function getFrameAt($at)
- {
- return ord($this->frame[$at['y']][$at['x']]);
- }
-
- //----------------------------------------------------------------------
- public function next()
- {
- do {
-
- if($this->bit == -1) {
- $this->bit = 0;
- return array('x'=>$this->x, 'y'=>$this->y);
- }
-
- $x = $this->x;
- $y = $this->y;
- $w = $this->width;
-
- if($this->bit == 0) {
- $x--;
- $this->bit++;
- } else {
- $x++;
- $y += $this->dir;
- $this->bit--;
- }
-
- if($this->dir < 0) {
- if($y < 0) {
- $y = 0;
- $x -= 2;
- $this->dir = 1;
- if($x == 6) {
- $x--;
- $y = 9;
- }
- }
- } else {
- if($y == $w) {
- $y = $w - 1;
- $x -= 2;
- $this->dir = -1;
- if($x == 6) {
- $x--;
- $y -= 8;
- }
- }
- }
- if($x < 0 || $y < 0) return null;
-
- $this->x = $x;
- $this->y = $y;
-
- } while(ord($this->frame[$y][$x]) & 0x80);
-
- return array('x'=>$x, 'y'=>$y);
- }
-
- } ;
-
- //##########################################################################
-
- class QRencode {
-
- public $casesensitive = true;
- public $eightbit = false;
-
- public $version = 0;
- public $size = 3;
- public $margin = 4;
-
- public $structured = 0; // not supported yet
-
- public $level = QR_ECLEVEL_L;
- public $hint = QR_MODE_8;
-
- //----------------------------------------------------------------------
- public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4)
- {
- $enc = new QRencode();
- $enc->size = $size;
- $enc->margin = $margin;
-
- switch ($level.'') {
- case '0':
- case '1':
- case '2':
- case '3':
- $enc->level = $level;
- break;
- case 'l':
- case 'L':
- $enc->level = QR_ECLEVEL_L;
- break;
- case 'm':
- case 'M':
- $enc->level = QR_ECLEVEL_M;
- break;
- case 'q':
- case 'Q':
- $enc->level = QR_ECLEVEL_Q;
- break;
- case 'h':
- case 'H':
- $enc->level = QR_ECLEVEL_H;
- break;
- }
-
- return $enc;
- }
-
- //----------------------------------------------------------------------
- public function encodeRAW($intext, $outfile = false)
- {
- $code = new QRcode();
-
- if($this->eightbit) {
- $code->encodeString8bit($intext, $this->version, $this->level);
- } else {
- $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
- }
-
- return $code->data;
- }
-
- //----------------------------------------------------------------------
- public function encode($intext, $outfile = false)
- {
- $code = new QRcode();
-
- if($this->eightbit) {
- $code->encodeString8bit($intext, $this->version, $this->level);
- } else {
- $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
- }
-
- QRtools::markTime('after_encode');
-
- if ($outfile!== false) {
- file_put_contents($outfile, join("\n", QRtools::binarize($code->data)));
- } else {
- return QRtools::binarize($code->data);
- }
- }
-
- //----------------------------------------------------------------------
- public function encodePNG($intext, $outfile = false,$saveandprint=false)
- {
- try {
-
- ob_start();
- $tab = $this->encode($intext);
- $err = ob_get_contents();
- ob_end_clean();
-
- if ($err != '')
- QRtools::log($outfile, $err);
-
- $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin));
-
- QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint);
-
- } catch (Exception $e) {
-
- QRtools::log($outfile, $e->getMessage());
-
- }
- }
- }
diff --git a/lib/phpqrcode/qrimage.php b/lib/phpqrcode/qrimage.php
deleted file mode 100644
index 10b0a6e1b..000000000
--- a/lib/phpqrcode/qrimage.php
+++ /dev/null
@@ -1,95 +0,0 @@
-
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- define('QR_IMAGE', true);
-
- class QRimage {
-
- //----------------------------------------------------------------------
- public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE)
- {
- $image = self::image($frame, $pixelPerPoint, $outerFrame);
-
- if ($filename === false) {
- Header("Content-type: image/png");
- ImagePng($image);
- } else {
- if($saveandprint===TRUE){
- ImagePng($image, $filename);
- header("Content-type: image/png");
- ImagePng($image);
- }else{
- ImagePng($image, $filename);
- }
- }
-
- ImageDestroy($image);
- }
-
- //----------------------------------------------------------------------
- public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85)
- {
- $image = self::image($frame, $pixelPerPoint, $outerFrame);
-
- if ($filename === false) {
- Header("Content-type: image/jpeg");
- ImageJpeg($image, null, $q);
- } else {
- ImageJpeg($image, $filename, $q);
- }
-
- ImageDestroy($image);
- }
-
- //----------------------------------------------------------------------
- private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4)
- {
- $h = count($frame);
- $w = strlen($frame[0]);
-
- $imgW = $w + 2*$outerFrame;
- $imgH = $h + 2*$outerFrame;
-
- $base_image =ImageCreate($imgW, $imgH);
-
- $col[0] = ImageColorAllocate($base_image,255,255,255);
- $col[1] = ImageColorAllocate($base_image,0,0,0);
-
- imagefill($base_image, 0, 0, $col[0]);
-
- for($y=0; $y<$h; $y++) {
- for($x=0; $x<$w; $x++) {
- if ($frame[$y][$x] == '1') {
- ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]);
- }
- }
- }
-
- $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
- ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
- ImageDestroy($base_image);
-
- return $target_image;
- }
- }
\ No newline at end of file
diff --git a/lib/phpqrcode/qrinput.php b/lib/phpqrcode/qrinput.php
deleted file mode 100644
index 0f6d7f944..000000000
--- a/lib/phpqrcode/qrinput.php
+++ /dev/null
@@ -1,729 +0,0 @@
-
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- define('STRUCTURE_HEADER_BITS', 20);
- define('MAX_STRUCTURED_SYMBOLS', 16);
-
- class QRinputItem {
-
- public $mode;
- public $size;
- public $data;
- public $bstream;
-
- public function __construct($mode, $size, $data, $bstream = null)
- {
- $setData = array_slice($data, 0, $size);
-
- if (count($setData) < $size) {
- $setData = array_merge($setData, array_fill(0,$size-count($setData),0));
- }
-
- if(!QRinput::check($mode, $size, $setData)) {
- throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData));
- return null;
- }
-
- $this->mode = $mode;
- $this->size = $size;
- $this->data = $setData;
- $this->bstream = $bstream;
- }
-
- //----------------------------------------------------------------------
- public function encodeModeNum($version)
- {
- try {
-
- $words = (int)($this->size / 3);
- $bs = new QRbitstream();
-
- $val = 0x1;
- $bs->appendNum(4, $val);
- $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size);
-
- for($i=0; $i<$words; $i++) {
- $val = (ord($this->data[$i*3 ]) - ord('0')) * 100;
- $val += (ord($this->data[$i*3+1]) - ord('0')) * 10;
- $val += (ord($this->data[$i*3+2]) - ord('0'));
- $bs->appendNum(10, $val);
- }
-
- if($this->size - $words * 3 == 1) {
- $val = ord($this->data[$words*3]) - ord('0');
- $bs->appendNum(4, $val);
- } else if($this->size - $words * 3 == 2) {
- $val = (ord($this->data[$words*3 ]) - ord('0')) * 10;
- $val += (ord($this->data[$words*3+1]) - ord('0'));
- $bs->appendNum(7, $val);
- }
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function encodeModeAn($version)
- {
- try {
- $words = (int)($this->size / 2);
- $bs = new QRbitstream();
-
- $bs->appendNum(4, 0x02);
- $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size);
-
- for($i=0; $i<$words; $i++) {
- $val = (int)QRinput::lookAnTable(ord($this->data[$i*2 ])) * 45;
- $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1]));
-
- $bs->appendNum(11, $val);
- }
-
- if($this->size & 1) {
- $val = QRinput::lookAnTable(ord($this->data[$words * 2]));
- $bs->appendNum(6, $val);
- }
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function encodeMode8($version)
- {
- try {
- $bs = new QRbitstream();
-
- $bs->appendNum(4, 0x4);
- $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size);
-
- for($i=0; $i<$this->size; $i++) {
- $bs->appendNum(8, ord($this->data[$i]));
- }
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function encodeModeKanji($version)
- {
- try {
-
- $bs = new QRbitrtream();
-
- $bs->appendNum(4, 0x8);
- $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2));
-
- for($i=0; $i<$this->size; $i+=2) {
- $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]);
- if($val <= 0x9ffc) {
- $val -= 0x8140;
- } else {
- $val -= 0xc140;
- }
-
- $h = ($val >> 8) * 0xc0;
- $val = ($val & 0xff) + $h;
-
- $bs->appendNum(13, $val);
- }
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function encodeModeStructure()
- {
- try {
- $bs = new QRbitstream();
-
- $bs->appendNum(4, 0x03);
- $bs->appendNum(4, ord($this->data[1]) - 1);
- $bs->appendNum(4, ord($this->data[0]) - 1);
- $bs->appendNum(8, ord($this->data[2]));
-
- $this->bstream = $bs;
- return 0;
-
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function estimateBitStreamSizeOfEntry($version)
- {
- $bits = 0;
-
- if($version == 0)
- $version = 1;
-
- switch($this->mode) {
- case QR_MODE_NUM: $bits = QRinput::estimateBitsModeNum($this->size); break;
- case QR_MODE_AN: $bits = QRinput::estimateBitsModeAn($this->size); break;
- case QR_MODE_8: $bits = QRinput::estimateBitsMode8($this->size); break;
- case QR_MODE_KANJI: $bits = QRinput::estimateBitsModeKanji($this->size);break;
- case QR_MODE_STRUCTURE: return STRUCTURE_HEADER_BITS;
- default:
- return 0;
- }
-
- $l = QRspec::lengthIndicator($this->mode, $version);
- $m = 1 << $l;
- $num = (int)(($this->size + $m - 1) / $m);
-
- $bits += $num * (4 + $l);
-
- return $bits;
- }
-
- //----------------------------------------------------------------------
- public function encodeBitStream($version)
- {
- try {
-
- unset($this->bstream);
- $words = QRspec::maximumWords($this->mode, $version);
-
- if($this->size > $words) {
-
- $st1 = new QRinputItem($this->mode, $words, $this->data);
- $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words));
-
- $st1->encodeBitStream($version);
- $st2->encodeBitStream($version);
-
- $this->bstream = new QRbitstream();
- $this->bstream->append($st1->bstream);
- $this->bstream->append($st2->bstream);
-
- unset($st1);
- unset($st2);
-
- } else {
-
- $ret = 0;
-
- switch($this->mode) {
- case QR_MODE_NUM: $ret = $this->encodeModeNum($version); break;
- case QR_MODE_AN: $ret = $this->encodeModeAn($version); break;
- case QR_MODE_8: $ret = $this->encodeMode8($version); break;
- case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break;
- case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure(); break;
-
- default:
- break;
- }
-
- if($ret < 0)
- return -1;
- }
-
- return $this->bstream->size();
-
- } catch (Exception $e) {
- return -1;
- }
- }
- };
-
- //##########################################################################
-
- class QRinput {
-
- public $items;
-
- private $version;
- private $level;
-
- //----------------------------------------------------------------------
- public function __construct($version = 0, $level = QR_ECLEVEL_L)
- {
- if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) {
- throw new Exception('Invalid version no');
- return NULL;
- }
-
- $this->version = $version;
- $this->level = $level;
- }
-
- //----------------------------------------------------------------------
- public function getVersion()
- {
- return $this->version;
- }
-
- //----------------------------------------------------------------------
- public function setVersion($version)
- {
- if($version < 0 || $version > QRSPEC_VERSION_MAX) {
- throw new Exception('Invalid version no');
- return -1;
- }
-
- $this->version = $version;
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function getErrorCorrectionLevel()
- {
- return $this->level;
- }
-
- //----------------------------------------------------------------------
- public function setErrorCorrectionLevel($level)
- {
- if($level > QR_ECLEVEL_H) {
- throw new Exception('Invalid ECLEVEL');
- return -1;
- }
-
- $this->level = $level;
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function appendEntry(QRinputItem $entry)
- {
- $this->items[] = $entry;
- }
-
- //----------------------------------------------------------------------
- public function append($mode, $size, $data)
- {
- try {
- $entry = new QRinputItem($mode, $size, $data);
- $this->items[] = $entry;
- return 0;
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
-
- public function insertStructuredAppendHeader($size, $index, $parity)
- {
- if( $size > MAX_STRUCTURED_SYMBOLS ) {
- throw new Exception('insertStructuredAppendHeader wrong size');
- }
-
- if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) {
- throw new Exception('insertStructuredAppendHeader wrong index');
- }
-
- $buf = array($size, $index, $parity);
-
- try {
- $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf);
- array_unshift($this->items, $entry);
- return 0;
- } catch (Exception $e) {
- return -1;
- }
- }
-
- //----------------------------------------------------------------------
- public function calcParity()
- {
- $parity = 0;
-
- foreach($this->items as $item) {
- if($item->mode != QR_MODE_STRUCTURE) {
- for($i=$item->size-1; $i>=0; $i--) {
- $parity ^= $item->data[$i];
- }
- }
- }
-
- return $parity;
- }
-
- //----------------------------------------------------------------------
- public static function checkModeNum($size, $data)
- {
- for($i=0; $i<$size; $i++) {
- if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){
- return false;
- }
- }
-
- return true;
- }
-
- //----------------------------------------------------------------------
- public static function estimateBitsModeNum($size)
- {
- $w = (int)$size / 3;
- $bits = $w * 10;
-
- switch($size - $w * 3) {
- case 1:
- $bits += 4;
- break;
- case 2:
- $bits += 7;
- break;
- default:
- break;
- }
-
- return $bits;
- }
-
- //----------------------------------------------------------------------
- public static $anTable = array(
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
- -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
- );
-
- //----------------------------------------------------------------------
- public static function lookAnTable($c)
- {
- return (($c > 127)?-1:self::$anTable[$c]);
- }
-
- //----------------------------------------------------------------------
- public static function checkModeAn($size, $data)
- {
- for($i=0; $i<$size; $i++) {
- if (self::lookAnTable(ord($data[$i])) == -1) {
- return false;
- }
- }
-
- return true;
- }
-
- //----------------------------------------------------------------------
- public static function estimateBitsModeAn($size)
- {
- $w = (int)($size / 2);
- $bits = $w * 11;
-
- if($size & 1) {
- $bits += 6;
- }
-
- return $bits;
- }
-
- //----------------------------------------------------------------------
- public static function estimateBitsMode8($size)
- {
- return $size * 8;
- }
-
- //----------------------------------------------------------------------
- public function estimateBitsModeKanji($size)
- {
- return (int)(($size / 2) * 13);
- }
-
- //----------------------------------------------------------------------
- public static function checkModeKanji($size, $data)
- {
- if($size & 1)
- return false;
-
- for($i=0; $i<$size; $i+=2) {
- $val = (ord($data[$i]) << 8) | ord($data[$i+1]);
- if( $val < 0x8140
- || ($val > 0x9ffc && $val < 0xe040)
- || $val > 0xebbf) {
- return false;
- }
- }
-
- return true;
- }
-
- /***********************************************************************
- * Validation
- **********************************************************************/
-
- public static function check($mode, $size, $data)
- {
- if($size <= 0)
- return false;
-
- switch($mode) {
- case QR_MODE_NUM: return self::checkModeNum($size, $data); break;
- case QR_MODE_AN: return self::checkModeAn($size, $data); break;
- case QR_MODE_KANJI: return self::checkModeKanji($size, $data); break;
- case QR_MODE_8: return true; break;
- case QR_MODE_STRUCTURE: return true; break;
-
- default:
- break;
- }
-
- return false;
- }
-
-
- //----------------------------------------------------------------------
- public function estimateBitStreamSize($version)
- {
- $bits = 0;
-
- foreach($this->items as $item) {
- $bits += $item->estimateBitStreamSizeOfEntry($version);
- }
-
- return $bits;
- }
-
- //----------------------------------------------------------------------
- public function estimateVersion()
- {
- $version = 0;
- $prev = 0;
- do {
- $prev = $version;
- $bits = $this->estimateBitStreamSize($prev);
- $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
- if ($version < 0) {
- return -1;
- }
- } while ($version > $prev);
-
- return $version;
- }
-
- //----------------------------------------------------------------------
- public static function lengthOfCode($mode, $version, $bits)
- {
- $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);
- switch($mode) {
- case QR_MODE_NUM:
- $chunks = (int)($payload / 10);
- $remain = $payload - $chunks * 10;
- $size = $chunks * 3;
- if($remain >= 7) {
- $size += 2;
- } else if($remain >= 4) {
- $size += 1;
- }
- break;
- case QR_MODE_AN:
- $chunks = (int)($payload / 11);
- $remain = $payload - $chunks * 11;
- $size = $chunks * 2;
- if($remain >= 6)
- $size++;
- break;
- case QR_MODE_8:
- $size = (int)($payload / 8);
- break;
- case QR_MODE_KANJI:
- $size = (int)(($payload / 13) * 2);
- break;
- case QR_MODE_STRUCTURE:
- $size = (int)($payload / 8);
- break;
- default:
- $size = 0;
- break;
- }
-
- $maxsize = QRspec::maximumWords($mode, $version);
- if($size < 0) $size = 0;
- if($size > $maxsize) $size = $maxsize;
-
- return $size;
- }
-
- //----------------------------------------------------------------------
- public function createBitStream()
- {
- $total = 0;
-
- foreach($this->items as $item) {
- $bits = $item->encodeBitStream($this->version);
-
- if($bits < 0)
- return -1;
-
- $total += $bits;
- }
-
- return $total;
- }
-
- //----------------------------------------------------------------------
- public function convertData()
- {
- $ver = $this->estimateVersion();
- if($ver > $this->getVersion()) {
- $this->setVersion($ver);
- }
-
- for(;;) {
- $bits = $this->createBitStream();
-
- if($bits < 0)
- return -1;
-
- $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
- if($ver < 0) {
- throw new Exception('WRONG VERSION');
- return -1;
- } else if($ver > $this->getVersion()) {
- $this->setVersion($ver);
- } else {
- break;
- }
- }
-
- return 0;
- }
-
- //----------------------------------------------------------------------
- public function appendPaddingBit(&$bstream)
- {
- $bits = $bstream->size();
- $maxwords = QRspec::getDataLength($this->version, $this->level);
- $maxbits = $maxwords * 8;
-
- if ($maxbits == $bits) {
- return 0;
- }
-
- if ($maxbits - $bits < 5) {
- return $bstream->appendNum($maxbits - $bits, 0);
- }
-
- $bits += 4;
- $words = (int)(($bits + 7) / 8);
-
- $padding = new QRbitstream();
- $ret = $padding->appendNum($words * 8 - $bits + 4, 0);
-
- if($ret < 0)
- return $ret;
-
- $padlen = $maxwords - $words;
-
- if($padlen > 0) {
-
- $padbuf = array();
- for($i=0; $i<$padlen; $i++) {
- $padbuf[$i] = ($i&1)?0x11:0xec;
- }
-
- $ret = $padding->appendBytes($padlen, $padbuf);
-
- if($ret < 0)
- return $ret;
-
- }
-
- $ret = $bstream->append($padding);
-
- return $ret;
- }
-
- //----------------------------------------------------------------------
- public function mergeBitStream()
- {
- if($this->convertData() < 0) {
- return null;
- }
-
- $bstream = new QRbitstream();
-
- foreach($this->items as $item) {
- $ret = $bstream->append($item->bstream);
- if($ret < 0) {
- return null;
- }
- }
-
- return $bstream;
- }
-
- //----------------------------------------------------------------------
- public function getBitStream()
- {
-
- $bstream = $this->mergeBitStream();
-
- if($bstream == null) {
- return null;
- }
-
- $ret = $this->appendPaddingBit($bstream);
- if($ret < 0) {
- return null;
- }
-
- return $bstream;
- }
-
- //----------------------------------------------------------------------
- public function getByteStream()
- {
- $bstream = $this->getBitStream();
- if($bstream == null) {
- return null;
- }
-
- return $bstream->toByte();
- }
- }
-
-
-
\ No newline at end of file
diff --git a/lib/phpqrcode/qrlib.php b/lib/phpqrcode/qrlib.php
deleted file mode 100644
index d55c4af29..000000000
--- a/lib/phpqrcode/qrlib.php
+++ /dev/null
@@ -1,43 +0,0 @@
-
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- $QR_BASEDIR = dirname(__FILE__).DIRECTORY_SEPARATOR;
-
- // Required libs
-
- include $QR_BASEDIR."qrconst.php";
- include $QR_BASEDIR."qrconfig.php";
- include $QR_BASEDIR."qrtools.php";
- include $QR_BASEDIR."qrspec.php";
- include $QR_BASEDIR."qrimage.php";
- include $QR_BASEDIR."qrinput.php";
- include $QR_BASEDIR."qrbitstream.php";
- include $QR_BASEDIR."qrsplit.php";
- include $QR_BASEDIR."qrrscode.php";
- include $QR_BASEDIR."qrmask.php";
- include $QR_BASEDIR."qrencode.php";
-
diff --git a/lib/phpqrcode/qrmask.php b/lib/phpqrcode/qrmask.php
deleted file mode 100644
index 43d653ce3..000000000
--- a/lib/phpqrcode/qrmask.php
+++ /dev/null
@@ -1,328 +0,0 @@
-
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- define('N1', 3);
- define('N2', 3);
- define('N3', 40);
- define('N4', 10);
-
- class QRmask {
-
- public $runLength = array();
-
- //----------------------------------------------------------------------
- public function __construct()
- {
- $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);
- }
-
- //----------------------------------------------------------------------
- public function writeFormatInformation($width, &$frame, $mask, $level)
- {
- $blacks = 0;
- $format = QRspec::getFormatInfo($mask, $level);
-
- for($i=0; $i<8; $i++) {
- if($format & 1) {
- $blacks += 2;
- $v = 0x85;
- } else {
- $v = 0x84;
- }
-
- $frame[8][$width - 1 - $i] = chr($v);
- if($i < 6) {
- $frame[$i][8] = chr($v);
- } else {
- $frame[$i + 1][8] = chr($v);
- }
- $format = $format >> 1;
- }
-
- for($i=0; $i<7; $i++) {
- if($format & 1) {
- $blacks += 2;
- $v = 0x85;
- } else {
- $v = 0x84;
- }
-
- $frame[$width - 7 + $i][8] = chr($v);
- if($i == 0) {
- $frame[8][7] = chr($v);
- } else {
- $frame[8][6 - $i] = chr($v);
- }
-
- $format = $format >> 1;
- }
-
- return $blacks;
- }
-
- //----------------------------------------------------------------------
- public function mask0($x, $y) { return ($x+$y)&1; }
- public function mask1($x, $y) { return ($y&1); }
- public function mask2($x, $y) { return ($x%3); }
- public function mask3($x, $y) { return ($x+$y)%3; }
- public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; }
- public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3; }
- public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1; }
- public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1; }
-
- //----------------------------------------------------------------------
- private function generateMaskNo($maskNo, $width, $frame)
- {
- $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
-
- for($y=0; $y<$width; $y++) {
- for($x=0; $x<$width; $x++) {
- if(ord($frame[$y][$x]) & 0x80) {
- $bitMask[$y][$x] = 0;
- } else {
- $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y);
- $bitMask[$y][$x] = ($maskFunc == 0)?1:0;
- }
-
- }
- }
-
- return $bitMask;
- }
-
- //----------------------------------------------------------------------
- public static function serial($bitFrame)
- {
- $codeArr = array();
-
- foreach ($bitFrame as $line)
- $codeArr[] = join('', $line);
-
- return gzcompress(join("\n", $codeArr), 9);
- }
-
- //----------------------------------------------------------------------
- public static function unserial($code)
- {
- $codeArr = array();
-
- $codeLines = explode("\n", gzuncompress($code));
- foreach ($codeLines as $line)
- $codeArr[] = str_split($line);
-
- return $codeArr;
- }
-
- //----------------------------------------------------------------------
- public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false)
- {
- $b = 0;
- $bitMask = array();
-
- $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat';
-
- if (QR_CACHEABLE) {
- if (file_exists($fileName)) {
- $bitMask = self::unserial(file_get_contents($fileName));
- } else {
- $bitMask = $this->generateMaskNo($maskNo, $width, $s);
- if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo))
- mkdir(QR_CACHE_DIR.'mask_'.$maskNo);
- file_put_contents($fileName, self::serial($bitMask));
- }
- } else {
- $bitMask = $this->generateMaskNo($maskNo, $width, $s);
- }
-
- if ($maskGenOnly)
- return;
-
- $d = $s;
-
- for($y=0; $y<$width; $y++) {
- for($x=0; $x<$width; $x++) {
- if($bitMask[$y][$x] == 1) {
- $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]);
- }
- $b += (int)(ord($d[$y][$x]) & 1);
- }
- }
-
- return $b;
- }
-
- //----------------------------------------------------------------------
- public function makeMask($width, $frame, $maskNo, $level)
- {
- $masked = array_fill(0, $width, str_repeat("\0", $width));
- $this->makeMaskNo($maskNo, $width, $frame, $masked);
- $this->writeFormatInformation($width, $masked, $maskNo, $level);
-
- return $masked;
- }
-
- //----------------------------------------------------------------------
- public function calcN1N3($length)
- {
- $demerit = 0;
-
- for($i=0; $i<$length; $i++) {
-
- if($this->runLength[$i] >= 5) {
- $demerit += (N1 + ($this->runLength[$i] - 5));
- }
- if($i & 1) {
- if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) {
- $fact = (int)($this->runLength[$i] / 3);
- if(($this->runLength[$i-2] == $fact) &&
- ($this->runLength[$i-1] == $fact) &&
- ($this->runLength[$i+1] == $fact) &&
- ($this->runLength[$i+2] == $fact)) {
- if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) {
- $demerit += N3;
- } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) {
- $demerit += N3;
- }
- }
- }
- }
- }
- return $demerit;
- }
-
- //----------------------------------------------------------------------
- public function evaluateSymbol($width, $frame)
- {
- $head = 0;
- $demerit = 0;
-
- for($y=0; $y<$width; $y++) {
- $head = 0;
- $this->runLength[0] = 1;
-
- $frameY = $frame[$y];
-
- if ($y>0)
- $frameYM = $frame[$y-1];
-
- for($x=0; $x<$width; $x++) {
- if(($x > 0) && ($y > 0)) {
- $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);
- $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);
-
- if(($b22 | ($w22 ^ 1))&1) {
- $demerit += N2;
- }
- }
- if(($x == 0) && (ord($frameY[$x]) & 1)) {
- $this->runLength[0] = -1;
- $head = 1;
- $this->runLength[$head] = 1;
- } else if($x > 0) {
- if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) {
- $head++;
- $this->runLength[$head] = 1;
- } else {
- $this->runLength[$head]++;
- }
- }
- }
-
- $demerit += $this->calcN1N3($head+1);
- }
-
- for($x=0; $x<$width; $x++) {
- $head = 0;
- $this->runLength[0] = 1;
-
- for($y=0; $y<$width; $y++) {
- if($y == 0 && (ord($frame[$y][$x]) & 1)) {
- $this->runLength[0] = -1;
- $head = 1;
- $this->runLength[$head] = 1;
- } else if($y > 0) {
- if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) {
- $head++;
- $this->runLength[$head] = 1;
- } else {
- $this->runLength[$head]++;
- }
- }
- }
-
- $demerit += $this->calcN1N3($head+1);
- }
-
- return $demerit;
- }
-
-
- //----------------------------------------------------------------------
- public function mask($width, $frame, $level)
- {
- $minDemerit = PHP_INT_MAX;
- $bestMaskNum = 0;
- $bestMask = array();
-
- $checked_masks = array(0,1,2,3,4,5,6,7);
-
- if (QR_FIND_FROM_RANDOM !== false) {
-
- $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9);
- for ($i = 0; $i < $howManuOut; $i++) {
- $remPos = rand (0, count($checked_masks)-1);
- unset($checked_masks[$remPos]);
- $checked_masks = array_values($checked_masks);
- }
-
- }
-
- $bestMask = $frame;
-
- foreach($checked_masks as $i) {
- $mask = array_fill(0, $width, str_repeat("\0", $width));
-
- $demerit = 0;
- $blacks = 0;
- $blacks = $this->makeMaskNo($i, $width, $frame, $mask);
- $blacks += $this->writeFormatInformation($width, $mask, $i, $level);
- $blacks = (int)(100 * $blacks / ($width * $width));
- $demerit = (int)((int)(abs($blacks - 50) / 5) * N4);
- $demerit += $this->evaluateSymbol($width, $mask);
-
- if($demerit < $minDemerit) {
- $minDemerit = $demerit;
- $bestMask = $mask;
- $bestMaskNum = $i;
- }
- }
-
- return $bestMask;
- }
-
- //----------------------------------------------------------------------
- }
diff --git a/lib/phpqrcode/qrrscode.php b/lib/phpqrcode/qrrscode.php
deleted file mode 100644
index 591129a32..000000000
--- a/lib/phpqrcode/qrrscode.php
+++ /dev/null
@@ -1,210 +0,0 @@
-
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- class QRrsItem {
-
- public $mm; // Bits per symbol
- public $nn; // Symbols per block (= (1<= $this->nn) {
- $x -= $this->nn;
- $x = ($x >> $this->mm) + ($x & $this->nn);
- }
-
- return $x;
- }
-
- //----------------------------------------------------------------------
- public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
- {
- // Common code for intializing a Reed-Solomon control block (char or int symbols)
- // Copyright 2004 Phil Karn, KA9Q
- // May be used under the terms of the GNU Lesser General Public License (LGPL)
-
- $rs = null;
-
- // Check parameter ranges
- if($symsize < 0 || $symsize > 8) return $rs;
- if($fcr < 0 || $fcr >= (1<<$symsize)) return $rs;
- if($prim <= 0 || $prim >= (1<<$symsize)) return $rs;
- if($nroots < 0 || $nroots >= (1<<$symsize)) return $rs; // Can't have more roots than symbol values!
- if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding
-
- $rs = new QRrsItem();
- $rs->mm = $symsize;
- $rs->nn = (1<<$symsize)-1;
- $rs->pad = $pad;
-
- $rs->alpha_to = array_fill(0, $rs->nn+1, 0);
- $rs->index_of = array_fill(0, $rs->nn+1, 0);
-
- // PHP style macro replacement ;)
- $NN =& $rs->nn;
- $A0 =& $NN;
-
- // Generate Galois field lookup tables
- $rs->index_of[0] = $A0; // log(zero) = -inf
- $rs->alpha_to[$A0] = 0; // alpha**-inf = 0
- $sr = 1;
-
- for($i=0; $i<$rs->nn; $i++) {
- $rs->index_of[$sr] = $i;
- $rs->alpha_to[$i] = $sr;
- $sr <<= 1;
- if($sr & (1<<$symsize)) {
- $sr ^= $gfpoly;
- }
- $sr &= $rs->nn;
- }
-
- if($sr != 1){
- // field generator polynomial is not primitive!
- $rs = NULL;
- return $rs;
- }
-
- /* Form RS code generator polynomial from its roots */
- $rs->genpoly = array_fill(0, $nroots+1, 0);
-
- $rs->fcr = $fcr;
- $rs->prim = $prim;
- $rs->nroots = $nroots;
- $rs->gfpoly = $gfpoly;
-
- /* Find prim-th root of 1, used in decoding */
- for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn)
- ; // intentional empty-body loop!
-
- $rs->iprim = (int)($iprim / $prim);
- $rs->genpoly[0] = 1;
-
- for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) {
- $rs->genpoly[$i+1] = 1;
-
- // Multiply rs->genpoly[] by @**(root + x)
- for ($j = $i; $j > 0; $j--) {
- if ($rs->genpoly[$j] != 0) {
- $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)];
- } else {
- $rs->genpoly[$j] = $rs->genpoly[$j-1];
- }
- }
- // rs->genpoly[0] can never be zero
- $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)];
- }
-
- // convert rs->genpoly[] to index form for quicker encoding
- for ($i = 0; $i <= $nroots; $i++)
- $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]];
-
- return $rs;
- }
-
- //----------------------------------------------------------------------
- public function encode_rs_char($data, &$parity)
- {
- $MM =& $this->mm;
- $NN =& $this->nn;
- $ALPHA_TO =& $this->alpha_to;
- $INDEX_OF =& $this->index_of;
- $GENPOLY =& $this->genpoly;
- $NROOTS =& $this->nroots;
- $FCR =& $this->fcr;
- $PRIM =& $this->prim;
- $IPRIM =& $this->iprim;
- $PAD =& $this->pad;
- $A0 =& $NN;
-
- $parity = array_fill(0, $NROOTS, 0);
-
- for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) {
-
- $feedback = $INDEX_OF[$data[$i] ^ $parity[0]];
- if($feedback != $A0) {
- // feedback term is non-zero
-
- // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
- // always be for the polynomials constructed by init_rs()
- $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback);
-
- for($j=1;$j<$NROOTS;$j++) {
- $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])];
- }
- }
-
- // Shift
- array_shift($parity);
- if($feedback != $A0) {
- array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]);
- } else {
- array_push($parity, 0);
- }
- }
- }
- }
-
- //##########################################################################
-
- class QRrs {
-
- public static $items = array();
-
- //----------------------------------------------------------------------
- public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
- {
- foreach(self::$items as $rs) {
- if($rs->pad != $pad) continue;
- if($rs->nroots != $nroots) continue;
- if($rs->mm != $symsize) continue;
- if($rs->gfpoly != $gfpoly) continue;
- if($rs->fcr != $fcr) continue;
- if($rs->prim != $prim) continue;
-
- return $rs;
- }
-
- $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
- array_unshift(self::$items, $rs);
-
- return $rs;
- }
- }
\ No newline at end of file
diff --git a/lib/phpqrcode/qrspec.php b/lib/phpqrcode/qrspec.php
deleted file mode 100644
index 92aea0c78..000000000
--- a/lib/phpqrcode/qrspec.php
+++ /dev/null
@@ -1,592 +0,0 @@
-
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * The following data / specifications are taken from
- * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
- * or
- * "Automatic identification and data capture techniques --
- * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- define('QRSPEC_VERSION_MAX', 40);
- define('QRSPEC_WIDTH_MAX', 177);
-
- define('QRCAP_WIDTH', 0);
- define('QRCAP_WORDS', 1);
- define('QRCAP_REMINDER', 2);
- define('QRCAP_EC', 3);
-
- class QRspec {
-
- public static $capacity = array(
- array( 0, 0, 0, array( 0, 0, 0, 0)),
- array( 21, 26, 0, array( 7, 10, 13, 17)), // 1
- array( 25, 44, 7, array( 10, 16, 22, 28)),
- array( 29, 70, 7, array( 15, 26, 36, 44)),
- array( 33, 100, 7, array( 20, 36, 52, 64)),
- array( 37, 134, 7, array( 26, 48, 72, 88)), // 5
- array( 41, 172, 7, array( 36, 64, 96, 112)),
- array( 45, 196, 0, array( 40, 72, 108, 130)),
- array( 49, 242, 0, array( 48, 88, 132, 156)),
- array( 53, 292, 0, array( 60, 110, 160, 192)),
- array( 57, 346, 0, array( 72, 130, 192, 224)), //10
- array( 61, 404, 0, array( 80, 150, 224, 264)),
- array( 65, 466, 0, array( 96, 176, 260, 308)),
- array( 69, 532, 0, array( 104, 198, 288, 352)),
- array( 73, 581, 3, array( 120, 216, 320, 384)),
- array( 77, 655, 3, array( 132, 240, 360, 432)), //15
- array( 81, 733, 3, array( 144, 280, 408, 480)),
- array( 85, 815, 3, array( 168, 308, 448, 532)),
- array( 89, 901, 3, array( 180, 338, 504, 588)),
- array( 93, 991, 3, array( 196, 364, 546, 650)),
- array( 97, 1085, 3, array( 224, 416, 600, 700)), //20
- array(101, 1156, 4, array( 224, 442, 644, 750)),
- array(105, 1258, 4, array( 252, 476, 690, 816)),
- array(109, 1364, 4, array( 270, 504, 750, 900)),
- array(113, 1474, 4, array( 300, 560, 810, 960)),
- array(117, 1588, 4, array( 312, 588, 870, 1050)), //25
- array(121, 1706, 4, array( 336, 644, 952, 1110)),
- array(125, 1828, 4, array( 360, 700, 1020, 1200)),
- array(129, 1921, 3, array( 390, 728, 1050, 1260)),
- array(133, 2051, 3, array( 420, 784, 1140, 1350)),
- array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30
- array(141, 2323, 3, array( 480, 868, 1290, 1530)),
- array(145, 2465, 3, array( 510, 924, 1350, 1620)),
- array(149, 2611, 3, array( 540, 980, 1440, 1710)),
- array(153, 2761, 3, array( 570, 1036, 1530, 1800)),
- array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35
- array(161, 3034, 0, array( 600, 1120, 1680, 1980)),
- array(165, 3196, 0, array( 630, 1204, 1770, 2100)),
- array(169, 3362, 0, array( 660, 1260, 1860, 2220)),
- array(173, 3532, 0, array( 720, 1316, 1950, 2310)),
- array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40
- );
-
- //----------------------------------------------------------------------
- public static function getDataLength($version, $level)
- {
- return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];
- }
-
- //----------------------------------------------------------------------
- public static function getECCLength($version, $level)
- {
- return self::$capacity[$version][QRCAP_EC][$level];
- }
-
- //----------------------------------------------------------------------
- public static function getWidth($version)
- {
- return self::$capacity[$version][QRCAP_WIDTH];
- }
-
- //----------------------------------------------------------------------
- public static function getRemainder($version)
- {
- return self::$capacity[$version][QRCAP_REMINDER];
- }
-
- //----------------------------------------------------------------------
- public static function getMinimumVersion($size, $level)
- {
-
- for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) {
- $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];
- if($words >= $size)
- return $i;
- }
-
- return -1;
- }
-
- //######################################################################
-
- public static $lengthTableBits = array(
- array(10, 12, 14),
- array( 9, 11, 13),
- array( 8, 16, 16),
- array( 8, 10, 12)
- );
-
- //----------------------------------------------------------------------
- public static function lengthIndicator($mode, $version)
- {
- if ($mode == QR_MODE_STRUCTURE)
- return 0;
-
- if ($version <= 9) {
- $l = 0;
- } else if ($version <= 26) {
- $l = 1;
- } else {
- $l = 2;
- }
-
- return self::$lengthTableBits[$mode][$l];
- }
-
- //----------------------------------------------------------------------
- public static function maximumWords($mode, $version)
- {
- if($mode == QR_MODE_STRUCTURE)
- return 3;
-
- if($version <= 9) {
- $l = 0;
- } else if($version <= 26) {
- $l = 1;
- } else {
- $l = 2;
- }
-
- $bits = self::$lengthTableBits[$mode][$l];
- $words = (1 << $bits) - 1;
-
- if($mode == QR_MODE_KANJI) {
- $words *= 2; // the number of bytes is required
- }
-
- return $words;
- }
-
- // Error correction code -----------------------------------------------
- // Table of the error correction code (Reed-Solomon block)
- // See Table 12-16 (pp.30-36), JIS X0510:2004.
-
- public static $eccTable = array(
- array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)),
- array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1
- array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)),
- array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)),
- array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)),
- array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5
- array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)),
- array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)),
- array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)),
- array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)),
- array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10
- array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)),
- array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)),
- array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)),
- array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)),
- array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15
- array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)),
- array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)),
- array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)),
- array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)),
- array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20
- array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)),
- array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)),
- array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)),
- array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)),
- array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), //25
- array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)),
- array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)),
- array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),
- array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)),
- array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30
- array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)),
- array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)),
- array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)),
- array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)),
- array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35
- array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),
- array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)),
- array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),
- array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)),
- array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40
- );
-
- //----------------------------------------------------------------------
- // CACHEABLE!!!
-
- public static function getEccSpec($version, $level, array &$spec)
- {
- if (count($spec) < 5) {
- $spec = array(0,0,0,0,0);
- }
-
- $b1 = self::$eccTable[$version][$level][0];
- $b2 = self::$eccTable[$version][$level][1];
- $data = self::getDataLength($version, $level);
- $ecc = self::getECCLength($version, $level);
-
- if($b2 == 0) {
- $spec[0] = $b1;
- $spec[1] = (int)($data / $b1);
- $spec[2] = (int)($ecc / $b1);
- $spec[3] = 0;
- $spec[4] = 0;
- } else {
- $spec[0] = $b1;
- $spec[1] = (int)($data / ($b1 + $b2));
- $spec[2] = (int)($ecc / ($b1 + $b2));
- $spec[3] = $b2;
- $spec[4] = $spec[1] + 1;
- }
- }
-
- // Alignment pattern ---------------------------------------------------
-
- // Positions of alignment patterns.
- // This array includes only the second and the third position of the
- // alignment patterns. Rest of them can be calculated from the distance
- // between them.
-
- // See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
-
- public static $alignmentPattern = array(
- array( 0, 0),
- array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5
- array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10
- array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15
- array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20
- array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25
- array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30
- array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35
- array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40
- );
-
-
- /** --------------------------------------------------------------------
- * Put an alignment marker.
- * @param frame
- * @param width
- * @param ox,oy center coordinate of the pattern
- */
- public static function putAlignmentMarker(array &$frame, $ox, $oy)
- {
- $finder = array(
- "\xa1\xa1\xa1\xa1\xa1",
- "\xa1\xa0\xa0\xa0\xa1",
- "\xa1\xa0\xa1\xa0\xa1",
- "\xa1\xa0\xa0\xa0\xa1",
- "\xa1\xa1\xa1\xa1\xa1"
- );
-
- $yStart = $oy-2;
- $xStart = $ox-2;
-
- for($y=0; $y<5; $y++) {
- QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]);
- }
- }
-
- //----------------------------------------------------------------------
- public static function putAlignmentPattern($version, &$frame, $width)
- {
- if($version < 2)
- return;
-
- $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];
- if($d < 0) {
- $w = 2;
- } else {
- $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2);
- }
-
- if($w * $w - 3 == 1) {
- $x = self::$alignmentPattern[$version][0];
- $y = self::$alignmentPattern[$version][0];
- self::putAlignmentMarker($frame, $x, $y);
- return;
- }
-
- $cx = self::$alignmentPattern[$version][0];
- for($x=1; $x<$w - 1; $x++) {
- self::putAlignmentMarker($frame, 6, $cx);
- self::putAlignmentMarker($frame, $cx, 6);
- $cx += $d;
- }
-
- $cy = self::$alignmentPattern[$version][0];
- for($y=0; $y<$w-1; $y++) {
- $cx = self::$alignmentPattern[$version][0];
- for($x=0; $x<$w-1; $x++) {
- self::putAlignmentMarker($frame, $cx, $cy);
- $cx += $d;
- }
- $cy += $d;
- }
- }
-
- // Version information pattern -----------------------------------------
-
- // Version information pattern (BCH coded).
- // See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
-
- // size: [QRSPEC_VERSION_MAX - 6]
-
- public static $versionPattern = array(
- 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
- 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
- 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
- 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
- 0x27541, 0x28c69
- );
-
- //----------------------------------------------------------------------
- public static function getVersionPattern($version)
- {
- if($version < 7 || $version > QRSPEC_VERSION_MAX)
- return 0;
-
- return self::$versionPattern[$version -7];
- }
-
- // Format information --------------------------------------------------
- // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)
-
- public static $formatInfo = array(
- array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),
- array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),
- array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),
- array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)
- );
-
- public static function getFormatInfo($mask, $level)
- {
- if($mask < 0 || $mask > 7)
- return 0;
-
- if($level < 0 || $level > 3)
- return 0;
-
- return self::$formatInfo[$level][$mask];
- }
-
- // Frame ---------------------------------------------------------------
- // Cache of initial frames.
-
- public static $frames = array();
-
- /** --------------------------------------------------------------------
- * Put a finder pattern.
- * @param frame
- * @param width
- * @param ox,oy upper-left coordinate of the pattern
- */
- public static function putFinderPattern(&$frame, $ox, $oy)
- {
- $finder = array(
- "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
- "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
- "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
- "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
- "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
- "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
- "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
- );
-
- for($y=0; $y<7; $y++) {
- QRstr::set($frame, $ox, $oy+$y, $finder[$y]);
- }
- }
-
- //----------------------------------------------------------------------
- public static function createFrame($version)
- {
- $width = self::$capacity[$version][QRCAP_WIDTH];
- $frameLine = str_repeat ("\0", $width);
- $frame = array_fill(0, $width, $frameLine);
-
- // Finder pattern
- self::putFinderPattern($frame, 0, 0);
- self::putFinderPattern($frame, $width - 7, 0);
- self::putFinderPattern($frame, 0, $width - 7);
-
- // Separator
- $yOffset = $width - 7;
-
- for($y=0; $y<7; $y++) {
- $frame[$y][7] = "\xc0";
- $frame[$y][$width - 8] = "\xc0";
- $frame[$yOffset][7] = "\xc0";
- $yOffset++;
- }
-
- $setPattern = str_repeat("\xc0", 8);
-
- QRstr::set($frame, 0, 7, $setPattern);
- QRstr::set($frame, $width-8, 7, $setPattern);
- QRstr::set($frame, 0, $width - 8, $setPattern);
-
- // Format info
- $setPattern = str_repeat("\x84", 9);
- QRstr::set($frame, 0, 8, $setPattern);
- QRstr::set($frame, $width - 8, 8, $setPattern, 8);
-
- $yOffset = $width - 8;
-
- for($y=0; $y<8; $y++,$yOffset++) {
- $frame[$y][8] = "\x84";
- $frame[$yOffset][8] = "\x84";
- }
-
- // Timing pattern
-
- for($i=1; $i<$width-15; $i++) {
- $frame[6][7+$i] = chr(0x90 | ($i & 1));
- $frame[7+$i][6] = chr(0x90 | ($i & 1));
- }
-
- // Alignment pattern
- self::putAlignmentPattern($version, $frame, $width);
-
- // Version information
- if($version >= 7) {
- $vinf = self::getVersionPattern($version);
-
- $v = $vinf;
-
- for($x=0; $x<6; $x++) {
- for($y=0; $y<3; $y++) {
- $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1));
- $v = $v >> 1;
- }
- }
-
- $v = $vinf;
- for($y=0; $y<6; $y++) {
- for($x=0; $x<3; $x++) {
- $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1));
- $v = $v >> 1;
- }
- }
- }
-
- // and a little bit...
- $frame[$width - 8][8] = "\x81";
-
- return $frame;
- }
-
- //----------------------------------------------------------------------
- public static function debug($frame, $binary_mode = false)
- {
- if ($binary_mode) {
-
- foreach ($frame as &$frameLine) {
- $frameLine = join(' ', explode('0', $frameLine));
- $frameLine = join('██', explode('1', $frameLine));
- }
-
- ?>
-
-
';
- echo join("
", $frame);
- echo '
';
-
- } else {
-
- foreach ($frame as &$frameLine) {
- $frameLine = join(' ', explode("\xc0", $frameLine));
- $frameLine = join('▒', explode("\xc1", $frameLine));
- $frameLine = join(' ', explode("\xa0", $frameLine));
- $frameLine = join('▒', explode("\xa1", $frameLine));
- $frameLine = join('◇', explode("\x84", $frameLine)); //format 0
- $frameLine = join('◆', explode("\x85", $frameLine)); //format 1
- $frameLine = join('☢', explode("\x81", $frameLine)); //special bit
- $frameLine = join(' ', explode("\x90", $frameLine)); //clock 0
- $frameLine = join('◷', explode("\x91", $frameLine)); //clock 1
- $frameLine = join(' ', explode("\x88", $frameLine)); //version
- $frameLine = join('▒', explode("\x89", $frameLine)); //version
- $frameLine = join('♦', explode("\x01", $frameLine));
- $frameLine = join('⋅', explode("\0", $frameLine));
- }
-
- ?>
-
- ";
- echo join("
", $frame);
- echo "";
-
- }
- }
-
- //----------------------------------------------------------------------
- public static function serial($frame)
- {
- return gzcompress(join("\n", $frame), 9);
- }
-
- //----------------------------------------------------------------------
- public static function unserial($code)
- {
- return explode("\n", gzuncompress($code));
- }
-
- //----------------------------------------------------------------------
- public static function newFrame($version)
- {
- if($version < 1 || $version > QRSPEC_VERSION_MAX)
- return null;
-
- if(!isset(self::$frames[$version])) {
-
- $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat';
-
- if (QR_CACHEABLE) {
- if (file_exists($fileName)) {
- self::$frames[$version] = self::unserial(file_get_contents($fileName));
- } else {
- self::$frames[$version] = self::createFrame($version);
- file_put_contents($fileName, self::serial(self::$frames[$version]));
- }
- } else {
- self::$frames[$version] = self::createFrame($version);
- }
- }
-
- if(is_null(self::$frames[$version]))
- return null;
-
- return self::$frames[$version];
- }
-
- //----------------------------------------------------------------------
- public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; }
- public static function rsBlockNum1($spec) { return $spec[0]; }
- public static function rsDataCodes1($spec) { return $spec[1]; }
- public static function rsEccCodes1($spec) { return $spec[2]; }
- public static function rsBlockNum2($spec) { return $spec[3]; }
- public static function rsDataCodes2($spec) { return $spec[4]; }
- public static function rsEccCodes2($spec) { return $spec[2]; }
- public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); }
- public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; }
-
- }
\ No newline at end of file
diff --git a/lib/phpqrcode/qrsplit.php b/lib/phpqrcode/qrsplit.php
deleted file mode 100644
index 1f9f65c3b..000000000
--- a/lib/phpqrcode/qrsplit.php
+++ /dev/null
@@ -1,311 +0,0 @@
-
- *
- * PHP QR Code is distributed under LGPL 3
- * Copyright (C) 2010 Dominik Dzienia
- *
- * The following data / specifications are taken from
- * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
- * or
- * "Automatic identification and data capture techniques --
- * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- class QRsplit {
-
- public $dataStr = '';
- public $input;
- public $modeHint;
-
- //----------------------------------------------------------------------
- public function __construct($dataStr, $input, $modeHint)
- {
- $this->dataStr = $dataStr;
- $this->input = $input;
- $this->modeHint = $modeHint;
- }
-
- //----------------------------------------------------------------------
- public static function isdigitat($str, $pos)
- {
- if ($pos >= strlen($str))
- return false;
-
- return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9')));
- }
-
- //----------------------------------------------------------------------
- public static function isalnumat($str, $pos)
- {
- if ($pos >= strlen($str))
- return false;
-
- return (QRinput::lookAnTable(ord($str[$pos])) >= 0);
- }
-
- //----------------------------------------------------------------------
- public function identifyMode($pos)
- {
- if ($pos >= strlen($this->dataStr))
- return QR_MODE_NUL;
-
- $c = $this->dataStr[$pos];
-
- if(self::isdigitat($this->dataStr, $pos)) {
- return QR_MODE_NUM;
- } else if(self::isalnumat($this->dataStr, $pos)) {
- return QR_MODE_AN;
- } else if($this->modeHint == QR_MODE_KANJI) {
-
- if ($pos+1 < strlen($this->dataStr))
- {
- $d = $this->dataStr[$pos+1];
- $word = (ord($c) << 8) | ord($d);
- if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {
- return QR_MODE_KANJI;
- }
- }
- }
-
- return QR_MODE_8;
- }
-
- //----------------------------------------------------------------------
- public function eatNum()
- {
- $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
- $p = 0;
- while(self::isdigitat($this->dataStr, $p)) {
- $p++;
- }
-
- $run = $p;
- $mode = $this->identifyMode($p);
-
- if($mode == QR_MODE_8) {
- $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
- + QRinput::estimateBitsMode8(1) // + 4 + l8
- - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
- if($dif > 0) {
- return $this->eat8();
- }
- }
- if($mode == QR_MODE_AN) {
- $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
- + QRinput::estimateBitsModeAn(1) // + 4 + la
- - QRinput::estimateBitsModeAn($run + 1);// - 4 - la
- if($dif > 0) {
- return $this->eatAn();
- }
- }
-
- $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));
- if($ret < 0)
- return -1;
-
- return $run;
- }
-
- //----------------------------------------------------------------------
- public function eatAn()
- {
- $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
- $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
- $p = 0;
-
- while(self::isalnumat($this->dataStr, $p)) {
- if(self::isdigitat($this->dataStr, $p)) {
- $q = $p;
- while(self::isdigitat($this->dataStr, $q)) {
- $q++;
- }
-
- $dif = QRinput::estimateBitsModeAn($p) // + 4 + la
- + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
- - QRinput::estimateBitsModeAn($q); // - 4 - la
-
- if($dif < 0) {
- break;
- } else {
- $p = $q;
- }
- } else {
- $p++;
- }
- }
-
- $run = $p;
-
- if(!self::isalnumat($this->dataStr, $p)) {
- $dif = QRinput::estimateBitsModeAn($run) + 4 + $la
- + QRinput::estimateBitsMode8(1) // + 4 + l8
- - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
- if($dif > 0) {
- return $this->eat8();
- }
- }
-
- $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));
- if($ret < 0)
- return -1;
-
- return $run;
- }
-
- //----------------------------------------------------------------------
- public function eatKanji()
- {
- $p = 0;
-
- while($this->identifyMode($p) == QR_MODE_KANJI) {
- $p += 2;
- }
-
- $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));
- if($ret < 0)
- return -1;
-
- return $ret;
- }
-
- //----------------------------------------------------------------------
- public function eat8()
- {
- $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
- $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
-
- $p = 1;
- $dataStrLen = strlen($this->dataStr);
-
- while($p < $dataStrLen) {
-
- $mode = $this->identifyMode($p);
- if($mode == QR_MODE_KANJI) {
- break;
- }
- if($mode == QR_MODE_NUM) {
- $q = $p;
- while(self::isdigitat($this->dataStr, $q)) {
- $q++;
- }
- $dif = QRinput::estimateBitsMode8($p) // + 4 + l8
- + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
- - QRinput::estimateBitsMode8($q); // - 4 - l8
- if($dif < 0) {
- break;
- } else {
- $p = $q;
- }
- } else if($mode == QR_MODE_AN) {
- $q = $p;
- while(self::isalnumat($this->dataStr, $q)) {
- $q++;
- }
- $dif = QRinput::estimateBitsMode8($p) // + 4 + l8
- + QRinput::estimateBitsModeAn($q - $p) + 4 + $la
- - QRinput::estimateBitsMode8($q); // - 4 - l8
- if($dif < 0) {
- break;
- } else {
- $p = $q;
- }
- } else {
- $p++;
- }
- }
-
- $run = $p;
- $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));
-
- if($ret < 0)
- return -1;
-
- return $run;
- }
-
- //----------------------------------------------------------------------
- public function splitString()
- {
- while (strlen($this->dataStr) > 0)
- {
- if($this->dataStr == '')
- return 0;
-
- $mode = $this->identifyMode(0);
-
- switch ($mode) {
- case QR_MODE_NUM: $length = $this->eatNum(); break;
- case QR_MODE_AN: $length = $this->eatAn(); break;
- case QR_MODE_KANJI:
- if ($this->modeHint == QR_MODE_KANJI)
- $length = $this->eatKanji();
- else $length = $this->eat8();
- break;
- default: $length = $this->eat8(); break;
-
- }
-
- if($length == 0) return 0;
- if($length < 0) return -1;
-
- $this->dataStr = substr($this->dataStr, $length);
- }
- }
-
- //----------------------------------------------------------------------
- public function toUpper()
- {
- $stringLen = strlen($this->dataStr);
- $p = 0;
-
- while ($p<$stringLen) {
- $mode = self::identifyMode(substr($this->dataStr, $p));
- if($mode == QR_MODE_KANJI) {
- $p += 2;
- } else {
- if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) {
- $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
- }
- $p++;
- }
- }
-
- return $this->dataStr;
- }
-
- //----------------------------------------------------------------------
- public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)
- {
- if(is_null($string) || $string == '\0' || $string == '') {
- throw new Exception('empty string!!!');
- }
-
- $split = new QRsplit($string, $input, $modeHint);
-
- if(!$casesensitive)
- $split->toUpper();
-
- return $split->splitString();
- }
- }
diff --git a/lib/phpqrcode/qrtools.php b/lib/phpqrcode/qrtools.php
deleted file mode 100644
index 3012db493..000000000
--- a/lib/phpqrcode/qrtools.php
+++ /dev/null
@@ -1,172 +0,0 @@
-
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- class QRtools {
-
- //----------------------------------------------------------------------
- public static function binarize($frame)
- {
- $len = count($frame);
- foreach ($frame as &$frameLine) {
-
- for($i=0; $i<$len; $i++) {
- $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0';
- }
- }
-
- return $frame;
- }
-
- //----------------------------------------------------------------------
- public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037')
- {
- $barcode_array = array();
-
- if (!is_array($mode))
- $mode = explode(',', $mode);
-
- $eccLevel = 'L';
-
- if (count($mode) > 1) {
- $eccLevel = $mode[1];
- }
-
- $qrTab = QRcode::text($code, false, $eccLevel);
- $size = count($qrTab);
-
- $barcode_array['num_rows'] = $size;
- $barcode_array['num_cols'] = $size;
- $barcode_array['bcode'] = array();
-
- foreach ($qrTab as $line) {
- $arrAdd = array();
- foreach(str_split($line) as $char)
- $arrAdd[] = ($char=='1')?1:0;
- $barcode_array['bcode'][] = $arrAdd;
- }
-
- return $barcode_array;
- }
-
- //----------------------------------------------------------------------
- public static function clearCache()
- {
- self::$frames = array();
- }
-
- //----------------------------------------------------------------------
- public static function buildCache()
- {
- QRtools::markTime('before_build_cache');
-
- $mask = new QRmask();
- for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) {
- $frame = QRspec::newFrame($a);
- if (QR_IMAGE) {
- $fileName = QR_CACHE_DIR.'frame_'.$a.'.png';
- QRimage::png(self::binarize($frame), $fileName, 1, 0);
- }
-
- $width = count($frame);
- $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
- for ($maskNo=0; $maskNo<8; $maskNo++)
- $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);
- }
-
- QRtools::markTime('after_build_cache');
- }
-
- //----------------------------------------------------------------------
- public static function log($outfile, $err)
- {
- if (QR_LOG_DIR !== false) {
- if ($err != '') {
- if ($outfile !== false) {
- file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
- } else {
- file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
- }
- }
- }
- }
-
- //----------------------------------------------------------------------
- public static function dumpMask($frame)
- {
- $width = count($frame);
- for($y=0;$y<$width;$y++) {
- for($x=0;$x<$width;$x++) {
- echo ord($frame[$y][$x]).',';
- }
- }
- }
-
- //----------------------------------------------------------------------
- public static function markTime($markerId)
- {
- list($usec, $sec) = explode(" ", microtime());
- $time = ((float)$usec + (float)$sec);
-
- if (!isset($GLOBALS['qr_time_bench']))
- $GLOBALS['qr_time_bench'] = array();
-
- $GLOBALS['qr_time_bench'][$markerId] = $time;
- }
-
- //----------------------------------------------------------------------
- public static function timeBenchmark()
- {
- self::markTime('finish');
-
- $lastTime = 0;
- $startTime = 0;
- $p = 0;
-
- echo '
- BENCHMARK |
- ';
-
- foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {
- if ($p > 0) {
- echo 'till '.$markerId.': | '.number_format($thisTime-$lastTime, 6).'s |
';
- } else {
- $startTime = $thisTime;
- }
-
- $p++;
- $lastTime = $thisTime;
- }
-
- echo '
- TOTAL: | '.number_format($lastTime-$startTime, 6).'s |
-
-
';
- }
-
- }
-
- //##########################################################################
-
- QRtools::markTime('start');
-
\ No newline at end of file
diff --git a/lib/phpqrcode/tools/merge.bat b/lib/phpqrcode/tools/merge.bat
deleted file mode 100644
index b60a4853c..000000000
--- a/lib/phpqrcode/tools/merge.bat
+++ /dev/null
@@ -1,2 +0,0 @@
-php ./merge.php
-pause
\ No newline at end of file
diff --git a/lib/phpqrcode/tools/merge.php b/lib/phpqrcode/tools/merge.php
deleted file mode 100644
index 19d338b34..000000000
--- a/lib/phpqrcode/tools/merge.php
+++ /dev/null
@@ -1,70 +0,0 @@
-
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- $QR_BASEDIR = dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR;
- $QR_TOOLSDIR = dirname(__FILE__).DIRECTORY_SEPARATOR;
-
- $outputFile = $QR_BASEDIR.'phpqrcode.php';
-
- // Required libs
-
- $fileList = array(
- $QR_BASEDIR.'qrconst.php',
- $QR_TOOLSDIR.'merged_config.php',
- $QR_BASEDIR.'qrtools.php',
- $QR_BASEDIR.'qrspec.php',
- $QR_BASEDIR.'qrimage.php',
- $QR_BASEDIR.'qrinput.php',
- $QR_BASEDIR.'qrbitstream.php',
- $QR_BASEDIR.'qrsplit.php',
- $QR_BASEDIR.'qrrscode.php',
- $QR_BASEDIR.'qrmask.php',
- $QR_BASEDIR.'qrencode.php'
- );
-
- $headerFile = $QR_TOOLSDIR.'merged_header.php';
- $versionFile = $QR_BASEDIR.'VERSION';
-
- $outputCode = '';
-
- foreach($fileList as $fileName) {
- $outputCode .= "\n\n".'//---- '.basename($fileName).' -----------------------------'."\n\n";
- $anotherCode = file_get_contents($fileName);
- $anotherCode = preg_replace ('/^<\?php/', '', $anotherCode);
- $anotherCode = preg_replace ('/\?>\*$/', '', $anotherCode);
- $outputCode .= "\n\n".$anotherCode."\n\n";
- }
-
- $versionDataEx = explode("\n", file_get_contents($versionFile));
-
- $outputContents = file_get_contents($headerFile);
- $outputContents .= "\n\n/*\n * Version: ".trim($versionDataEx[0])."\n * Build: ".trim($versionDataEx[1])."\n */\n\n";
- $outputContents .= $outputCode;
-
- file_put_contents($outputFile, $outputContents);
-
-
\ No newline at end of file
diff --git a/lib/phpqrcode/tools/merge.sh b/lib/phpqrcode/tools/merge.sh
deleted file mode 100644
index e4c2fbcb8..000000000
--- a/lib/phpqrcode/tools/merge.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-php ./merge.php
\ No newline at end of file
diff --git a/lib/phpqrcode/tools/merged_config.php b/lib/phpqrcode/tools/merged_config.php
deleted file mode 100644
index 55ddb4506..000000000
--- a/lib/phpqrcode/tools/merged_config.php
+++ /dev/null
@@ -1,17 +0,0 @@
-
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
\ No newline at end of file
diff --git a/lib/xsl_mop-up.js b/lib/xsl_mop-up.js
deleted file mode 100644
index 87c967090..000000000
--- a/lib/xsl_mop-up.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// -*-coding: latin-1;-*-
-// Time-stamp: "2006-05-17 22:06:46 ADT" sburke@cpan.org
-
-// A workaround for XSL-to-XHTML systems that don't
-// implement XSL 'disable-output-escaping="yes"'.
-//
-// sburke@cpan.org, Sean M. Burke.
-// - I hereby release this JavaScript code into the public domain.
-
-var is_decoding;
-var DEBUG = 0;
-
-function complaining (s) { alert(s); return new Error(s,s); }
-
-if(!( document.getElementById && document.getElementsByName ))
- throw complaining("Your browser is too old to render this page properly."
- + " Consider going to getfirefox.com to upgrade.");
-
-function check_decoding () {
- var d = document.getElementById('cometestme');
- if(!d) {
- throw complaining("Can't find an id='cometestme' element?");
- } else if(!('textContent' in d)) {
- // It's a browser with a halfassed DOM implementation (like IE6)
- // that doesn't implement textContent! Assume that if it's that
- // dumb, it probably doesn't implement disable-content-encoding.
-
- } else {
- var ampy = d.textContent;
- if(DEBUG > 1) { alert("Got " + ampy); }
-
- if(ampy == undefined) throw complaining("'cometestme' element has undefined text content?!");
- if(ampy == '' ) throw complaining("'cometestme' element has empty text content?!" );
-
- if (ampy == "\x26" ) { is_decoding = true; }
- else if (ampy == "\x26amp;" ) { is_decoding = false; }
- else { throw complaining('Insane value: "' + ampy + '"!'); }
- }
-
- var msg =
- (is_decoding == undefined) ? "I can't tell whether the XSL processor supports disable-content-encoding!D"
- : is_decoding ? "The XSL processor DOES support disable-content-encoding"
- : "The XSL processor does NOT support disable-content-encoding"
- ;
- if(DEBUG) alert(msg);
- return msg;
-}
-
-
-function go_decoding () {
- check_decoding();
-
- if(is_decoding) {
- DEBUG && alert("No work needs doing -- already decoded!");
- return;
- }
-
- var to_decode = document.getElementsByName('decodeme');
- if(!( to_decode && to_decode.length )) {
- DEBUG && alert("No work needs doing -- no elements to decode!");
- return;
- }
-
- if(!( ( "innerHTML" in to_decode[0]) && ( "textContent" in to_decode[0]) ))
- throw complaining( "Your JavaScript version doesn't implement DOM " +
- "properly enough to show this page correctly. " +
- "Consider going to getfirefox.com to upgrade.");
-
- var s;
- for(var i = to_decode.length - 1; i >= 0; i--) {
- s = to_decode[i].textContent;
-
- if(
- s == undefined ||
- (s.indexOf('&') == -1 && s.indexOf('<') == -1)
- ) {
- // the null or markupless element needs no reworking
- } else {
- to_decode[i].innerHTML = s; // that's the magic
- }
- }
-
- return;
-}
-
-//End
diff --git a/plugins/auth_internal/init.php b/plugins/auth_internal/init.php
index eec506cfd..3071733eb 100644
--- a/plugins/auth_internal/init.php
+++ b/plugins/auth_internal/init.php
@@ -23,78 +23,81 @@ class Auth_Internal extends Auth_Base {
$pwd_hash2 = encrypt_password($password, $login);
$otp = (int) ($_REQUEST["otp"] ?? 0);
- if (get_schema_version() > 96) {
+ // don't bother with null/null logins for auth_external etc
+ if ($login && get_schema_version() > 96) {
- $sth = $this->pdo->prepare("SELECT otp_enabled,salt FROM ttrss_users WHERE
- LOWER(login) = LOWER(?)");
- $sth->execute([$login]);
+ $user_id = UserHelper::find_user_by_login($login);
- if ($row = $sth->fetch()) {
- $otp_enabled = $row['otp_enabled'];
+ if ($user_id && UserHelper::is_otp_enabled($user_id)) {
- if ($otp_enabled) {
-
- // only allow app password checking if OTP is enabled
- if ($service && get_schema_version() > 138) {
- return $this->check_app_password($login, $password, $service);
- }
-
- if ($otp) {
- $base32 = new \OTPHP\Base32();
-
- $secret = $base32->encode(mb_substr(sha1($row["salt"]), 0, 12), false);
- $secret_legacy = $base32->encode(sha1($row["salt"]));
-
- $totp = new \OTPHP\TOTP($secret);
- $otp_check = $totp->now();
-
- $totp_legacy = new \OTPHP\TOTP($secret_legacy);
- $otp_check_legacy = $totp_legacy->now();
-
- if ($otp !== $otp_check && $otp !== $otp_check_legacy) {
- return false;
- }
- } else {
- $return = urlencode($_REQUEST["return"]);
- ?>
-
-
-
- Tiny Tiny RSS
-
-
- = stylesheet_tag("themes/light.css") ?>
-
- = __("Authentication") ?>
-
-
-
- 138) {
+ return $this->check_app_password($login, $password, $service);
}
+
+ if ($otp) {
+
+ /*$base32 = new \OTPHP\Base32();
+
+ $secret = $base32->encode(mb_substr(sha1($row["salt"]), 0, 12), false);
+ $secret_legacy = $base32->encode(sha1($row["salt"]));
+
+ $totp = new \OTPHP\TOTP($secret);
+ $otp_check = $totp->now();
+
+ $totp_legacy = new \OTPHP\TOTP($secret_legacy);
+ $otp_check_legacy = $totp_legacy->now();
+
+ if ($otp !== $otp_check && $otp !== $otp_check_legacy) {
+ return false;
+ } */
+
+ if (UserHelper::check_otp($user_id, $otp))
+ return $user_id;
+ else
+ return false;
+
+ } else {
+ $return = urlencode($_REQUEST["return"]);
+ ?>
+
+
+
+ Tiny Tiny RSS
+
+
+ = stylesheet_tag("themes/light.css") ?>
+
+ = __("Authentication") ?>
+
+
+
+ 138) {
$user_id = $this->check_app_password($login, $password, $service);
diff --git a/vendor/OTPHP/Base32.php b/vendor/OTPHP/Base32.php
deleted file mode 100644
index f0dc2f16b..000000000
--- a/vendor/OTPHP/Base32.php
+++ /dev/null
@@ -1,85 +0,0 @@
-'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7',
- 'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15',
- 'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23',
- 'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31'
- );
-
- /**
- * Use padding false when encoding for urls
- *
- * @return base32 encoded string
- * @author Bryan Ruiz
- **/
- public static function encode($input, $padding = true) {
- if(empty($input)) return "";
- $input = str_split($input);
- $binaryString = "";
- for($i = 0; $i < count($input); $i++) {
- $binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT);
- }
- $fiveBitBinaryArray = str_split($binaryString, 5);
- $base32 = "";
- $i=0;
- while($i < count($fiveBitBinaryArray)) {
- $base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5,'0'), 2, 10)];
- $i++;
- }
- if($padding && ($x = strlen($binaryString) % 40) != 0) {
- if($x == 8) $base32 .= str_repeat(self::$map[32], 6);
- else if($x == 16) $base32 .= str_repeat(self::$map[32], 4);
- else if($x == 24) $base32 .= str_repeat(self::$map[32], 3);
- else if($x == 32) $base32 .= self::$map[32];
- }
- return $base32;
- }
-
- public static function decode($input) {
- if(empty($input)) return;
- $paddingCharCount = substr_count($input, self::$map[32]);
- $allowedValues = array(6,4,3,1,0);
- if(!in_array($paddingCharCount, $allowedValues)) return false;
- for($i=0; $i<4; $i++){
- if($paddingCharCount == $allowedValues[$i] &&
- substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false;
- }
- $input = str_replace('=','', $input);
- $input = str_split($input);
- $binaryString = "";
- for($i=0; $i < count($input); $i = $i+8) {
- $x = "";
- if(!in_array($input[$i], self::$map)) return false;
- for($j=0; $j < 8; $j++) {
- $x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
- }
- $eightBits = str_split($x, 8);
- for($z = 0; $z < count($eightBits); $z++) {
- $binaryString .= ( ($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48 ) ? $y:"";
- }
- }
- return $binaryString;
- }
-}
-
diff --git a/vendor/OTPHP/HOTP.php b/vendor/OTPHP/HOTP.php
deleted file mode 100644
index 7092fd9ff..000000000
--- a/vendor/OTPHP/HOTP.php
+++ /dev/null
@@ -1,74 +0,0 @@
-generateOTP($count);
- }
-
-
- /**
- * Verify if a password is valid for a specific counter value
- *
- * @param integer $otp the one-time password
- * @param integer $counter the counter value
- * @return bool true if the counter is valid, false otherwise
- */
- public function verify($otp, $counter) {
- return ($otp == $this->at($counter));
- }
-
- /**
- * Returns the uri for a specific secret for hotp method.
- * Can be encoded as a image for simple configuration in
- * Google Authenticator.
- *
- * @param string $name the name of the account / profile
- * @param integer $initial_count the initial counter
- * @return string the uri for the hmac secret
- */
- public function provisioning_uri($name, $initial_count) {
- return "otpauth://hotp/".urlencode($name)."?secret={$this->secret}&counter=$initial_count";
- }
- }
-
-}
diff --git a/vendor/OTPHP/OTP.php b/vendor/OTPHP/OTP.php
deleted file mode 100644
index d1995ef99..000000000
--- a/vendor/OTPHP/OTP.php
+++ /dev/null
@@ -1,120 +0,0 @@
-digits = isset($opt['digits']) ? $opt['digits'] : 6;
- $this->digest = isset($opt['digest']) ? $opt['digest'] : 'sha1';
- $this->secret = $secret;
- }
-
- /**
- * Generate a one-time password
- *
- * @param integer $input : number used to seed the hmac hash function.
- * This number is usually a counter (HOTP) or calculated based on the current
- * timestamp (see TOTP class).
- * @return integer the one-time password
- */
- public function generateOTP($input) {
- $hash = hash_hmac($this->digest, $this->intToBytestring($input), $this->byteSecret());
- foreach(str_split($hash, 2) as $hex) { // stupid PHP has bin2hex but no hex2bin WTF
- $hmac[] = hexdec($hex);
- }
- $offset = $hmac[19] & 0xf;
- $code = ($hmac[$offset+0] & 0x7F) << 24 |
- ($hmac[$offset + 1] & 0xFF) << 16 |
- ($hmac[$offset + 2] & 0xFF) << 8 |
- ($hmac[$offset + 3] & 0xFF);
- return $code % pow(10, $this->digits);
- }
-
- /**
- * Returns the binary value of the base32 encoded secret
- * @access private
- * This method should be private but was left public for
- * phpunit tests to work.
- * @return binary secret key
- */
- public function byteSecret() {
- return Base32::decode($this->secret);
- }
-
- /**
- * Turns an integer in a OATH bytestring
- * @param integer $int
- * @access private
- * @return string bytestring
- */
- public function intToBytestring($int) {
- $result = Array();
- while($int != 0) {
- $result[] = chr($int & 0xFF);
- $int >>= 8;
- }
- return str_pad(join(array_reverse($result)), 8, "\000", STR_PAD_LEFT);
- }
- }
-}
diff --git a/vendor/OTPHP/OTPHP.php b/vendor/OTPHP/OTPHP.php
deleted file mode 100644
index a6c6f8d66..000000000
--- a/vendor/OTPHP/OTPHP.php
+++ /dev/null
@@ -1,27 +0,0 @@
-interval = isset($opt['interval']) ? $opt['interval'] : 30;
- parent::__construct($s, $opt);
- }
-
- /**
- * Get the password for a specific timestamp value
- *
- * @param integer $timestamp the timestamp which is timecoded and
- * used to seed the hmac hash function.
- * @return integer the One Time Password
- */
- public function at($timestamp) {
- return $this->generateOTP($this->timecode($timestamp));
- }
-
- /**
- * Get the password for the current timestamp value
- *
- * @return integer the current One Time Password
- */
- public function now() {
- return $this->generateOTP($this->timecode(time()));
- }
-
- /**
- * Verify if a password is valid for a specific counter value
- *
- * @param integer $otp the one-time password
- * @param integer $timestamp the timestamp for the a given time, defaults to current time.
- * @return bool true if the counter is valid, false otherwise
- */
- public function verify($otp, $timestamp = null) {
- if($timestamp === null)
- $timestamp = time();
- return ($otp == $this->at($timestamp));
- }
-
- /**
- * Returns the uri for a specific secret for totp method.
- * Can be encoded as a image for simple configuration in
- * Google Authenticator.
- *
- * @param string $name the name of the account / profile
- * @return string the uri for the hmac secret
- */
- public function provisioning_uri($name) {
- return "otpauth://totp/".urlencode($name)."?secret={$this->secret}";
- }
-
- /**
- * Transform a timestamp in a counter based on specified internal
- *
- * @param integer $timestamp
- * @return integer the timecode
- */
- protected function timecode($timestamp) {
- return (int)( (((int)$timestamp * 1000) / ($this->interval * 1000)));
- }
- }
-
-}
diff --git a/vendor/Psr/Log/AbstractLogger.php b/vendor/Psr/Log/AbstractLogger.php
deleted file mode 100644
index 90e721af2..000000000
--- a/vendor/Psr/Log/AbstractLogger.php
+++ /dev/null
@@ -1,128 +0,0 @@
-log(LogLevel::EMERGENCY, $message, $context);
- }
-
- /**
- * Action must be taken immediately.
- *
- * Example: Entire website down, database unavailable, etc. This should
- * trigger the SMS alerts and wake you up.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function alert($message, array $context = array())
- {
- $this->log(LogLevel::ALERT, $message, $context);
- }
-
- /**
- * Critical conditions.
- *
- * Example: Application component unavailable, unexpected exception.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function critical($message, array $context = array())
- {
- $this->log(LogLevel::CRITICAL, $message, $context);
- }
-
- /**
- * Runtime errors that do not require immediate action but should typically
- * be logged and monitored.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function error($message, array $context = array())
- {
- $this->log(LogLevel::ERROR, $message, $context);
- }
-
- /**
- * Exceptional occurrences that are not errors.
- *
- * Example: Use of deprecated APIs, poor use of an API, undesirable things
- * that are not necessarily wrong.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function warning($message, array $context = array())
- {
- $this->log(LogLevel::WARNING, $message, $context);
- }
-
- /**
- * Normal but significant events.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function notice($message, array $context = array())
- {
- $this->log(LogLevel::NOTICE, $message, $context);
- }
-
- /**
- * Interesting events.
- *
- * Example: User logs in, SQL logs.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function info($message, array $context = array())
- {
- $this->log(LogLevel::INFO, $message, $context);
- }
-
- /**
- * Detailed debug information.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function debug($message, array $context = array())
- {
- $this->log(LogLevel::DEBUG, $message, $context);
- }
-}
diff --git a/vendor/Psr/Log/InvalidArgumentException.php b/vendor/Psr/Log/InvalidArgumentException.php
deleted file mode 100644
index 67f852d1d..000000000
--- a/vendor/Psr/Log/InvalidArgumentException.php
+++ /dev/null
@@ -1,7 +0,0 @@
-logger = $logger;
- }
-}
diff --git a/vendor/Psr/Log/LoggerInterface.php b/vendor/Psr/Log/LoggerInterface.php
deleted file mode 100644
index 5ea72438b..000000000
--- a/vendor/Psr/Log/LoggerInterface.php
+++ /dev/null
@@ -1,123 +0,0 @@
-log(LogLevel::EMERGENCY, $message, $context);
- }
-
- /**
- * Action must be taken immediately.
- *
- * Example: Entire website down, database unavailable, etc. This should
- * trigger the SMS alerts and wake you up.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function alert($message, array $context = array())
- {
- $this->log(LogLevel::ALERT, $message, $context);
- }
-
- /**
- * Critical conditions.
- *
- * Example: Application component unavailable, unexpected exception.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function critical($message, array $context = array())
- {
- $this->log(LogLevel::CRITICAL, $message, $context);
- }
-
- /**
- * Runtime errors that do not require immediate action but should typically
- * be logged and monitored.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function error($message, array $context = array())
- {
- $this->log(LogLevel::ERROR, $message, $context);
- }
-
- /**
- * Exceptional occurrences that are not errors.
- *
- * Example: Use of deprecated APIs, poor use of an API, undesirable things
- * that are not necessarily wrong.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function warning($message, array $context = array())
- {
- $this->log(LogLevel::WARNING, $message, $context);
- }
-
- /**
- * Normal but significant events.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function notice($message, array $context = array())
- {
- $this->log(LogLevel::NOTICE, $message, $context);
- }
-
- /**
- * Interesting events.
- *
- * Example: User logs in, SQL logs.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function info($message, array $context = array())
- {
- $this->log(LogLevel::INFO, $message, $context);
- }
-
- /**
- * Detailed debug information.
- *
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function debug($message, array $context = array())
- {
- $this->log(LogLevel::DEBUG, $message, $context);
- }
-
- /**
- * Logs with an arbitrary level.
- *
- * @param mixed $level
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- abstract public function log($level, $message, array $context = array());
-}
diff --git a/vendor/Psr/Log/NullLogger.php b/vendor/Psr/Log/NullLogger.php
deleted file mode 100644
index d8cd682c8..000000000
--- a/vendor/Psr/Log/NullLogger.php
+++ /dev/null
@@ -1,28 +0,0 @@
-logger) { }`
- * blocks.
- */
-class NullLogger extends AbstractLogger
-{
- /**
- * Logs with an arbitrary level.
- *
- * @param mixed $level
- * @param string $message
- * @param array $context
- *
- * @return void
- */
- public function log($level, $message, array $context = array())
- {
- // noop
- }
-}
diff --git a/vendor/Psr/Log/Test/LoggerInterfaceTest.php b/vendor/Psr/Log/Test/LoggerInterfaceTest.php
deleted file mode 100644
index a0391a52b..000000000
--- a/vendor/Psr/Log/Test/LoggerInterfaceTest.php
+++ /dev/null
@@ -1,140 +0,0 @@
- ".
- *
- * Example ->error('Foo') would yield "error Foo".
- *
- * @return string[]
- */
- abstract public function getLogs();
-
- public function testImplements()
- {
- $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
- }
-
- /**
- * @dataProvider provideLevelsAndMessages
- */
- public function testLogsAtAllLevels($level, $message)
- {
- $logger = $this->getLogger();
- $logger->{$level}($message, array('user' => 'Bob'));
- $logger->log($level, $message, array('user' => 'Bob'));
-
- $expected = array(
- $level.' message of level '.$level.' with context: Bob',
- $level.' message of level '.$level.' with context: Bob',
- );
- $this->assertEquals($expected, $this->getLogs());
- }
-
- public function provideLevelsAndMessages()
- {
- return array(
- LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
- LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
- LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
- LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
- LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
- LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
- LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
- LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
- );
- }
-
- /**
- * @expectedException \Psr\Log\InvalidArgumentException
- */
- public function testThrowsOnInvalidLevel()
- {
- $logger = $this->getLogger();
- $logger->log('invalid level', 'Foo');
- }
-
- public function testContextReplacement()
- {
- $logger = $this->getLogger();
- $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
-
- $expected = array('info {Message {nothing} Bob Bar a}');
- $this->assertEquals($expected, $this->getLogs());
- }
-
- public function testObjectCastToString()
- {
- if (method_exists($this, 'createPartialMock')) {
- $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString'));
- } else {
- $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
- }
- $dummy->expects($this->once())
- ->method('__toString')
- ->will($this->returnValue('DUMMY'));
-
- $this->getLogger()->warning($dummy);
-
- $expected = array('warning DUMMY');
- $this->assertEquals($expected, $this->getLogs());
- }
-
- public function testContextCanContainAnything()
- {
- $context = array(
- 'bool' => true,
- 'null' => null,
- 'string' => 'Foo',
- 'int' => 0,
- 'float' => 0.5,
- 'nested' => array('with object' => new DummyTest),
- 'object' => new \DateTime,
- 'resource' => fopen('php://memory', 'r'),
- );
-
- $this->getLogger()->warning('Crazy context data', $context);
-
- $expected = array('warning Crazy context data');
- $this->assertEquals($expected, $this->getLogs());
- }
-
- public function testContextExceptionKeyCanBeExceptionOrOtherValues()
- {
- $logger = $this->getLogger();
- $logger->warning('Random message', array('exception' => 'oops'));
- $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));
-
- $expected = array(
- 'warning Random message',
- 'critical Uncaught Exception!'
- );
- $this->assertEquals($expected, $this->getLogs());
- }
-}
-
-class DummyTest
-{
- public function __toString()
- {
- }
-}
diff --git a/vendor/autoload.php b/vendor/autoload.php
new file mode 100644
index 000000000..e6e3ad736
--- /dev/null
+++ b/vendor/autoload.php
@@ -0,0 +1,7 @@
+=6.0.0 <8"
+ },
+ "scripts": {
+ "assert:generate-docs": "php bin/generate_method_docs.php",
+ "assert:cs-lint": "php-cs-fixer fix --diff -vvv --dry-run",
+ "assert:cs-fix": "php-cs-fixer fix . -vvv || true",
+ "assert:sa-code": "vendor/bin/phpstan analyse --configuration=phpstan-code.neon --no-progress --ansi -l 7 bin lib",
+ "assert:sa-tests": "vendor/bin/phpstan analyse --configuration=phpstan-tests.neon --no-progress --ansi -l 7 tests"
+ },
+ "suggest": {
+ "ext-intl": "Needed to allow Assertion::count(), Assertion::isCountable(), Assertion::minCount(), and Assertion::maxCount() to operate on ResourceBundles"
+ }
+}
diff --git a/vendor/beberlei/assert/lib/Assert/Assert.php b/vendor/beberlei/assert/lib/Assert/Assert.php
new file mode 100644
index 000000000..6910258d6
--- /dev/null
+++ b/vendor/beberlei/assert/lib/Assert/Assert.php
@@ -0,0 +1,96 @@
+notEmpty()->integer();
+ * Assert::that($value)->nullOr()->string()->startsWith("Foo");
+ *
+ * The assertion chain can be stateful, that means be careful when you reuse
+ * it. You should never pass around the chain.
+ */
+ public static function that($value, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
+ {
+ $assertionChain = new AssertionChain($value, $defaultMessage, $defaultPropertyPath);
+
+ return $assertionChain->setAssertionClassName(static::$assertionClass);
+ }
+
+ /**
+ * Start validation on a set of values, returns {@link AssertionChain}.
+ *
+ * @param mixed $values
+ * @param string|callable|null $defaultMessage
+ * @param string|null $defaultPropertyPath
+ *
+ * @return AssertionChain
+ */
+ public static function thatAll($values, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
+ {
+ return static::that($values, $defaultMessage, $defaultPropertyPath)->all();
+ }
+
+ /**
+ * Start validation and allow NULL, returns {@link AssertionChain}.
+ *
+ * @param mixed $value
+ * @param string|callable|null $defaultMessage
+ * @param string|null $defaultPropertyPath
+ *
+ * @return AssertionChain
+ */
+ public static function thatNullOr($value, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
+ {
+ return static::that($value, $defaultMessage, $defaultPropertyPath)->nullOr();
+ }
+
+ /**
+ * Create a lazy assertion object.
+ *
+ * @return LazyAssertion
+ */
+ public static function lazy(): LazyAssertion
+ {
+ $lazyAssertion = new LazyAssertion();
+
+ return $lazyAssertion
+ ->setAssertClass(\get_called_class())
+ ->setExceptionClass(static::$lazyAssertionExceptionClass);
+ }
+}
diff --git a/vendor/beberlei/assert/lib/Assert/Assertion.php b/vendor/beberlei/assert/lib/Assert/Assertion.php
new file mode 100644
index 000000000..a8b04e529
--- /dev/null
+++ b/vendor/beberlei/assert/lib/Assert/Assertion.php
@@ -0,0 +1,2825 @@
+
+ *
+ * @method static bool allAlnum(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is alphanumeric for all values.
+ * @method static bool allBase64(string[] $value, string|callable $message = null, string $propertyPath = null) Assert that a constant is defined for all values.
+ * @method static bool allBetween(mixed[] $value, mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit for all values.
+ * @method static bool allBetweenExclusive(mixed[] $value, mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater than a lower limit, and less than an upper limit for all values.
+ * @method static bool allBetweenLength(mixed[] $value, int $minLength, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string length is between min and max lengths for all values.
+ * @method static bool allBoolean(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is php boolean for all values.
+ * @method static bool allChoice(mixed[] $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices for all values.
+ * @method static bool allChoicesNotEmpty(array[] $values, array $choices, string|callable $message = null, string $propertyPath = null) Determines if the values array has every choice as key and that this choice has content for all values.
+ * @method static bool allClassExists(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that the class exists for all values.
+ * @method static bool allContains(mixed[] $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string contains a sequence of chars for all values.
+ * @method static bool allCount(array[]|Countable[]|ResourceBundle[]|SimpleXMLElement[] $countable, int $count, string|callable $message = null, string $propertyPath = null) Assert that the count of countable is equal to count for all values.
+ * @method static bool allDate(string[] $value, string $format, string|callable $message = null, string $propertyPath = null) Assert that date is valid and corresponds to the given format for all values.
+ * @method static bool allDefined(mixed[] $constant, string|callable $message = null, string $propertyPath = null) Assert that a constant is defined for all values.
+ * @method static bool allDigit(mixed[] $value, string|callable $message = null, string $propertyPath = null) Validates if an integer or integerish is a digit for all values.
+ * @method static bool allDirectory(string[] $value, string|callable $message = null, string $propertyPath = null) Assert that a directory exists for all values.
+ * @method static bool allE164(string[] $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid E164 Phone Number for all values.
+ * @method static bool allEmail(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL) for all values.
+ * @method static bool allEndsWith(mixed[] $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string ends with a sequence of chars for all values.
+ * @method static bool allEq(mixed[] $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are equal (using ==) for all values.
+ * @method static bool allEqArraySubset(mixed[] $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that the array contains the subset for all values.
+ * @method static bool allExtensionLoaded(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded for all values.
+ * @method static bool allExtensionVersion(string[] $extension, string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded and a specific version is installed for all values.
+ * @method static bool allFalse(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that the value is boolean False for all values.
+ * @method static bool allFile(string[] $value, string|callable $message = null, string $propertyPath = null) Assert that a file exists for all values.
+ * @method static bool allFloat(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php float for all values.
+ * @method static bool allGreaterOrEqualThan(mixed[] $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater or equal than given limit for all values.
+ * @method static bool allGreaterThan(mixed[] $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater than given limit for all values.
+ * @method static bool allImplementsInterface(mixed[] $class, string $interfaceName, string|callable $message = null, string $propertyPath = null) Assert that the class implements the interface for all values.
+ * @method static bool allInArray(mixed[] $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices. This is an alias of Assertion::choice() for all values.
+ * @method static bool allInteger(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php integer for all values.
+ * @method static bool allIntegerish(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php integer'ish for all values.
+ * @method static bool allInterfaceExists(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that the interface exists for all values.
+ * @method static bool allIp(string[] $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 or IPv6 address for all values.
+ * @method static bool allIpv4(string[] $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 address for all values.
+ * @method static bool allIpv6(string[] $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv6 address for all values.
+ * @method static bool allIsArray(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array for all values.
+ * @method static bool allIsArrayAccessible(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or an array-accessible object for all values.
+ * @method static bool allIsCallable(mixed[] $value, string|callable $message = null, string $propertyPath = null) Determines that the provided value is callable for all values.
+ * @method static bool allIsCountable(array[]|Countable[]|ResourceBundle[]|SimpleXMLElement[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is countable for all values.
+ * @method static bool allIsInstanceOf(mixed[] $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is instance of given class-name for all values.
+ * @method static bool allIsJsonString(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid json string for all values.
+ * @method static bool allIsObject(mixed[] $value, string|callable $message = null, string $propertyPath = null) Determines that the provided value is an object for all values.
+ * @method static bool allIsResource(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is a resource for all values.
+ * @method static bool allIsTraversable(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or a traversable object for all values.
+ * @method static bool allKeyExists(mixed[] $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array for all values.
+ * @method static bool allKeyIsset(mixed[] $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object using isset() for all values.
+ * @method static bool allKeyNotExists(mixed[] $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key does not exist in an array for all values.
+ * @method static bool allLength(mixed[] $value, int $length, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string has a given length for all values.
+ * @method static bool allLessOrEqualThan(mixed[] $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less or equal than given limit for all values.
+ * @method static bool allLessThan(mixed[] $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less than given limit for all values.
+ * @method static bool allMax(mixed[] $value, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that a number is smaller as a given limit for all values.
+ * @method static bool allMaxCount(array[]|Countable[]|ResourceBundle[]|SimpleXMLElement[] $countable, int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at most $count elements for all values.
+ * @method static bool allMaxLength(mixed[] $value, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string value is not longer than $maxLength chars for all values.
+ * @method static bool allMethodExists(string[] $value, mixed $object, string|callable $message = null, string $propertyPath = null) Determines that the named method is defined in the provided object for all values.
+ * @method static bool allMin(mixed[] $value, mixed $minValue, string|callable $message = null, string $propertyPath = null) Assert that a value is at least as big as a given limit for all values.
+ * @method static bool allMinCount(array[]|Countable[]|ResourceBundle[]|SimpleXMLElement[] $countable, int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at least $count elements for all values.
+ * @method static bool allMinLength(mixed[] $value, int $minLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that a string is at least $minLength chars long for all values.
+ * @method static bool allNoContent(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is empty for all values.
+ * @method static bool allNotBlank(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is not blank for all values.
+ * @method static bool allNotContains(mixed[] $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string does not contains a sequence of chars for all values.
+ * @method static bool allNotEmpty(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is not empty for all values.
+ * @method static bool allNotEmptyKey(mixed[] $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object and its value is not empty for all values.
+ * @method static bool allNotEq(mixed[] $value1, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not equal (using ==) for all values.
+ * @method static bool allNotInArray(mixed[] $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is not in array of choices for all values.
+ * @method static bool allNotIsInstanceOf(mixed[] $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is not instance of given class-name for all values.
+ * @method static bool allNotNull(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is not null for all values.
+ * @method static bool allNotRegex(mixed[] $value, string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value does not match a regex for all values.
+ * @method static bool allNotSame(mixed[] $value1, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not the same (using ===) for all values.
+ * @method static bool allNull(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is null for all values.
+ * @method static bool allNumeric(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is numeric for all values.
+ * @method static bool allObjectOrClass(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that the value is an object, or a class that exists for all values.
+ * @method static bool allPhpVersion(string[] $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert on PHP version for all values.
+ * @method static bool allPropertiesExist(mixed[] $value, array $properties, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the properties all exist for all values.
+ * @method static bool allPropertyExists(mixed[] $value, string $property, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the property exists for all values.
+ * @method static bool allRange(mixed[] $value, mixed $minValue, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that value is in range of numbers for all values.
+ * @method static bool allReadable(string[] $value, string|callable $message = null, string $propertyPath = null) Assert that the value is something readable for all values.
+ * @method static bool allRegex(mixed[] $value, string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value matches a regex for all values.
+ * @method static bool allSame(mixed[] $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are the same (using ===) for all values.
+ * @method static bool allSatisfy(mixed[] $value, callable $callback, string|callable $message = null, string $propertyPath = null) Assert that the provided value is valid according to a callback for all values.
+ * @method static bool allScalar(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is a PHP scalar for all values.
+ * @method static bool allStartsWith(mixed[] $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string starts with a sequence of chars for all values.
+ * @method static bool allString(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is a string for all values.
+ * @method static bool allSubclassOf(mixed[] $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is subclass of given class-name for all values.
+ * @method static bool allTrue(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that the value is boolean True for all values.
+ * @method static bool allUrl(mixed[] $value, string|callable $message = null, string $propertyPath = null) Assert that value is an URL for all values.
+ * @method static bool allUuid(string[] $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid UUID for all values.
+ * @method static bool allVersion(string[] $version1, string $operator, string $version2, string|callable $message = null, string $propertyPath = null) Assert comparison of two versions for all values.
+ * @method static bool allWriteable(string[] $value, string|callable $message = null, string $propertyPath = null) Assert that the value is something writeable for all values.
+ * @method static bool nullOrAlnum(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is alphanumeric or that the value is null.
+ * @method static bool nullOrBase64(string|null $value, string|callable $message = null, string $propertyPath = null) Assert that a constant is defined or that the value is null.
+ * @method static bool nullOrBetween(mixed|null $value, mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit or that the value is null.
+ * @method static bool nullOrBetweenExclusive(mixed|null $value, mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater than a lower limit, and less than an upper limit or that the value is null.
+ * @method static bool nullOrBetweenLength(mixed|null $value, int $minLength, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string length is between min and max lengths or that the value is null.
+ * @method static bool nullOrBoolean(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is php boolean or that the value is null.
+ * @method static bool nullOrChoice(mixed|null $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices or that the value is null.
+ * @method static bool nullOrChoicesNotEmpty(array|null $values, array $choices, string|callable $message = null, string $propertyPath = null) Determines if the values array has every choice as key and that this choice has content or that the value is null.
+ * @method static bool nullOrClassExists(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that the class exists or that the value is null.
+ * @method static bool nullOrContains(mixed|null $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string contains a sequence of chars or that the value is null.
+ * @method static bool nullOrCount(array|Countable|ResourceBundle|SimpleXMLElement|null $countable, int $count, string|callable $message = null, string $propertyPath = null) Assert that the count of countable is equal to count or that the value is null.
+ * @method static bool nullOrDate(string|null $value, string $format, string|callable $message = null, string $propertyPath = null) Assert that date is valid and corresponds to the given format or that the value is null.
+ * @method static bool nullOrDefined(mixed|null $constant, string|callable $message = null, string $propertyPath = null) Assert that a constant is defined or that the value is null.
+ * @method static bool nullOrDigit(mixed|null $value, string|callable $message = null, string $propertyPath = null) Validates if an integer or integerish is a digit or that the value is null.
+ * @method static bool nullOrDirectory(string|null $value, string|callable $message = null, string $propertyPath = null) Assert that a directory exists or that the value is null.
+ * @method static bool nullOrE164(string|null $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid E164 Phone Number or that the value is null.
+ * @method static bool nullOrEmail(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL) or that the value is null.
+ * @method static bool nullOrEndsWith(mixed|null $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string ends with a sequence of chars or that the value is null.
+ * @method static bool nullOrEq(mixed|null $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are equal (using ==) or that the value is null.
+ * @method static bool nullOrEqArraySubset(mixed|null $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that the array contains the subset or that the value is null.
+ * @method static bool nullOrExtensionLoaded(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded or that the value is null.
+ * @method static bool nullOrExtensionVersion(string|null $extension, string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded and a specific version is installed or that the value is null.
+ * @method static bool nullOrFalse(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that the value is boolean False or that the value is null.
+ * @method static bool nullOrFile(string|null $value, string|callable $message = null, string $propertyPath = null) Assert that a file exists or that the value is null.
+ * @method static bool nullOrFloat(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php float or that the value is null.
+ * @method static bool nullOrGreaterOrEqualThan(mixed|null $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater or equal than given limit or that the value is null.
+ * @method static bool nullOrGreaterThan(mixed|null $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater than given limit or that the value is null.
+ * @method static bool nullOrImplementsInterface(mixed|null $class, string $interfaceName, string|callable $message = null, string $propertyPath = null) Assert that the class implements the interface or that the value is null.
+ * @method static bool nullOrInArray(mixed|null $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices. This is an alias of Assertion::choice() or that the value is null.
+ * @method static bool nullOrInteger(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php integer or that the value is null.
+ * @method static bool nullOrIntegerish(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php integer'ish or that the value is null.
+ * @method static bool nullOrInterfaceExists(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that the interface exists or that the value is null.
+ * @method static bool nullOrIp(string|null $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 or IPv6 address or that the value is null.
+ * @method static bool nullOrIpv4(string|null $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 address or that the value is null.
+ * @method static bool nullOrIpv6(string|null $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv6 address or that the value is null.
+ * @method static bool nullOrIsArray(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or that the value is null.
+ * @method static bool nullOrIsArrayAccessible(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or an array-accessible object or that the value is null.
+ * @method static bool nullOrIsCallable(mixed|null $value, string|callable $message = null, string $propertyPath = null) Determines that the provided value is callable or that the value is null.
+ * @method static bool nullOrIsCountable(array|Countable|ResourceBundle|SimpleXMLElement|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is countable or that the value is null.
+ * @method static bool nullOrIsInstanceOf(mixed|null $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is instance of given class-name or that the value is null.
+ * @method static bool nullOrIsJsonString(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid json string or that the value is null.
+ * @method static bool nullOrIsObject(mixed|null $value, string|callable $message = null, string $propertyPath = null) Determines that the provided value is an object or that the value is null.
+ * @method static bool nullOrIsResource(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is a resource or that the value is null.
+ * @method static bool nullOrIsTraversable(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or a traversable object or that the value is null.
+ * @method static bool nullOrKeyExists(mixed|null $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array or that the value is null.
+ * @method static bool nullOrKeyIsset(mixed|null $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object using isset() or that the value is null.
+ * @method static bool nullOrKeyNotExists(mixed|null $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key does not exist in an array or that the value is null.
+ * @method static bool nullOrLength(mixed|null $value, int $length, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string has a given length or that the value is null.
+ * @method static bool nullOrLessOrEqualThan(mixed|null $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less or equal than given limit or that the value is null.
+ * @method static bool nullOrLessThan(mixed|null $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less than given limit or that the value is null.
+ * @method static bool nullOrMax(mixed|null $value, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that a number is smaller as a given limit or that the value is null.
+ * @method static bool nullOrMaxCount(array|Countable|ResourceBundle|SimpleXMLElement|null $countable, int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at most $count elements or that the value is null.
+ * @method static bool nullOrMaxLength(mixed|null $value, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string value is not longer than $maxLength chars or that the value is null.
+ * @method static bool nullOrMethodExists(string|null $value, mixed $object, string|callable $message = null, string $propertyPath = null) Determines that the named method is defined in the provided object or that the value is null.
+ * @method static bool nullOrMin(mixed|null $value, mixed $minValue, string|callable $message = null, string $propertyPath = null) Assert that a value is at least as big as a given limit or that the value is null.
+ * @method static bool nullOrMinCount(array|Countable|ResourceBundle|SimpleXMLElement|null $countable, int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at least $count elements or that the value is null.
+ * @method static bool nullOrMinLength(mixed|null $value, int $minLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that a string is at least $minLength chars long or that the value is null.
+ * @method static bool nullOrNoContent(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is empty or that the value is null.
+ * @method static bool nullOrNotBlank(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is not blank or that the value is null.
+ * @method static bool nullOrNotContains(mixed|null $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string does not contains a sequence of chars or that the value is null.
+ * @method static bool nullOrNotEmpty(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is not empty or that the value is null.
+ * @method static bool nullOrNotEmptyKey(mixed|null $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object and its value is not empty or that the value is null.
+ * @method static bool nullOrNotEq(mixed|null $value1, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not equal (using ==) or that the value is null.
+ * @method static bool nullOrNotInArray(mixed|null $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is not in array of choices or that the value is null.
+ * @method static bool nullOrNotIsInstanceOf(mixed|null $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is not instance of given class-name or that the value is null.
+ * @method static bool nullOrNotNull(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is not null or that the value is null.
+ * @method static bool nullOrNotRegex(mixed|null $value, string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value does not match a regex or that the value is null.
+ * @method static bool nullOrNotSame(mixed|null $value1, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not the same (using ===) or that the value is null.
+ * @method static bool nullOrNull(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is null or that the value is null.
+ * @method static bool nullOrNumeric(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is numeric or that the value is null.
+ * @method static bool nullOrObjectOrClass(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that the value is an object, or a class that exists or that the value is null.
+ * @method static bool nullOrPhpVersion(string|null $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert on PHP version or that the value is null.
+ * @method static bool nullOrPropertiesExist(mixed|null $value, array $properties, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the properties all exist or that the value is null.
+ * @method static bool nullOrPropertyExists(mixed|null $value, string $property, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the property exists or that the value is null.
+ * @method static bool nullOrRange(mixed|null $value, mixed $minValue, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that value is in range of numbers or that the value is null.
+ * @method static bool nullOrReadable(string|null $value, string|callable $message = null, string $propertyPath = null) Assert that the value is something readable or that the value is null.
+ * @method static bool nullOrRegex(mixed|null $value, string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value matches a regex or that the value is null.
+ * @method static bool nullOrSame(mixed|null $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are the same (using ===) or that the value is null.
+ * @method static bool nullOrSatisfy(mixed|null $value, callable $callback, string|callable $message = null, string $propertyPath = null) Assert that the provided value is valid according to a callback or that the value is null.
+ * @method static bool nullOrScalar(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is a PHP scalar or that the value is null.
+ * @method static bool nullOrStartsWith(mixed|null $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string starts with a sequence of chars or that the value is null.
+ * @method static bool nullOrString(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is a string or that the value is null.
+ * @method static bool nullOrSubclassOf(mixed|null $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is subclass of given class-name or that the value is null.
+ * @method static bool nullOrTrue(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that the value is boolean True or that the value is null.
+ * @method static bool nullOrUrl(mixed|null $value, string|callable $message = null, string $propertyPath = null) Assert that value is an URL or that the value is null.
+ * @method static bool nullOrUuid(string|null $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid UUID or that the value is null.
+ * @method static bool nullOrVersion(string|null $version1, string $operator, string $version2, string|callable $message = null, string $propertyPath = null) Assert comparison of two versions or that the value is null.
+ * @method static bool nullOrWriteable(string|null $value, string|callable $message = null, string $propertyPath = null) Assert that the value is something writeable or that the value is null.
+ */
+class Assertion
+{
+ const INVALID_FLOAT = 9;
+ const INVALID_INTEGER = 10;
+ const INVALID_DIGIT = 11;
+ const INVALID_INTEGERISH = 12;
+ const INVALID_BOOLEAN = 13;
+ const VALUE_EMPTY = 14;
+ const VALUE_NULL = 15;
+ const VALUE_NOT_NULL = 25;
+ const INVALID_STRING = 16;
+ const INVALID_REGEX = 17;
+ const INVALID_MIN_LENGTH = 18;
+ const INVALID_MAX_LENGTH = 19;
+ const INVALID_STRING_START = 20;
+ const INVALID_STRING_CONTAINS = 21;
+ const INVALID_CHOICE = 22;
+ const INVALID_NUMERIC = 23;
+ const INVALID_ARRAY = 24;
+ const INVALID_KEY_EXISTS = 26;
+ const INVALID_NOT_BLANK = 27;
+ const INVALID_INSTANCE_OF = 28;
+ const INVALID_SUBCLASS_OF = 29;
+ const INVALID_RANGE = 30;
+ const INVALID_ALNUM = 31;
+ const INVALID_TRUE = 32;
+ const INVALID_EQ = 33;
+ const INVALID_SAME = 34;
+ const INVALID_MIN = 35;
+ const INVALID_MAX = 36;
+ const INVALID_LENGTH = 37;
+ const INVALID_FALSE = 38;
+ const INVALID_STRING_END = 39;
+ const INVALID_UUID = 40;
+ const INVALID_COUNT = 41;
+ const INVALID_NOT_EQ = 42;
+ const INVALID_NOT_SAME = 43;
+ const INVALID_TRAVERSABLE = 44;
+ const INVALID_ARRAY_ACCESSIBLE = 45;
+ const INVALID_KEY_ISSET = 46;
+ const INVALID_VALUE_IN_ARRAY = 47;
+ const INVALID_E164 = 48;
+ const INVALID_BASE64 = 49;
+ const INVALID_NOT_REGEX = 50;
+ const INVALID_DIRECTORY = 101;
+ const INVALID_FILE = 102;
+ const INVALID_READABLE = 103;
+ const INVALID_WRITEABLE = 104;
+ const INVALID_CLASS = 105;
+ const INVALID_INTERFACE = 106;
+ const INVALID_FILE_NOT_EXISTS = 107;
+ const INVALID_EMAIL = 201;
+ const INTERFACE_NOT_IMPLEMENTED = 202;
+ const INVALID_URL = 203;
+ const INVALID_NOT_INSTANCE_OF = 204;
+ const VALUE_NOT_EMPTY = 205;
+ const INVALID_JSON_STRING = 206;
+ const INVALID_OBJECT = 207;
+ const INVALID_METHOD = 208;
+ const INVALID_SCALAR = 209;
+ const INVALID_LESS = 210;
+ const INVALID_LESS_OR_EQUAL = 211;
+ const INVALID_GREATER = 212;
+ const INVALID_GREATER_OR_EQUAL = 213;
+ const INVALID_DATE = 214;
+ const INVALID_CALLABLE = 215;
+ const INVALID_KEY_NOT_EXISTS = 216;
+ const INVALID_SATISFY = 217;
+ const INVALID_IP = 218;
+ const INVALID_BETWEEN = 219;
+ const INVALID_BETWEEN_EXCLUSIVE = 220;
+ const INVALID_EXTENSION = 222;
+ const INVALID_CONSTANT = 221;
+ const INVALID_VERSION = 223;
+ const INVALID_PROPERTY = 224;
+ const INVALID_RESOURCE = 225;
+ const INVALID_COUNTABLE = 226;
+ const INVALID_MIN_COUNT = 227;
+ const INVALID_MAX_COUNT = 228;
+ const INVALID_STRING_NOT_CONTAINS = 229;
+
+ /**
+ * Exception to throw when an assertion failed.
+ *
+ * @var string
+ */
+ protected static $exceptionClass = InvalidArgumentException::class;
+
+ /**
+ * Assert that two values are equal (using ==).
+ *
+ * @param mixed $value
+ * @param mixed $value2
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function eq($value, $value2, $message = null, string $propertyPath = null): bool
+ {
+ if ($value != $value2) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" does not equal expected value "%s".'),
+ static::stringify($value),
+ static::stringify($value2)
+ );
+
+ throw static::createException($value, $message, static::INVALID_EQ, $propertyPath, ['expected' => $value2]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the array contains the subset.
+ *
+ * @param mixed $value
+ * @param mixed $value2
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function eqArraySubset($value, $value2, $message = null, string $propertyPath = null): bool
+ {
+ static::isArray($value, $message, $propertyPath);
+ static::isArray($value2, $message, $propertyPath);
+
+ $patched = \array_replace_recursive($value, $value2);
+ static::eq($patched, $value, $message, $propertyPath);
+
+ return true;
+ }
+
+ /**
+ * Assert that two values are the same (using ===).
+ *
+ * @param mixed $value
+ * @param mixed $value2
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function same($value, $value2, $message = null, string $propertyPath = null): bool
+ {
+ if ($value !== $value2) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not the same as expected value "%s".'),
+ static::stringify($value),
+ static::stringify($value2)
+ );
+
+ throw static::createException($value, $message, static::INVALID_SAME, $propertyPath, ['expected' => $value2]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that two values are not equal (using ==).
+ *
+ * @param mixed $value1
+ * @param mixed $value2
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notEq($value1, $value2, $message = null, string $propertyPath = null): bool
+ {
+ if ($value1 == $value2) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" was not expected to be equal to value "%s".'),
+ static::stringify($value1),
+ static::stringify($value2)
+ );
+ throw static::createException($value1, $message, static::INVALID_NOT_EQ, $propertyPath, ['expected' => $value2]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that two values are not the same (using ===).
+ *
+ * @param mixed $value1
+ * @param mixed $value2
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notSame($value1, $value2, $message = null, string $propertyPath = null): bool
+ {
+ if ($value1 === $value2) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" was not expected to be the same as value "%s".'),
+ static::stringify($value1),
+ static::stringify($value2)
+ );
+ throw static::createException($value1, $message, static::INVALID_NOT_SAME, $propertyPath, ['expected' => $value2]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is not in array of choices.
+ *
+ * @param mixed $value
+ * @param array $choices
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notInArray($value, array $choices, $message = null, string $propertyPath = null): bool
+ {
+ if (true === \in_array($value, $choices)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" was not expected to be an element of the values: %s'),
+ static::stringify($value),
+ static::stringify($choices)
+ );
+ throw static::createException($value, $message, static::INVALID_VALUE_IN_ARRAY, $propertyPath, ['choices' => $choices]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is a php integer.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function integer($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_int($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not an integer.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_INTEGER, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is a php float.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function float($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_float($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not a float.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_FLOAT, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Validates if an integer or integerish is a digit.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function digit($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\ctype_digit((string)$value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not a digit.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_DIGIT, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is a php integer'ish.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function integerish($value, $message = null, string $propertyPath = null): bool
+ {
+ if (
+ \is_resource($value) ||
+ \is_object($value) ||
+ \is_bool($value) ||
+ \is_null($value) ||
+ \is_array($value) ||
+ (\is_string($value) && '' == $value) ||
+ (
+ \strval(\intval($value)) !== \strval($value) &&
+ \strval(\intval($value)) !== \strval(\ltrim($value, '0')) &&
+ '' !== \strval(\intval($value)) &&
+ '' !== \strval(\ltrim($value, '0'))
+ )
+ ) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not an integer or a number castable to integer.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_INTEGERISH, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is php boolean.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function boolean($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_bool($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not a boolean.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_BOOLEAN, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is a PHP scalar.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function scalar($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_scalar($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not a scalar.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_SCALAR, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is not empty.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notEmpty($value, $message = null, string $propertyPath = null): bool
+ {
+ if (empty($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is empty, but non empty value was expected.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::VALUE_EMPTY, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is empty.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function noContent($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!empty($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not empty, but empty value was expected.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::VALUE_NOT_EMPTY, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is null.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ */
+ public static function null($value, $message = null, string $propertyPath = null): bool
+ {
+ if (null !== $value) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not null, but null value was expected.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::VALUE_NOT_NULL, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is not null.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notNull($value, $message = null, string $propertyPath = null): bool
+ {
+ if (null === $value) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is null, but non null value was expected.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::VALUE_NULL, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is a string.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function string($value, $message = null, string $propertyPath = null)
+ {
+ if (!\is_string($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" expected to be string, type %s given.'),
+ static::stringify($value),
+ \gettype($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_STRING, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value matches a regex.
+ *
+ * @param mixed $value
+ * @param string $pattern
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function regex($value, $pattern, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ if (!\preg_match($pattern, $value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" does not match expression.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_REGEX, $propertyPath, ['pattern' => $pattern]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value does not match a regex.
+ *
+ * @param mixed $value
+ * @param string $pattern
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notRegex($value, $pattern, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ if (\preg_match($pattern, $value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" matches expression.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_NOT_REGEX, $propertyPath, ['pattern' => $pattern]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that string has a given length.
+ *
+ * @param mixed $value
+ * @param int $length
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ * @param string $encoding
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function length($value, $length, $message = null, string $propertyPath = null, $encoding = 'utf8'): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ if (\mb_strlen($value, $encoding) !== $length) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" has to be %d exactly characters long, but length is %d.'),
+ static::stringify($value),
+ $length,
+ \mb_strlen($value, $encoding)
+ );
+
+ throw static::createException($value, $message, static::INVALID_LENGTH, $propertyPath, ['length' => $length, 'encoding' => $encoding]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that a string is at least $minLength chars long.
+ *
+ * @param mixed $value
+ * @param int $minLength
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ * @param string $encoding
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function minLength($value, $minLength, $message = null, string $propertyPath = null, $encoding = 'utf8'): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ if (\mb_strlen($value, $encoding) < $minLength) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is too short, it should have at least %d characters, but only has %d characters.'),
+ static::stringify($value),
+ $minLength,
+ \mb_strlen($value, $encoding)
+ );
+
+ throw static::createException($value, $message, static::INVALID_MIN_LENGTH, $propertyPath, ['min_length' => $minLength, 'encoding' => $encoding]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that string value is not longer than $maxLength chars.
+ *
+ * @param mixed $value
+ * @param int $maxLength
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ * @param string $encoding
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function maxLength($value, $maxLength, $message = null, string $propertyPath = null, $encoding = 'utf8'): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ if (\mb_strlen($value, $encoding) > $maxLength) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is too long, it should have no more than %d characters, but has %d characters.'),
+ static::stringify($value),
+ $maxLength,
+ \mb_strlen($value, $encoding)
+ );
+
+ throw static::createException($value, $message, static::INVALID_MAX_LENGTH, $propertyPath, ['max_length' => $maxLength, 'encoding' => $encoding]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that string length is between min and max lengths.
+ *
+ * @param mixed $value
+ * @param int $minLength
+ * @param int $maxLength
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ * @param string $encoding
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function betweenLength($value, $minLength, $maxLength, $message = null, string $propertyPath = null, $encoding = 'utf8'): bool
+ {
+ static::string($value, $message, $propertyPath);
+ static::minLength($value, $minLength, $message, $propertyPath, $encoding);
+ static::maxLength($value, $maxLength, $message, $propertyPath, $encoding);
+
+ return true;
+ }
+
+ /**
+ * Assert that string starts with a sequence of chars.
+ *
+ * @param mixed $string
+ * @param string $needle
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ * @param string $encoding
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function startsWith($string, $needle, $message = null, string $propertyPath = null, $encoding = 'utf8'): bool
+ {
+ static::string($string, $message, $propertyPath);
+
+ if (0 !== \mb_strpos($string, $needle, null, $encoding)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" does not start with "%s".'),
+ static::stringify($string),
+ static::stringify($needle)
+ );
+
+ throw static::createException($string, $message, static::INVALID_STRING_START, $propertyPath, ['needle' => $needle, 'encoding' => $encoding]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that string ends with a sequence of chars.
+ *
+ * @param mixed $string
+ * @param string $needle
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ * @param string $encoding
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function endsWith($string, $needle, $message = null, string $propertyPath = null, $encoding = 'utf8'): bool
+ {
+ static::string($string, $message, $propertyPath);
+
+ $stringPosition = \mb_strlen($string, $encoding) - \mb_strlen($needle, $encoding);
+
+ if (\mb_strripos($string, $needle, null, $encoding) !== $stringPosition) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" does not end with "%s".'),
+ static::stringify($string),
+ static::stringify($needle)
+ );
+
+ throw static::createException($string, $message, static::INVALID_STRING_END, $propertyPath, ['needle' => $needle, 'encoding' => $encoding]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that string contains a sequence of chars.
+ *
+ * @param mixed $string
+ * @param string $needle
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ * @param string $encoding
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function contains($string, $needle, $message = null, string $propertyPath = null, $encoding = 'utf8'): bool
+ {
+ static::string($string, $message, $propertyPath);
+
+ if (false === \mb_strpos($string, $needle, null, $encoding)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" does not contain "%s".'),
+ static::stringify($string),
+ static::stringify($needle)
+ );
+
+ throw static::createException($string, $message, static::INVALID_STRING_CONTAINS, $propertyPath, ['needle' => $needle, 'encoding' => $encoding]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that string does not contains a sequence of chars.
+ *
+ * @param mixed $string
+ * @param string $needle
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ * @param string $encoding
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notContains($string, $needle, $message = null, string $propertyPath = null, $encoding = 'utf8'): bool
+ {
+ static::string($string, $message, $propertyPath);
+
+ if (false !== \mb_strpos($string, $needle, null, $encoding)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" contains "%s".'),
+ static::stringify($string),
+ static::stringify($needle)
+ );
+
+ throw static::createException($string, $message, static::INVALID_STRING_NOT_CONTAINS, $propertyPath, ['needle' => $needle, 'encoding' => $encoding]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is in array of choices.
+ *
+ * @param mixed $value
+ * @param array $choices
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function choice($value, array $choices, $message = null, string $propertyPath = null): bool
+ {
+ if (!\in_array($value, $choices, true)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not an element of the valid values: %s'),
+ static::stringify($value),
+ \implode(', ', \array_map([\get_called_class(), 'stringify'], $choices))
+ );
+
+ throw static::createException($value, $message, static::INVALID_CHOICE, $propertyPath, ['choices' => $choices]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is in array of choices.
+ *
+ * This is an alias of {@see choice()}.
+ *
+ * @param mixed $value
+ * @param array $choices
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function inArray($value, array $choices, $message = null, string $propertyPath = null): bool
+ {
+ return static::choice($value, $choices, $message, $propertyPath);
+ }
+
+ /**
+ * Assert that value is numeric.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function numeric($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_numeric($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not numeric.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_NUMERIC, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is a resource.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ */
+ public static function isResource($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_resource($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not a resource.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_RESOURCE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is an array.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function isArray($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_array($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not an array.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_ARRAY, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is an array or a traversable object.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function isTraversable($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_array($value) && !$value instanceof Traversable) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not an array and does not implement Traversable.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_TRAVERSABLE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is an array or an array-accessible object.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function isArrayAccessible($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_array($value) && !$value instanceof ArrayAccess) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not an array and does not implement ArrayAccess.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_ARRAY_ACCESSIBLE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is countable.
+ *
+ * @param array|Countable|ResourceBundle|SimpleXMLElement $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function isCountable($value, $message = null, string $propertyPath = null): bool
+ {
+ if (\function_exists('is_countable')) {
+ $assert = \is_countable($value);
+ } else {
+ $assert = \is_array($value) || $value instanceof Countable || $value instanceof ResourceBundle || $value instanceof SimpleXMLElement;
+ }
+
+ if (!$assert) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not an array and does not implement Countable.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_COUNTABLE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that key exists in an array.
+ *
+ * @param mixed $value
+ * @param string|int $key
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function keyExists($value, $key, $message = null, string $propertyPath = null): bool
+ {
+ static::isArray($value, $message, $propertyPath);
+
+ if (!\array_key_exists($key, $value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Array does not contain an element with key "%s"'),
+ static::stringify($key)
+ );
+
+ throw static::createException($value, $message, static::INVALID_KEY_EXISTS, $propertyPath, ['key' => $key]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that key does not exist in an array.
+ *
+ * @param mixed $value
+ * @param string|int $key
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function keyNotExists($value, $key, $message = null, string $propertyPath = null): bool
+ {
+ static::isArray($value, $message, $propertyPath);
+
+ if (\array_key_exists($key, $value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Array contains an element with key "%s"'),
+ static::stringify($key)
+ );
+
+ throw static::createException($value, $message, static::INVALID_KEY_NOT_EXISTS, $propertyPath, ['key' => $key]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that key exists in an array/array-accessible object using isset().
+ *
+ * @param mixed $value
+ * @param string|int $key
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function keyIsset($value, $key, $message = null, string $propertyPath = null): bool
+ {
+ static::isArrayAccessible($value, $message, $propertyPath);
+
+ if (!isset($value[$key])) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'The element with key "%s" was not found'),
+ static::stringify($key)
+ );
+
+ throw static::createException($value, $message, static::INVALID_KEY_ISSET, $propertyPath, ['key' => $key]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that key exists in an array/array-accessible object and its value is not empty.
+ *
+ * @param mixed $value
+ * @param string|int $key
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notEmptyKey($value, $key, $message = null, string $propertyPath = null): bool
+ {
+ static::keyIsset($value, $key, $message, $propertyPath);
+ static::notEmpty($value[$key], $message, $propertyPath);
+
+ return true;
+ }
+
+ /**
+ * Assert that value is not blank.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notBlank($value, $message = null, string $propertyPath = null): bool
+ {
+ if (false === $value || (empty($value) && '0' != $value) || (\is_string($value) && '' === \trim($value))) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is blank, but was expected to contain a value.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_NOT_BLANK, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is instance of given class-name.
+ *
+ * @param mixed $value
+ * @param string $className
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function isInstanceOf($value, $className, $message = null, string $propertyPath = null): bool
+ {
+ if (!($value instanceof $className)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Class "%s" was expected to be instanceof of "%s" but is not.'),
+ static::stringify($value),
+ $className
+ );
+
+ throw static::createException($value, $message, static::INVALID_INSTANCE_OF, $propertyPath, ['class' => $className]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is not instance of given class-name.
+ *
+ * @param mixed $value
+ * @param string $className
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function notIsInstanceOf($value, $className, $message = null, string $propertyPath = null): bool
+ {
+ if ($value instanceof $className) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Class "%s" was not expected to be instanceof of "%s".'),
+ static::stringify($value),
+ $className
+ );
+
+ throw static::createException($value, $message, static::INVALID_NOT_INSTANCE_OF, $propertyPath, ['class' => $className]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is subclass of given class-name.
+ *
+ * @param mixed $value
+ * @param string $className
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function subclassOf($value, $className, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_subclass_of($value, $className)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Class "%s" was expected to be subclass of "%s".'),
+ static::stringify($value),
+ $className
+ );
+
+ throw static::createException($value, $message, static::INVALID_SUBCLASS_OF, $propertyPath, ['class' => $className]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is in range of numbers.
+ *
+ * @param mixed $value
+ * @param mixed $minValue
+ * @param mixed $maxValue
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function range($value, $minValue, $maxValue, $message = null, string $propertyPath = null): bool
+ {
+ static::numeric($value, $message, $propertyPath);
+
+ if ($value < $minValue || $value > $maxValue) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Number "%s" was expected to be at least "%d" and at most "%d".'),
+ static::stringify($value),
+ static::stringify($minValue),
+ static::stringify($maxValue)
+ );
+
+ throw static::createException($value, $message, static::INVALID_RANGE, $propertyPath, ['min' => $minValue, 'max' => $maxValue]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that a value is at least as big as a given limit.
+ *
+ * @param mixed $value
+ * @param mixed $minValue
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function min($value, $minValue, $message = null, string $propertyPath = null): bool
+ {
+ static::numeric($value, $message, $propertyPath);
+
+ if ($value < $minValue) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Number "%s" was expected to be at least "%s".'),
+ static::stringify($value),
+ static::stringify($minValue)
+ );
+
+ throw static::createException($value, $message, static::INVALID_MIN, $propertyPath, ['min' => $minValue]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that a number is smaller as a given limit.
+ *
+ * @param mixed $value
+ * @param mixed $maxValue
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function max($value, $maxValue, $message = null, string $propertyPath = null): bool
+ {
+ static::numeric($value, $message, $propertyPath);
+
+ if ($value > $maxValue) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Number "%s" was expected to be at most "%s".'),
+ static::stringify($value),
+ static::stringify($maxValue)
+ );
+
+ throw static::createException($value, $message, static::INVALID_MAX, $propertyPath, ['max' => $maxValue]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that a file exists.
+ *
+ * @param string $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function file($value, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+ static::notEmpty($value, $message, $propertyPath);
+
+ if (!\is_file($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'File "%s" was expected to exist.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_FILE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that a directory exists.
+ *
+ * @param string $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function directory($value, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ if (!\is_dir($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Path "%s" was expected to be a directory.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_DIRECTORY, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the value is something readable.
+ *
+ * @param string $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function readable($value, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ if (!\is_readable($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Path "%s" was expected to be readable.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_READABLE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the value is something writeable.
+ *
+ * @param string $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function writeable($value, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ if (!\is_writable($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Path "%s" was expected to be writeable.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_WRITEABLE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL).
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function email($value, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ if (!\filter_var($value, FILTER_VALIDATE_EMAIL)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" was expected to be a valid e-mail address.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_EMAIL, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is an URL.
+ *
+ * This code snipped was taken from the Symfony project and modified to the special demands of this method.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ *
+ * @see https://github.com/symfony/Validator/blob/master/Constraints/UrlValidator.php
+ * @see https://github.com/symfony/Validator/blob/master/Constraints/Url.php
+ */
+ public static function url($value, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+
+ $protocols = ['http', 'https'];
+
+ $pattern = '~^
+ (%s):// # protocol
+ (([\.\pL\pN-]+:)?([\.\pL\pN-]+)@)? # basic auth
+ (
+ ([\pL\pN\pS\-\.])+(\.?([\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
+ | # or
+ \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address
+ | # or
+ \[
+ (?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::))))
+ \] # an IPv6 address
+ )
+ (:[0-9]+)? # a port (optional)
+ (?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path
+ (?:\? (?:[\pL\pN\-._\~!$&\'\[\]()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a query (optional)
+ (?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional)
+ $~ixu';
+
+ $pattern = \sprintf($pattern, \implode('|', $protocols));
+
+ if (!\preg_match($pattern, $value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" was expected to be a valid URL starting with http or https'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_URL, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is alphanumeric.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function alnum($value, $message = null, string $propertyPath = null): bool
+ {
+ try {
+ static::regex($value, '(^([a-zA-Z]{1}[a-zA-Z0-9]*)$)', $message, $propertyPath);
+ } catch (Throwable $e) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not alphanumeric, starting with letters and containing only letters and numbers.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_ALNUM, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the value is boolean True.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function true($value, $message = null, string $propertyPath = null): bool
+ {
+ if (true !== $value) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not TRUE.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_TRUE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the value is boolean False.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function false($value, $message = null, string $propertyPath = null): bool
+ {
+ if (false !== $value) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not FALSE.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_FALSE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the class exists.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function classExists($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\class_exists($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Class "%s" does not exist.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_CLASS, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the interface exists.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function interfaceExists($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\interface_exists($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Interface "%s" does not exist.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_INTERFACE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the class implements the interface.
+ *
+ * @param mixed $class
+ * @param string $interfaceName
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function implementsInterface($class, $interfaceName, $message = null, string $propertyPath = null): bool
+ {
+ try {
+ $reflection = new ReflectionClass($class);
+ if (!$reflection->implementsInterface($interfaceName)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Class "%s" does not implement interface "%s".'),
+ static::stringify($class),
+ static::stringify($interfaceName)
+ );
+
+ throw static::createException($class, $message, static::INTERFACE_NOT_IMPLEMENTED, $propertyPath, ['interface' => $interfaceName]);
+ }
+ } catch (ReflectionException $e) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Class "%s" failed reflection.'),
+ static::stringify($class)
+ );
+ throw static::createException($class, $message, static::INTERFACE_NOT_IMPLEMENTED, $propertyPath, ['interface' => $interfaceName]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the given string is a valid json string.
+ *
+ * NOTICE:
+ * Since this does a json_decode to determine its validity
+ * you probably should consider, when using the variable
+ * content afterwards, just to decode and check for yourself instead
+ * of using this assertion.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function isJsonString($value, $message = null, string $propertyPath = null): bool
+ {
+ if (null === \json_decode($value) && JSON_ERROR_NONE !== \json_last_error()) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not a valid JSON string.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_JSON_STRING, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the given string is a valid UUID.
+ *
+ * Uses code from {@link https://github.com/ramsey/uuid} that is MIT licensed.
+ *
+ * @param string $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function uuid($value, $message = null, string $propertyPath = null): bool
+ {
+ $value = \str_replace(['urn:', 'uuid:', '{', '}'], '', $value);
+
+ if ('00000000-0000-0000-0000-000000000000' === $value) {
+ return true;
+ }
+
+ if (!\preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not a valid UUID.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_UUID, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the given string is a valid E164 Phone Number.
+ *
+ * @see https://en.wikipedia.org/wiki/E.164
+ *
+ * @param string $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function e164($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\preg_match('/^\+?[1-9]\d{1,14}$/', $value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" is not a valid E164.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_E164, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the count of countable is equal to count.
+ *
+ * @param array|Countable|ResourceBundle|SimpleXMLElement $countable
+ * @param int $count
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function count($countable, $count, $message = null, string $propertyPath = null): bool
+ {
+ if ($count !== \count($countable)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'List does not contain exactly %d elements (%d given).'),
+ static::stringify($count),
+ static::stringify(\count($countable))
+ );
+
+ throw static::createException($countable, $message, static::INVALID_COUNT, $propertyPath, ['count' => $count]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the countable have at least $count elements.
+ *
+ * @param array|Countable|ResourceBundle|SimpleXMLElement $countable
+ * @param int $count
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function minCount($countable, $count, $message = null, string $propertyPath = null): bool
+ {
+ if ($count > \count($countable)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'List should have at least %d elements, but has %d elements.'),
+ static::stringify($count),
+ static::stringify(\count($countable))
+ );
+
+ throw static::createException($countable, $message, static::INVALID_MIN_COUNT, $propertyPath, ['count' => $count]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the countable have at most $count elements.
+ *
+ * @param array|Countable|ResourceBundle|SimpleXMLElement $countable
+ * @param int $count
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function maxCount($countable, $count, $message = null, string $propertyPath = null): bool
+ {
+ if ($count < \count($countable)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'List should have at most %d elements, but has %d elements.'),
+ static::stringify($count),
+ static::stringify(\count($countable))
+ );
+
+ throw static::createException($countable, $message, static::INVALID_MAX_COUNT, $propertyPath, ['count' => $count]);
+ }
+
+ return true;
+ }
+
+ /**
+ * static call handler to implement:
+ * - "null or assertion" delegation
+ * - "all" delegation.
+ *
+ * @param string $method
+ * @param array $args
+ *
+ * @return bool|mixed
+ *
+ * @throws AssertionFailedException
+ */
+ public static function __callStatic($method, $args)
+ {
+ if (0 === \strpos($method, 'nullOr')) {
+ if (!\array_key_exists(0, $args)) {
+ throw new BadMethodCallException('Missing the first argument.');
+ }
+
+ if (null === $args[0]) {
+ return true;
+ }
+
+ $method = \substr($method, 6);
+
+ return \call_user_func_array([\get_called_class(), $method], $args);
+ }
+
+ if (0 === \strpos($method, 'all')) {
+ if (!\array_key_exists(0, $args)) {
+ throw new BadMethodCallException('Missing the first argument.');
+ }
+
+ static::isTraversable($args[0]);
+
+ $method = \substr($method, 3);
+ $values = \array_shift($args);
+ $calledClass = \get_called_class();
+
+ foreach ($values as $value) {
+ \call_user_func_array([$calledClass, $method], \array_merge([$value], $args));
+ }
+
+ return true;
+ }
+
+ throw new BadMethodCallException('No assertion Assertion#'.$method.' exists.');
+ }
+
+ /**
+ * Determines if the values array has every choice as key and that this choice has content.
+ *
+ * @param array $values
+ * @param array $choices
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function choicesNotEmpty(array $values, array $choices, $message = null, string $propertyPath = null): bool
+ {
+ static::notEmpty($values, $message, $propertyPath);
+
+ foreach ($choices as $choice) {
+ static::notEmptyKey($values, $choice, $message, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines that the named method is defined in the provided object.
+ *
+ * @param string $value
+ * @param mixed $object
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function methodExists($value, $object, $message = null, string $propertyPath = null): bool
+ {
+ static::isObject($object, $message, $propertyPath);
+
+ if (!\method_exists($object, $value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Expected "%s" does not exist in provided object.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_METHOD, $propertyPath, ['object' => \get_class($object)]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines that the provided value is an object.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function isObject($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_object($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Provided "%s" is not a valid object.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_OBJECT, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines if the value is less than given limit.
+ *
+ * @param mixed $value
+ * @param mixed $limit
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function lessThan($value, $limit, $message = null, string $propertyPath = null): bool
+ {
+ if ($value >= $limit) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Provided "%s" is not less than "%s".'),
+ static::stringify($value),
+ static::stringify($limit)
+ );
+
+ throw static::createException($value, $message, static::INVALID_LESS, $propertyPath, ['limit' => $limit]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines if the value is less or equal than given limit.
+ *
+ * @param mixed $value
+ * @param mixed $limit
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function lessOrEqualThan($value, $limit, $message = null, string $propertyPath = null): bool
+ {
+ if ($value > $limit) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Provided "%s" is not less or equal than "%s".'),
+ static::stringify($value),
+ static::stringify($limit)
+ );
+
+ throw static::createException($value, $message, static::INVALID_LESS_OR_EQUAL, $propertyPath, ['limit' => $limit]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines if the value is greater than given limit.
+ *
+ * @param mixed $value
+ * @param mixed $limit
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function greaterThan($value, $limit, $message = null, string $propertyPath = null): bool
+ {
+ if ($value <= $limit) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Provided "%s" is not greater than "%s".'),
+ static::stringify($value),
+ static::stringify($limit)
+ );
+
+ throw static::createException($value, $message, static::INVALID_GREATER, $propertyPath, ['limit' => $limit]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Determines if the value is greater or equal than given limit.
+ *
+ * @param mixed $value
+ * @param mixed $limit
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function greaterOrEqualThan($value, $limit, $message = null, string $propertyPath = null): bool
+ {
+ if ($value < $limit) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Provided "%s" is not greater or equal than "%s".'),
+ static::stringify($value),
+ static::stringify($limit)
+ );
+
+ throw static::createException($value, $message, static::INVALID_GREATER_OR_EQUAL, $propertyPath, ['limit' => $limit]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit.
+ *
+ * @param mixed $value
+ * @param mixed $lowerLimit
+ * @param mixed $upperLimit
+ * @param string|callable|null $message
+ * @param string $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function between($value, $lowerLimit, $upperLimit, $message = null, string $propertyPath = null): bool
+ {
+ if ($lowerLimit > $value || $value > $upperLimit) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Provided "%s" is neither greater than or equal to "%s" nor less than or equal to "%s".'),
+ static::stringify($value),
+ static::stringify($lowerLimit),
+ static::stringify($upperLimit)
+ );
+
+ throw static::createException($value, $message, static::INVALID_BETWEEN, $propertyPath, ['lower' => $lowerLimit, 'upper' => $upperLimit]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that a value is greater than a lower limit, and less than an upper limit.
+ *
+ * @param mixed $value
+ * @param mixed $lowerLimit
+ * @param mixed $upperLimit
+ * @param string|callable|null $message
+ * @param string $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function betweenExclusive($value, $lowerLimit, $upperLimit, $message = null, string $propertyPath = null): bool
+ {
+ if ($lowerLimit >= $value || $value >= $upperLimit) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Provided "%s" is neither greater than "%s" nor less than "%s".'),
+ static::stringify($value),
+ static::stringify($lowerLimit),
+ static::stringify($upperLimit)
+ );
+
+ throw static::createException($value, $message, static::INVALID_BETWEEN_EXCLUSIVE, $propertyPath, ['lower' => $lowerLimit, 'upper' => $upperLimit]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that extension is loaded.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function extensionLoaded($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\extension_loaded($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Extension "%s" is required.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_EXTENSION, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that date is valid and corresponds to the given format.
+ *
+ * @param string $value
+ * @param string $format supports all of the options date(), except for the following:
+ * N, w, W, t, L, o, B, a, A, g, h, I, O, P, Z, c, r
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ *
+ * @see http://php.net/manual/function.date.php#refsect1-function.date-parameters
+ */
+ public static function date($value, $format, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+ static::string($format, $message, $propertyPath);
+
+ $dateTime = DateTime::createFromFormat('!'.$format, $value);
+
+ if (false === $dateTime || $value !== $dateTime->format($format)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Date "%s" is invalid or does not match format "%s".'),
+ static::stringify($value),
+ static::stringify($format)
+ );
+
+ throw static::createException($value, $message, static::INVALID_DATE, $propertyPath, ['format' => $format]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the value is an object, or a class that exists.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function objectOrClass($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_object($value)) {
+ static::classExists($value, $message, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the value is an object or class, and that the property exists.
+ *
+ * @param mixed $value
+ * @param string $property
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function propertyExists($value, $property, $message = null, string $propertyPath = null): bool
+ {
+ static::objectOrClass($value);
+
+ if (!\property_exists($value, $property)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Class "%s" does not have property "%s".'),
+ static::stringify($value),
+ static::stringify($property)
+ );
+
+ throw static::createException($value, $message, static::INVALID_PROPERTY, $propertyPath, ['property' => $property]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the value is an object or class, and that the properties all exist.
+ *
+ * @param mixed $value
+ * @param array $properties
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function propertiesExist($value, array $properties, $message = null, string $propertyPath = null): bool
+ {
+ static::objectOrClass($value);
+ static::allString($properties, $message, $propertyPath);
+
+ $invalidProperties = [];
+ foreach ($properties as $property) {
+ if (!\property_exists($value, $property)) {
+ $invalidProperties[] = $property;
+ }
+ }
+
+ if ($invalidProperties) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Class "%s" does not have these properties: %s.'),
+ static::stringify($value),
+ static::stringify(\implode(', ', $invalidProperties))
+ );
+
+ throw static::createException($value, $message, static::INVALID_PROPERTY, $propertyPath, ['properties' => $properties]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert comparison of two versions.
+ *
+ * @param string $version1
+ * @param string $operator
+ * @param string $version2
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function version($version1, $operator, $version2, $message = null, string $propertyPath = null): bool
+ {
+ static::notEmpty($operator, 'versionCompare operator is required and cannot be empty.');
+
+ if (true !== \version_compare($version1, $version2, $operator)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Version "%s" is not "%s" version "%s".'),
+ static::stringify($version1),
+ static::stringify($operator),
+ static::stringify($version2)
+ );
+
+ throw static::createException($version1, $message, static::INVALID_VERSION, $propertyPath, ['operator' => $operator, 'version' => $version2]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert on PHP version.
+ *
+ * @param string $operator
+ * @param mixed $version
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function phpVersion($operator, $version, $message = null, string $propertyPath = null): bool
+ {
+ static::defined('PHP_VERSION');
+
+ return static::version(PHP_VERSION, $operator, $version, $message, $propertyPath);
+ }
+
+ /**
+ * Assert that extension is loaded and a specific version is installed.
+ *
+ * @param string $extension
+ * @param string $operator
+ * @param mixed $version
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function extensionVersion($extension, $operator, $version, $message = null, string $propertyPath = null): bool
+ {
+ static::extensionLoaded($extension, $message, $propertyPath);
+
+ return static::version(\phpversion($extension), $operator, $version, $message, $propertyPath);
+ }
+
+ /**
+ * Determines that the provided value is callable.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function isCallable($value, $message = null, string $propertyPath = null): bool
+ {
+ if (!\is_callable($value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Provided "%s" is not a callable.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_CALLABLE, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that the provided value is valid according to a callback.
+ *
+ * If the callback returns `false` the assertion will fail.
+ *
+ * @param mixed $value
+ * @param callable $callback
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function satisfy($value, $callback, $message = null, string $propertyPath = null): bool
+ {
+ static::isCallable($callback);
+
+ if (false === \call_user_func($callback, $value)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Provided "%s" is invalid according to custom rule.'),
+ static::stringify($value)
+ );
+
+ throw static::createException($value, $message, static::INVALID_SATISFY, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is an IPv4 or IPv6 address
+ * (using input_filter/FILTER_VALIDATE_IP).
+ *
+ * @param string $value
+ * @param int|null $flag
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ *
+ * @see http://php.net/manual/filter.filters.flags.php
+ */
+ public static function ip($value, $flag = null, $message = null, string $propertyPath = null): bool
+ {
+ static::string($value, $message, $propertyPath);
+ if (!\filter_var($value, FILTER_VALIDATE_IP, $flag)) {
+ $message = \sprintf(
+ static::generateMessage($message ?: 'Value "%s" was expected to be a valid IP address.'),
+ static::stringify($value)
+ );
+ throw static::createException($value, $message, static::INVALID_IP, $propertyPath, ['flag' => $flag]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that value is an IPv4 address
+ * (using input_filter/FILTER_VALIDATE_IP).
+ *
+ * @param string $value
+ * @param int|null $flag
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ *
+ * @see http://php.net/manual/filter.filters.flags.php
+ */
+ public static function ipv4($value, $flag = null, $message = null, string $propertyPath = null): bool
+ {
+ static::ip($value, $flag | FILTER_FLAG_IPV4, static::generateMessage($message ?: 'Value "%s" was expected to be a valid IPv4 address.'), $propertyPath);
+
+ return true;
+ }
+
+ /**
+ * Assert that value is an IPv6 address
+ * (using input_filter/FILTER_VALIDATE_IP).
+ *
+ * @param string $value
+ * @param int|null $flag
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ *
+ * @see http://php.net/manual/filter.filters.flags.php
+ */
+ public static function ipv6($value, $flag = null, $message = null, string $propertyPath = null): bool
+ {
+ static::ip($value, $flag | FILTER_FLAG_IPV6, static::generateMessage($message ?: 'Value "%s" was expected to be a valid IPv6 address.'), $propertyPath);
+
+ return true;
+ }
+
+ /**
+ * Assert that a constant is defined.
+ *
+ * @param mixed $constant
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ */
+ public static function defined($constant, $message = null, string $propertyPath = null): bool
+ {
+ if (!\defined($constant)) {
+ $message = \sprintf(static::generateMessage($message ?: 'Value "%s" expected to be a defined constant.'), $constant);
+
+ throw static::createException($constant, $message, static::INVALID_CONSTANT, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Assert that a constant is defined.
+ *
+ * @param string $value
+ * @param string|callable|null $message
+ * @param string|null $propertyPath
+ *
+ * @return bool
+ *
+ * @throws AssertionFailedException
+ */
+ public static function base64($value, $message = null, string $propertyPath = null): bool
+ {
+ if (false === \base64_decode($value, true)) {
+ $message = \sprintf(static::generateMessage($message ?: 'Value "%s" is not a valid base64 string.'), $value);
+
+ throw static::createException($value, $message, static::INVALID_BASE64, $propertyPath);
+ }
+
+ return true;
+ }
+
+ /**
+ * Helper method that handles building the assertion failure exceptions.
+ * They are returned from this method so that the stack trace still shows
+ * the assertions method.
+ *
+ * @param mixed $value
+ * @param string|callable|null $message
+ * @param int $code
+ * @param string|null $propertyPath
+ * @param array $constraints
+ *
+ * @return mixed
+ */
+ protected static function createException($value, $message, $code, $propertyPath = null, array $constraints = [])
+ {
+ $exceptionClass = static::$exceptionClass;
+
+ return new $exceptionClass($message, $code, $propertyPath, $value, $constraints);
+ }
+
+ /**
+ * Make a string version of a value.
+ *
+ * @param mixed $value
+ *
+ * @return string
+ */
+ protected static function stringify($value): string
+ {
+ $result = \gettype($value);
+
+ if (\is_bool($value)) {
+ $result = $value ? '' : '';
+ } elseif (\is_scalar($value)) {
+ $val = (string)$value;
+
+ if (\mb_strlen($val) > 100) {
+ $val = \mb_substr($val, 0, 97).'...';
+ }
+
+ $result = $val;
+ } elseif (\is_array($value)) {
+ $result = '';
+ } elseif (\is_object($value)) {
+ $result = \get_class($value);
+ } elseif (\is_resource($value)) {
+ $result = \get_resource_type($value);
+ } elseif (null === $value) {
+ $result = '';
+ }
+
+ return $result;
+ }
+
+ /**
+ * Generate the message.
+ *
+ * @param string|callable|null $message
+ *
+ * @return string
+ */
+ protected static function generateMessage($message): string
+ {
+ if (\is_callable($message)) {
+ $traces = \debug_backtrace(0);
+
+ $parameters = [];
+
+ try {
+ $reflection = new ReflectionClass($traces[1]['class']);
+ $method = $reflection->getMethod($traces[1]['function']);
+ foreach ($method->getParameters() as $index => $parameter) {
+ if ('message' !== $parameter->getName()) {
+ $parameters[$parameter->getName()] = \array_key_exists($index, $traces[1]['args'])
+ ? $traces[1]['args'][$index]
+ : $parameter->getDefaultValue();
+ }
+ }
+
+ $parameters['::assertion'] = \sprintf('%s%s%s', $traces[1]['class'], $traces[1]['type'], $traces[1]['function']);
+
+ $message = \call_user_func_array($message, [$parameters]);
+ } // @codeCoverageIgnoreStart
+ catch (Throwable $exception) {
+ $message = \sprintf('Unable to generate message : %s', $exception->getMessage());
+ } // @codeCoverageIgnoreEnd
+ }
+
+ return (string)$message;
+ }
+}
diff --git a/vendor/beberlei/assert/lib/Assert/AssertionChain.php b/vendor/beberlei/assert/lib/Assert/AssertionChain.php
new file mode 100644
index 000000000..dbb6e839b
--- /dev/null
+++ b/vendor/beberlei/assert/lib/Assert/AssertionChain.php
@@ -0,0 +1,254 @@
+
+ *
+ * @method AssertionChain alnum(string|callable $message = null, string $propertyPath = null) Assert that value is alphanumeric.
+ * @method AssertionChain base64(string|callable $message = null, string $propertyPath = null) Assert that a constant is defined.
+ * @method AssertionChain between(mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit.
+ * @method AssertionChain betweenExclusive(mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater than a lower limit, and less than an upper limit.
+ * @method AssertionChain betweenLength(int $minLength, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string length is between min and max lengths.
+ * @method AssertionChain boolean(string|callable $message = null, string $propertyPath = null) Assert that value is php boolean.
+ * @method AssertionChain choice(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices.
+ * @method AssertionChain choicesNotEmpty(array $choices, string|callable $message = null, string $propertyPath = null) Determines if the values array has every choice as key and that this choice has content.
+ * @method AssertionChain classExists(string|callable $message = null, string $propertyPath = null) Assert that the class exists.
+ * @method AssertionChain contains(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string contains a sequence of chars.
+ * @method AssertionChain count(int $count, string|callable $message = null, string $propertyPath = null) Assert that the count of countable is equal to count.
+ * @method AssertionChain date(string $format, string|callable $message = null, string $propertyPath = null) Assert that date is valid and corresponds to the given format.
+ * @method AssertionChain defined(string|callable $message = null, string $propertyPath = null) Assert that a constant is defined.
+ * @method AssertionChain digit(string|callable $message = null, string $propertyPath = null) Validates if an integer or integerish is a digit.
+ * @method AssertionChain directory(string|callable $message = null, string $propertyPath = null) Assert that a directory exists.
+ * @method AssertionChain e164(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid E164 Phone Number.
+ * @method AssertionChain email(string|callable $message = null, string $propertyPath = null) Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL).
+ * @method AssertionChain endsWith(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string ends with a sequence of chars.
+ * @method AssertionChain eq(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are equal (using ==).
+ * @method AssertionChain eqArraySubset(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that the array contains the subset.
+ * @method AssertionChain extensionLoaded(string|callable $message = null, string $propertyPath = null) Assert that extension is loaded.
+ * @method AssertionChain extensionVersion(string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded and a specific version is installed.
+ * @method AssertionChain false(string|callable $message = null, string $propertyPath = null) Assert that the value is boolean False.
+ * @method AssertionChain file(string|callable $message = null, string $propertyPath = null) Assert that a file exists.
+ * @method AssertionChain float(string|callable $message = null, string $propertyPath = null) Assert that value is a php float.
+ * @method AssertionChain greaterOrEqualThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater or equal than given limit.
+ * @method AssertionChain greaterThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater than given limit.
+ * @method AssertionChain implementsInterface(string $interfaceName, string|callable $message = null, string $propertyPath = null) Assert that the class implements the interface.
+ * @method AssertionChain inArray(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices. This is an alias of Assertion::choice().
+ * @method AssertionChain integer(string|callable $message = null, string $propertyPath = null) Assert that value is a php integer.
+ * @method AssertionChain integerish(string|callable $message = null, string $propertyPath = null) Assert that value is a php integer'ish.
+ * @method AssertionChain interfaceExists(string|callable $message = null, string $propertyPath = null) Assert that the interface exists.
+ * @method AssertionChain ip(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 or IPv6 address.
+ * @method AssertionChain ipv4(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 address.
+ * @method AssertionChain ipv6(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv6 address.
+ * @method AssertionChain isArray(string|callable $message = null, string $propertyPath = null) Assert that value is an array.
+ * @method AssertionChain isArrayAccessible(string|callable $message = null, string $propertyPath = null) Assert that value is an array or an array-accessible object.
+ * @method AssertionChain isCallable(string|callable $message = null, string $propertyPath = null) Determines that the provided value is callable.
+ * @method AssertionChain isCountable(string|callable $message = null, string $propertyPath = null) Assert that value is countable.
+ * @method AssertionChain isInstanceOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is instance of given class-name.
+ * @method AssertionChain isJsonString(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid json string.
+ * @method AssertionChain isObject(string|callable $message = null, string $propertyPath = null) Determines that the provided value is an object.
+ * @method AssertionChain isResource(string|callable $message = null, string $propertyPath = null) Assert that value is a resource.
+ * @method AssertionChain isTraversable(string|callable $message = null, string $propertyPath = null) Assert that value is an array or a traversable object.
+ * @method AssertionChain keyExists(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array.
+ * @method AssertionChain keyIsset(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object using isset().
+ * @method AssertionChain keyNotExists(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key does not exist in an array.
+ * @method AssertionChain length(int $length, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string has a given length.
+ * @method AssertionChain lessOrEqualThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less or equal than given limit.
+ * @method AssertionChain lessThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less than given limit.
+ * @method AssertionChain max(mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that a number is smaller as a given limit.
+ * @method AssertionChain maxCount(int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at most $count elements.
+ * @method AssertionChain maxLength(int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string value is not longer than $maxLength chars.
+ * @method AssertionChain methodExists(mixed $object, string|callable $message = null, string $propertyPath = null) Determines that the named method is defined in the provided object.
+ * @method AssertionChain min(mixed $minValue, string|callable $message = null, string $propertyPath = null) Assert that a value is at least as big as a given limit.
+ * @method AssertionChain minCount(int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at least $count elements.
+ * @method AssertionChain minLength(int $minLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that a string is at least $minLength chars long.
+ * @method AssertionChain noContent(string|callable $message = null, string $propertyPath = null) Assert that value is empty.
+ * @method AssertionChain notBlank(string|callable $message = null, string $propertyPath = null) Assert that value is not blank.
+ * @method AssertionChain notContains(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string does not contains a sequence of chars.
+ * @method AssertionChain notEmpty(string|callable $message = null, string $propertyPath = null) Assert that value is not empty.
+ * @method AssertionChain notEmptyKey(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object and its value is not empty.
+ * @method AssertionChain notEq(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not equal (using ==).
+ * @method AssertionChain notInArray(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is not in array of choices.
+ * @method AssertionChain notIsInstanceOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is not instance of given class-name.
+ * @method AssertionChain notNull(string|callable $message = null, string $propertyPath = null) Assert that value is not null.
+ * @method AssertionChain notRegex(string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value does not match a regex.
+ * @method AssertionChain notSame(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not the same (using ===).
+ * @method AssertionChain null(string|callable $message = null, string $propertyPath = null) Assert that value is null.
+ * @method AssertionChain numeric(string|callable $message = null, string $propertyPath = null) Assert that value is numeric.
+ * @method AssertionChain objectOrClass(string|callable $message = null, string $propertyPath = null) Assert that the value is an object, or a class that exists.
+ * @method AssertionChain phpVersion(mixed $version, string|callable $message = null, string $propertyPath = null) Assert on PHP version.
+ * @method AssertionChain propertiesExist(array $properties, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the properties all exist.
+ * @method AssertionChain propertyExists(string $property, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the property exists.
+ * @method AssertionChain range(mixed $minValue, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that value is in range of numbers.
+ * @method AssertionChain readable(string|callable $message = null, string $propertyPath = null) Assert that the value is something readable.
+ * @method AssertionChain regex(string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value matches a regex.
+ * @method AssertionChain same(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are the same (using ===).
+ * @method AssertionChain satisfy(callable $callback, string|callable $message = null, string $propertyPath = null) Assert that the provided value is valid according to a callback.
+ * @method AssertionChain scalar(string|callable $message = null, string $propertyPath = null) Assert that value is a PHP scalar.
+ * @method AssertionChain startsWith(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string starts with a sequence of chars.
+ * @method AssertionChain string(string|callable $message = null, string $propertyPath = null) Assert that value is a string.
+ * @method AssertionChain subclassOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is subclass of given class-name.
+ * @method AssertionChain true(string|callable $message = null, string $propertyPath = null) Assert that the value is boolean True.
+ * @method AssertionChain url(string|callable $message = null, string $propertyPath = null) Assert that value is an URL.
+ * @method AssertionChain uuid(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid UUID.
+ * @method AssertionChain version(string $operator, string $version2, string|callable $message = null, string $propertyPath = null) Assert comparison of two versions.
+ * @method AssertionChain writeable(string|callable $message = null, string $propertyPath = null) Assert that the value is something writeable.
+ */
+class AssertionChain
+{
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ /**
+ * @var string|callable|null
+ */
+ private $defaultMessage;
+
+ /**
+ * @var string|null
+ */
+ private $defaultPropertyPath;
+
+ /**
+ * Return each assertion as always valid.
+ *
+ * @var bool
+ */
+ private $alwaysValid = false;
+
+ /**
+ * Perform assertion on every element of array or traversable.
+ *
+ * @var bool
+ */
+ private $all = false;
+
+ /** @var string|Assertion Class to use for assertion calls */
+ private $assertionClassName = 'Assert\Assertion';
+
+ /**
+ * AssertionChain constructor.
+ *
+ * @param mixed $value
+ * @param string|callable|null $defaultMessage
+ * @param string|null $defaultPropertyPath
+ */
+ public function __construct($value, $defaultMessage = null, string $defaultPropertyPath = null)
+ {
+ $this->value = $value;
+ $this->defaultMessage = $defaultMessage;
+ $this->defaultPropertyPath = $defaultPropertyPath;
+ }
+
+ /**
+ * Call assertion on the current value in the chain.
+ *
+ * @param string $methodName
+ * @param array $args
+ *
+ * @return AssertionChain
+ */
+ public function __call($methodName, $args): AssertionChain
+ {
+ if (true === $this->alwaysValid) {
+ return $this;
+ }
+
+ if (!\method_exists($this->assertionClassName, $methodName)) {
+ throw new \RuntimeException("Assertion '".$methodName."' does not exist.");
+ }
+
+ $reflClass = new ReflectionClass($this->assertionClassName);
+ $method = $reflClass->getMethod($methodName);
+
+ \array_unshift($args, $this->value);
+ $params = $method->getParameters();
+
+ foreach ($params as $idx => $param) {
+ if (isset($args[$idx])) {
+ continue;
+ }
+
+ if ('message' == $param->getName()) {
+ $args[$idx] = $this->defaultMessage;
+ }
+
+ if ('propertyPath' == $param->getName()) {
+ $args[$idx] = $this->defaultPropertyPath;
+ }
+ }
+
+ if ($this->all) {
+ $methodName = 'all'.$methodName;
+ }
+
+ \call_user_func_array([$this->assertionClassName, $methodName], $args);
+
+ return $this;
+ }
+
+ /**
+ * Switch chain into validation mode for an array of values.
+ *
+ * @return AssertionChain
+ */
+ public function all(): AssertionChain
+ {
+ $this->all = true;
+
+ return $this;
+ }
+
+ /**
+ * Switch chain into mode allowing nulls, ignoring further assertions.
+ *
+ * @return AssertionChain
+ */
+ public function nullOr(): AssertionChain
+ {
+ if (null === $this->value) {
+ $this->alwaysValid = true;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param string $className
+ *
+ * @return $this
+ */
+ public function setAssertionClassName($className): AssertionChain
+ {
+ if (!\is_string($className)) {
+ throw new LogicException('Exception class name must be passed as a string');
+ }
+
+ if (Assertion::class !== $className && !\is_subclass_of($className, Assertion::class)) {
+ throw new LogicException($className.' is not (a subclass of) '.Assertion::class);
+ }
+
+ $this->assertionClassName = $className;
+
+ return $this;
+ }
+}
diff --git a/vendor/beberlei/assert/lib/Assert/AssertionFailedException.php b/vendor/beberlei/assert/lib/Assert/AssertionFailedException.php
new file mode 100644
index 000000000..c18483884
--- /dev/null
+++ b/vendor/beberlei/assert/lib/Assert/AssertionFailedException.php
@@ -0,0 +1,35 @@
+propertyPath = $propertyPath;
+ $this->value = $value;
+ $this->constraints = $constraints;
+ }
+
+ /**
+ * User controlled way to define a sub-property causing
+ * the failure of a currently asserted objects.
+ *
+ * Useful to transport information about the nature of the error
+ * back to higher layers.
+ *
+ * @return string|null
+ */
+ public function getPropertyPath()
+ {
+ return $this->propertyPath;
+ }
+
+ /**
+ * Get the value that caused the assertion to fail.
+ *
+ * @return mixed
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * Get the constraints that applied to the failed assertion.
+ *
+ * @return array
+ */
+ public function getConstraints(): array
+ {
+ return $this->constraints;
+ }
+}
diff --git a/vendor/beberlei/assert/lib/Assert/LazyAssertion.php b/vendor/beberlei/assert/lib/Assert/LazyAssertion.php
new file mode 100644
index 000000000..6ccd64236
--- /dev/null
+++ b/vendor/beberlei/assert/lib/Assert/LazyAssertion.php
@@ -0,0 +1,230 @@
+
+ *
+ * @method LazyAssertion alnum(string|callable $message = null, string $propertyPath = null) Assert that value is alphanumeric.
+ * @method LazyAssertion base64(string|callable $message = null, string $propertyPath = null) Assert that a constant is defined.
+ * @method LazyAssertion between(mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit.
+ * @method LazyAssertion betweenExclusive(mixed $lowerLimit, mixed $upperLimit, string|callable $message = null, string $propertyPath = null) Assert that a value is greater than a lower limit, and less than an upper limit.
+ * @method LazyAssertion betweenLength(int $minLength, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string length is between min and max lengths.
+ * @method LazyAssertion boolean(string|callable $message = null, string $propertyPath = null) Assert that value is php boolean.
+ * @method LazyAssertion choice(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices.
+ * @method LazyAssertion choicesNotEmpty(array $choices, string|callable $message = null, string $propertyPath = null) Determines if the values array has every choice as key and that this choice has content.
+ * @method LazyAssertion classExists(string|callable $message = null, string $propertyPath = null) Assert that the class exists.
+ * @method LazyAssertion contains(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string contains a sequence of chars.
+ * @method LazyAssertion count(int $count, string|callable $message = null, string $propertyPath = null) Assert that the count of countable is equal to count.
+ * @method LazyAssertion date(string $format, string|callable $message = null, string $propertyPath = null) Assert that date is valid and corresponds to the given format.
+ * @method LazyAssertion defined(string|callable $message = null, string $propertyPath = null) Assert that a constant is defined.
+ * @method LazyAssertion digit(string|callable $message = null, string $propertyPath = null) Validates if an integer or integerish is a digit.
+ * @method LazyAssertion directory(string|callable $message = null, string $propertyPath = null) Assert that a directory exists.
+ * @method LazyAssertion e164(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid E164 Phone Number.
+ * @method LazyAssertion email(string|callable $message = null, string $propertyPath = null) Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL).
+ * @method LazyAssertion endsWith(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string ends with a sequence of chars.
+ * @method LazyAssertion eq(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are equal (using ==).
+ * @method LazyAssertion eqArraySubset(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that the array contains the subset.
+ * @method LazyAssertion extensionLoaded(string|callable $message = null, string $propertyPath = null) Assert that extension is loaded.
+ * @method LazyAssertion extensionVersion(string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded and a specific version is installed.
+ * @method LazyAssertion false(string|callable $message = null, string $propertyPath = null) Assert that the value is boolean False.
+ * @method LazyAssertion file(string|callable $message = null, string $propertyPath = null) Assert that a file exists.
+ * @method LazyAssertion float(string|callable $message = null, string $propertyPath = null) Assert that value is a php float.
+ * @method LazyAssertion greaterOrEqualThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater or equal than given limit.
+ * @method LazyAssertion greaterThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater than given limit.
+ * @method LazyAssertion implementsInterface(string $interfaceName, string|callable $message = null, string $propertyPath = null) Assert that the class implements the interface.
+ * @method LazyAssertion inArray(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices. This is an alias of Assertion::choice().
+ * @method LazyAssertion integer(string|callable $message = null, string $propertyPath = null) Assert that value is a php integer.
+ * @method LazyAssertion integerish(string|callable $message = null, string $propertyPath = null) Assert that value is a php integer'ish.
+ * @method LazyAssertion interfaceExists(string|callable $message = null, string $propertyPath = null) Assert that the interface exists.
+ * @method LazyAssertion ip(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 or IPv6 address.
+ * @method LazyAssertion ipv4(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 address.
+ * @method LazyAssertion ipv6(int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv6 address.
+ * @method LazyAssertion isArray(string|callable $message = null, string $propertyPath = null) Assert that value is an array.
+ * @method LazyAssertion isArrayAccessible(string|callable $message = null, string $propertyPath = null) Assert that value is an array or an array-accessible object.
+ * @method LazyAssertion isCallable(string|callable $message = null, string $propertyPath = null) Determines that the provided value is callable.
+ * @method LazyAssertion isCountable(string|callable $message = null, string $propertyPath = null) Assert that value is countable.
+ * @method LazyAssertion isInstanceOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is instance of given class-name.
+ * @method LazyAssertion isJsonString(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid json string.
+ * @method LazyAssertion isObject(string|callable $message = null, string $propertyPath = null) Determines that the provided value is an object.
+ * @method LazyAssertion isResource(string|callable $message = null, string $propertyPath = null) Assert that value is a resource.
+ * @method LazyAssertion isTraversable(string|callable $message = null, string $propertyPath = null) Assert that value is an array or a traversable object.
+ * @method LazyAssertion keyExists(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array.
+ * @method LazyAssertion keyIsset(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object using isset().
+ * @method LazyAssertion keyNotExists(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key does not exist in an array.
+ * @method LazyAssertion length(int $length, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string has a given length.
+ * @method LazyAssertion lessOrEqualThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less or equal than given limit.
+ * @method LazyAssertion lessThan(mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less than given limit.
+ * @method LazyAssertion max(mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that a number is smaller as a given limit.
+ * @method LazyAssertion maxCount(int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at most $count elements.
+ * @method LazyAssertion maxLength(int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string value is not longer than $maxLength chars.
+ * @method LazyAssertion methodExists(mixed $object, string|callable $message = null, string $propertyPath = null) Determines that the named method is defined in the provided object.
+ * @method LazyAssertion min(mixed $minValue, string|callable $message = null, string $propertyPath = null) Assert that a value is at least as big as a given limit.
+ * @method LazyAssertion minCount(int $count, string|callable $message = null, string $propertyPath = null) Assert that the countable have at least $count elements.
+ * @method LazyAssertion minLength(int $minLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that a string is at least $minLength chars long.
+ * @method LazyAssertion noContent(string|callable $message = null, string $propertyPath = null) Assert that value is empty.
+ * @method LazyAssertion notBlank(string|callable $message = null, string $propertyPath = null) Assert that value is not blank.
+ * @method LazyAssertion notContains(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string does not contains a sequence of chars.
+ * @method LazyAssertion notEmpty(string|callable $message = null, string $propertyPath = null) Assert that value is not empty.
+ * @method LazyAssertion notEmptyKey(string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object and its value is not empty.
+ * @method LazyAssertion notEq(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not equal (using ==).
+ * @method LazyAssertion notInArray(array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is not in array of choices.
+ * @method LazyAssertion notIsInstanceOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is not instance of given class-name.
+ * @method LazyAssertion notNull(string|callable $message = null, string $propertyPath = null) Assert that value is not null.
+ * @method LazyAssertion notRegex(string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value does not match a regex.
+ * @method LazyAssertion notSame(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not the same (using ===).
+ * @method LazyAssertion null(string|callable $message = null, string $propertyPath = null) Assert that value is null.
+ * @method LazyAssertion numeric(string|callable $message = null, string $propertyPath = null) Assert that value is numeric.
+ * @method LazyAssertion objectOrClass(string|callable $message = null, string $propertyPath = null) Assert that the value is an object, or a class that exists.
+ * @method LazyAssertion phpVersion(mixed $version, string|callable $message = null, string $propertyPath = null) Assert on PHP version.
+ * @method LazyAssertion propertiesExist(array $properties, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the properties all exist.
+ * @method LazyAssertion propertyExists(string $property, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the property exists.
+ * @method LazyAssertion range(mixed $minValue, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that value is in range of numbers.
+ * @method LazyAssertion readable(string|callable $message = null, string $propertyPath = null) Assert that the value is something readable.
+ * @method LazyAssertion regex(string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value matches a regex.
+ * @method LazyAssertion same(mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are the same (using ===).
+ * @method LazyAssertion satisfy(callable $callback, string|callable $message = null, string $propertyPath = null) Assert that the provided value is valid according to a callback.
+ * @method LazyAssertion scalar(string|callable $message = null, string $propertyPath = null) Assert that value is a PHP scalar.
+ * @method LazyAssertion startsWith(string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string starts with a sequence of chars.
+ * @method LazyAssertion string(string|callable $message = null, string $propertyPath = null) Assert that value is a string.
+ * @method LazyAssertion subclassOf(string $className, string|callable $message = null, string $propertyPath = null) Assert that value is subclass of given class-name.
+ * @method LazyAssertion true(string|callable $message = null, string $propertyPath = null) Assert that the value is boolean True.
+ * @method LazyAssertion url(string|callable $message = null, string $propertyPath = null) Assert that value is an URL.
+ * @method LazyAssertion uuid(string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid UUID.
+ * @method LazyAssertion version(string $operator, string $version2, string|callable $message = null, string $propertyPath = null) Assert comparison of two versions.
+ * @method LazyAssertion writeable(string|callable $message = null, string $propertyPath = null) Assert that the value is something writeable.
+ * @method LazyAssertion all() Switch chain into validation mode for an array of values.
+ * @method LazyAssertion nullOr() Switch chain into mode allowing nulls, ignoring further assertions.
+ */
+class LazyAssertion
+{
+ private $currentChainFailed = false;
+ private $alwaysTryAll = false;
+ private $thisChainTryAll = false;
+ private $currentChain;
+ private $errors = [];
+
+ /** @var string The class to use as AssertionChain factory */
+ private $assertClass = Assert::class;
+
+ /** @var string|LazyAssertionException The class to use for exceptions */
+ private $exceptionClass = LazyAssertionException::class;
+
+ /**
+ * @param mixed $value
+ * @param string|null $propertyPath
+ * @param string|callable|null $defaultMessage
+ *
+ * @return static
+ */
+ public function that($value, string $propertyPath = null, $defaultMessage = null)
+ {
+ $this->currentChainFailed = false;
+ $this->thisChainTryAll = false;
+ $assertClass = $this->assertClass;
+ $this->currentChain = $assertClass::that($value, $defaultMessage, $propertyPath);
+
+ return $this;
+ }
+
+ /**
+ * @return static
+ */
+ public function tryAll()
+ {
+ if (!$this->currentChain) {
+ $this->alwaysTryAll = true;
+ }
+
+ $this->thisChainTryAll = true;
+
+ return $this;
+ }
+
+ /**
+ * @param string $method
+ * @param array $args
+ *
+ * @return static
+ */
+ public function __call($method, $args)
+ {
+ if (false === $this->alwaysTryAll
+ && false === $this->thisChainTryAll
+ && true === $this->currentChainFailed
+ ) {
+ return $this;
+ }
+
+ try {
+ \call_user_func_array([$this->currentChain, $method], $args);
+ } catch (AssertionFailedException $e) {
+ $this->errors[] = $e;
+ $this->currentChainFailed = true;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ *
+ * @throws LazyAssertionException
+ */
+ public function verifyNow(): bool
+ {
+ if ($this->errors) {
+ throw \call_user_func([$this->exceptionClass, 'fromErrors'], $this->errors);
+ }
+
+ return true;
+ }
+
+ /**
+ * @param string $className
+ *
+ * @return static
+ */
+ public function setAssertClass(string $className)
+ {
+ if (Assert::class !== $className && !\is_subclass_of($className, Assert::class)) {
+ throw new LogicException($className.' is not (a subclass of) '.Assert::class);
+ }
+
+ $this->assertClass = $className;
+
+ return $this;
+ }
+
+ /**
+ * @param string $className
+ *
+ * @return static
+ */
+ public function setExceptionClass(string $className)
+ {
+ if (LazyAssertionException::class !== $className && !\is_subclass_of($className, LazyAssertionException::class)) {
+ throw new LogicException($className.' is not (a subclass of) '.LazyAssertionException::class);
+ }
+
+ $this->exceptionClass = $className;
+
+ return $this;
+ }
+}
diff --git a/vendor/beberlei/assert/lib/Assert/LazyAssertionException.php b/vendor/beberlei/assert/lib/Assert/LazyAssertionException.php
new file mode 100644
index 000000000..f76ecc699
--- /dev/null
+++ b/vendor/beberlei/assert/lib/Assert/LazyAssertionException.php
@@ -0,0 +1,55 @@
+getPropertyPath(), $error->getMessage());
+ }
+
+ return new static($message, $errors);
+ }
+
+ public function __construct($message, array $errors)
+ {
+ parent::__construct($message, 0, null, null);
+
+ $this->errors = $errors;
+ }
+
+ /**
+ * @return InvalidArgumentException[]
+ */
+ public function getErrorExceptions(): array
+ {
+ return $this->errors;
+ }
+}
diff --git a/vendor/beberlei/assert/lib/Assert/functions.php b/vendor/beberlei/assert/lib/Assert/functions.php
new file mode 100644
index 000000000..e0ccbd7d9
--- /dev/null
+++ b/vendor/beberlei/assert/lib/Assert/functions.php
@@ -0,0 +1,80 @@
+notEmpty()->integer();
+ * \Assert\that($value)->nullOr()->string()->startsWith("Foo");
+ *
+ * The assertion chain can be stateful, that means be careful when you reuse
+ * it. You should never pass around the chain.
+ */
+function that($value, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
+{
+ return Assert::that($value, $defaultMessage, $defaultPropertyPath);
+}
+
+/**
+ * Start validation on a set of values, returns {@link AssertionChain}.
+ *
+ * @param mixed $values
+ * @param string|callable|null $defaultMessage
+ * @param string $defaultPropertyPath
+ *
+ * @return AssertionChain
+ */
+function thatAll($values, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
+{
+ return Assert::thatAll($values, $defaultMessage, $defaultPropertyPath);
+}
+
+/**
+ * Start validation and allow NULL, returns {@link AssertionChain}.
+ *
+ * @param mixed $value
+ * @param string|callable|null $defaultMessage
+ * @param string $defaultPropertyPath
+ *
+ * @return AssertionChain
+ *
+ * @deprecated In favour of Assert::thatNullOr($value, $defaultMessage = null, $defaultPropertyPath = null)
+ */
+function thatNullOr($value, $defaultMessage = null, string $defaultPropertyPath = null): AssertionChain
+{
+ return Assert::thatNullOr($value, $defaultMessage, $defaultPropertyPath);
+}
+
+/**
+ * Create a lazy assertion object.
+ *
+ * @return LazyAssertion
+ */
+function lazy(): LazyAssertion
+{
+ return Assert::lazy();
+}
diff --git a/vendor/beberlei/assert/phpstan-code.neon b/vendor/beberlei/assert/phpstan-code.neon
new file mode 100644
index 000000000..49aa5723f
--- /dev/null
+++ b/vendor/beberlei/assert/phpstan-code.neon
@@ -0,0 +1,10 @@
+parameters:
+ autoload_files:
+ - bin/MethodDocGenerator.php
+ ignoreErrors:
+ # is_countable() is available only in PHP 7.3+
+ - '#Function is_countable not found#'
+
+ # Calling count() on ResourceBundle and SimpleXMLElement is valid from PHP 7.0+, but does not correctly advertise
+ # the fact, and so PHPStan has an issue with this. This will be fixed in PHP 7.4+
+ - '#Call to function count\(\) with argument type array|Countable|ResourceBundle|SimpleXMLElement will always result in number 1#'
diff --git a/vendor/beberlei/assert/phpstan-tests.neon b/vendor/beberlei/assert/phpstan-tests.neon
new file mode 100644
index 000000000..e9ab0bcf9
--- /dev/null
+++ b/vendor/beberlei/assert/phpstan-tests.neon
@@ -0,0 +1,10 @@
+parameters:
+ ignoreErrors:
+ # The following errors are ignored as they are testing for errors and exceptions that static analysis correctly identifies as problems.
+ - '#Call to an undefined method Assert\\AssertionChain::unknownAssertion\(\)#'
+ - '#Call to an undefined static method Assert\\Assertion::nullOrAssertionDoesNotExist\(\)#'
+ - '#Class Foo not found#'
+ - '#Parameter \#1 $value of static method Assert\\Assertion::isCountable\(\) expects array|Countable|ResourceBundle|SimpleXMLElement, string given#'
+ - '#Parameter \#2 \$operator of static method Assert\\Assertion::version\(\) expects string, null given#'
+ - '#Static method Assert\\Assertion::allTrue\(\) invoked with 0 parameters, 1-3 required#'
+ - '#Static method Assert\\Assertion::nullOrMax\(\) invoked with 0 parameters, 2-4 required#'
diff --git a/vendor/chillerlan/php-qrcode/.github/FUNDING.yml b/vendor/chillerlan/php-qrcode/.github/FUNDING.yml
new file mode 100644
index 000000000..fc89a6739
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/.github/FUNDING.yml
@@ -0,0 +1 @@
+ko_fi: codemasher
diff --git a/vendor/chillerlan/php-qrcode/.github/workflows/tests.yml b/vendor/chillerlan/php-qrcode/.github/workflows/tests.yml
new file mode 100644
index 000000000..5dd343abd
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/.github/workflows/tests.yml
@@ -0,0 +1,55 @@
+# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
+# https://github.com/localheinz/php-library-template/blob/master/.github/workflows/continuous-integration.yml
+# https://github.com/sebastianbergmann/phpunit/blob/master/.github/workflows/ci.yml
+
+on:
+ - pull_request
+ - push
+
+name: "Continuous Integration"
+
+jobs:
+
+ tests:
+ name: "Unit Tests"
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ php-binary:
+ - php7.2
+ - php7.3
+ - php7.4
+
+ steps:
+ - name: "Checkout"
+ uses: actions/checkout@v1.1.0
+
+ - name: "Install dependencies with composer"
+ run: ${{ matrix.php-binary }} $(which composer) update --no-interaction --no-progress --no-suggest
+
+ - name: "Run unit tests with phpunit"
+ run: ${{ matrix.php-binary }} vendor/bin/phpunit --configuration=phpunit.xml --no-coverage
+
+
+ code-coverage:
+ name: "Code Coverage"
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: "Checkout"
+ uses: actions/checkout@v1.1.0
+
+ - name: "Install locked dependencies with composer"
+ run: php7.4 $(which composer) install --no-interaction --no-progress --no-suggest
+
+ - name: "Dump Xdebug filter with phpunit/phpunit"
+ run: php7.4 vendor/bin/phpunit --configuration=phpunit.xml --dump-xdebug-filter=.build/phpunit/xdebug-filter.php
+
+ - name: "Collect code coverage with Xdebug and phpunit/phpunit"
+ run: php7.4 vendor/bin/phpunit --configuration=phpunit.xml --prepend=.build/phpunit/xdebug-filter.php
+
+ - name: "Send code coverage report to Codecov.io"
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ run: bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/chillerlan/php-qrcode/.gitignore b/vendor/chillerlan/php-qrcode/.gitignore
new file mode 100644
index 000000000..ecebb9964
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/.gitignore
@@ -0,0 +1,5 @@
+.build/*
+.idea/*
+vendor/*
+composer.lock
+*.phpunit.result.cache
diff --git a/vendor/chillerlan/php-qrcode/.scrutinizer.yml b/vendor/chillerlan/php-qrcode/.scrutinizer.yml
new file mode 100644
index 000000000..7fdd2a4dc
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/.scrutinizer.yml
@@ -0,0 +1,5 @@
+filter:
+ excluded_paths:
+ - examples/*
+ - tests/*
+ - vendor/*
diff --git a/vendor/chillerlan/php-qrcode/.travis.yml b/vendor/chillerlan/php-qrcode/.travis.yml
new file mode 100644
index 000000000..78b8d79e9
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/.travis.yml
@@ -0,0 +1,19 @@
+addons:
+ apt:
+ packages:
+ - imagemagick
+
+language: php
+
+matrix:
+ include:
+ - php: 7.2
+ - php: 7.3
+ - php: 7.4
+
+before_install:
+ - pecl channel-update pecl.php.net
+ - printf "\n" | pecl install imagick
+install: travis_retry composer install --no-interaction --prefer-source
+script: vendor/bin/phpunit --configuration phpunit.xml --coverage-clover clover.xml
+after_script: bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/OTPHP/LICENCE b/vendor/chillerlan/php-qrcode/LICENSE
similarity index 93%
rename from vendor/OTPHP/LICENCE
rename to vendor/chillerlan/php-qrcode/LICENSE
index d14cbc23c..dac852818 100644
--- a/vendor/OTPHP/LICENCE
+++ b/vendor/chillerlan/php-qrcode/LICENSE
@@ -1,4 +1,6 @@
-Copyright (c) 2011 Le Lag
+The MIT License (MIT)
+
+Copyright (c) 2015 Smiley
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -17,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-
diff --git a/vendor/chillerlan/php-qrcode/README.md b/vendor/chillerlan/php-qrcode/README.md
new file mode 100644
index 000000000..075b2a376
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/README.md
@@ -0,0 +1,392 @@
+# chillerlan/php-qrcode
+
+A PHP7.2+ QR Code library based on the [implementation](https://github.com/kazuhikoarase/qrcode-generator) by [Kazuhiko Arase](https://github.com/kazuhikoarase),
+namespaced, cleaned up, improved and other stuff.
+
+[![Packagist version][packagist-badge]][packagist]
+[![License][license-badge]][license]
+[![Travis CI][travis-badge]][travis]
+[![CodeCov][coverage-badge]][coverage]
+[![Scrunitizer CI][scrutinizer-badge]][scrutinizer]
+[![Packagist downloads][downloads-badge]][downloads]
+[![PayPal donate][donate-badge]][donate]
+
+[![Continuous Integration][gh-action-badge]][gh-action]
+
+[packagist-badge]: https://img.shields.io/packagist/v/chillerlan/php-qrcode.svg?style=flat-square
+[packagist]: https://packagist.org/packages/chillerlan/php-qrcode
+[license-badge]: https://img.shields.io/github/license/chillerlan/php-qrcode.svg?style=flat-square
+[license]: https://github.com/chillerlan/php-qrcode/blob/main/LICENSE
+[travis-badge]: https://img.shields.io/travis/chillerlan/php-qrcode.svg?style=flat-square
+[travis]: https://travis-ci.org/chillerlan/php-qrcode
+[coverage-badge]: https://img.shields.io/codecov/c/github/chillerlan/php-qrcode.svg?style=flat-square
+[coverage]: https://codecov.io/github/chillerlan/php-qrcode
+[scrutinizer-badge]: https://img.shields.io/scrutinizer/g/chillerlan/php-qrcode.svg?style=flat-square
+[scrutinizer]: https://scrutinizer-ci.com/g/chillerlan/php-qrcode
+[downloads-badge]: https://img.shields.io/packagist/dt/chillerlan/php-qrcode.svg?style=flat-square
+[downloads]: https://packagist.org/packages/chillerlan/php-qrcode/stats
+[donate-badge]: https://img.shields.io/badge/donate-paypal-ff33aa.svg?style=flat-square
+[donate]: https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4
+[gh-action-badge]: https://github.com/chillerlan/php-qrcode/workflows/Continuous%20Integration/badge.svg
+[gh-action]: https://github.com/chillerlan/php-qrcode/actions
+
+## Documentation
+
+### Requirements
+- PHP 7.2+
+ - `ext-mbstring`
+ - optional:
+ - `ext-json`, `ext-gd`
+ - `ext-imagick` with [ImageMagick](https://imagemagick.org) installed
+ - [`setasign/fpdf`](https://github.com/setasign/fpdf) for the PDF output module
+
+### Installation
+**requires [composer](https://getcomposer.org)**
+
+via terminal: `composer require chillerlan/php-qrcode`
+
+*composer.json* (note: replace `dev-master` with a [version boundary](https://getcomposer.org/doc/articles/versions.md), e.g. `^3.2`)
+```json
+{
+ "require": {
+ "php": "^7.2",
+ "chillerlan/php-qrcode": "^3.4"
+ }
+}
+```
+
+### Usage
+We want to encode this URI for a mobile authenticator into a QRcode image:
+```php
+$data = 'otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net';
+
+//quick and simple:
+echo '';
+```
+
+
+
+
+
+
+Wait, what was that? Please again, slower!
+
+### Advanced usage
+
+Ok, step by step. First you'll need a `QRCode` instance, which can be optionally invoked with a `QROptions` (or a [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/master/src/SettingsContainerInterface.php), respectively) object as the only parameter.
+
+```php
+$options = new QROptions([
+ 'version' => 5,
+ 'outputType' => QRCode::OUTPUT_MARKUP_SVG,
+ 'eccLevel' => QRCode::ECC_L,
+]);
+
+// invoke a fresh QRCode instance
+$qrcode = new QRCode($options);
+
+// and dump the output
+$qrcode->render($data);
+
+// ...with additional cache file
+$qrcode->render($data, '/path/to/file.svg');
+```
+
+In case you just want the raw QR code matrix, call `QRCode::getMatrix()` - this method is also called internally from `QRCode::render()`. See also [Custom output modules](#custom-qroutputinterface).
+
+```php
+$matrix = $qrcode->getMatrix($data);
+
+foreach($matrix->matrix() as $y => $row){
+ foreach($row as $x => $module){
+
+ // get a module's value
+ $value = $module;
+ $value = $matrix->get($x, $y);
+
+ // boolean check a module
+ if($matrix->check($x, $y)){ // if($module >> 8 > 0)
+ // do stuff, the module is dark
+ }
+ else{
+ // do other stuff, the module is light
+ }
+
+ }
+}
+```
+
+Have a look [in this folder](https://github.com/chillerlan/php-qrcode/tree/master/examples) for some more usage examples.
+
+#### Custom module values
+Previous versions of `QRCode` held only boolean matrix values that only allowed to determine whether a module was dark or not. Now you can distinguish between different parts of the matrix, namely the several required patterns from the QR Code specification, and use them in different ways.
+
+The dark value is the module (light) value shifted by 8 bits to the left: `$value = $M_TYPE << ($bool ? 8 : 0);`, where `$M_TYPE` is one of the `QRMatrix::M_*` constants.
+You can check the value for a type explicitly like...
+```php
+// for true (dark)
+$value >> 8 === $M_TYPE;
+
+//for false (light)
+$value === $M_TYPE;
+```
+...or you can perform a loose check, ignoring the module value
+```php
+// for true
+$value >> 8 > 0;
+
+// for false
+$value >> 8 === 0
+```
+
+See also `QRMatrix::set()`, `QRMatrix::check()` and [`QRMatrix` constants](#qrmatrix-constants).
+
+To map the values and properly render the modules for the given `QROutputInterface`, it's necessary to overwrite the default values:
+```php
+$options = new QROptions;
+
+// for HTML, SVG and ImageMagick
+$options->moduleValues = [
+ // finder
+ 1536 => '#A71111', // dark (true)
+ 6 => '#FFBFBF', // light (false)
+ // alignment
+ 2560 => '#A70364',
+ 10 => '#FFC9C9',
+ // timing
+ 3072 => '#98005D',
+ 12 => '#FFB8E9',
+ // format
+ 3584 => '#003804',
+ 14 => '#00FB12',
+ // version
+ 4096 => '#650098',
+ 16 => '#E0B8FF',
+ // data
+ 1024 => '#4A6000',
+ 4 => '#ECF9BE',
+ // darkmodule
+ 512 => '#080063',
+ // separator
+ 8 => '#AFBFBF',
+ // quietzone
+ 18 => '#FFFFFF',
+];
+
+// for the image output types
+$options->moduleValues = [
+ 512 => [0, 0, 0],
+ // ...
+];
+
+// for string/text output
+$options->moduleValues = [
+ 512 => '#',
+ // ...
+];
+```
+
+#### Custom `QROutputInterface`
+Instead of bloating your code you can simply create your own output interface by extending `QROutputAbstract`. Have a look at the [built-in output modules](https://github.com/chillerlan/php-qrcode/tree/master/src/Output).
+
+```php
+class MyCustomOutput extends QROutputAbstract{
+
+ // inherited from QROutputAbstract
+ protected $matrix; // QRMatrix
+ protected $moduleCount; // modules QRMatrix::size()
+ protected $options; // MyCustomOptions or QROptions
+ protected $scale; // scale factor from options
+ protected $length; // length of the matrix ($moduleCount * $scale)
+
+ // ...check/set default module values (abstract method, called by the constructor)
+ protected function setModuleValues():void{
+ // $this->moduleValues = ...
+ }
+
+ // QROutputInterface::dump()
+ public function dump(string $file = null):string{
+ $output = '';
+
+ for($row = 0; $row < $this->moduleCount; $row++){
+ for($col = 0; $col < $this->moduleCount; $col++){
+ $output .= (int)$this->matrix->check($col, $row);
+ }
+ }
+
+ return $output;
+ }
+
+}
+```
+
+In case you need additional settings for your output module, just extend `QROptions`...
+```
+class MyCustomOptions extends QROptions{
+ protected $myParam = 'defaultValue';
+
+ // ...
+}
+```
+...or use the [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/master/src/SettingsContainerInterface.php), which is the more flexible approach.
+
+```php
+trait MyCustomOptionsTrait{
+ protected $myParam = 'defaultValue';
+
+ // ...
+}
+```
+set the options:
+```php
+$myOptions = [
+ 'version' => 5,
+ 'eccLevel' => QRCode::ECC_L,
+ 'outputType' => QRCode::OUTPUT_CUSTOM,
+ 'outputInterface' => MyCustomOutput::class,
+ // your custom settings
+ 'myParam' => 'whatever value',
+ ];
+
+// extends QROptions
+$myCustomOptions = new MyCustomOptions($myOptions);
+
+// using the SettingsContainerInterface
+$myCustomOptions = new class($myOptions) extends SettingsContainerAbstract{
+ use QROptionsTrait, MyCustomOptionsTrait;
+};
+
+```
+
+You can then call `QRCode` with the custom modules...
+```php
+(new QRCode($myCustomOptions))->render($data);
+```
+...or invoke the `QROutputInterface` manually.
+```php
+$qrOutputInterface = new MyCustomOutput($myCustomOptions, (new QRCode($myCustomOptions))->getMatrix($data));
+
+//dump the output, which is equivalent to QRCode::render()
+$qrOutputInterface->dump();
+```
+
+### API
+
+#### `QRCode` methods
+method | return | description
+------ | ------ | -----------
+`__construct(QROptions $options = null)` | - | see [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/master/src/SettingsContainerInterface.php)
+`render(string $data, string $file = null)` | mixed, `QROutputInterface::dump()` | renders a QR Code for the given `$data` and `QROptions`, saves `$file` optional
+`getMatrix(string $data)` | `QRMatrix` | returns a `QRMatrix` object for the given `$data` and current `QROptions`
+`initDataInterface(string $data)` | `QRDataInterface` | returns a fresh `QRDataInterface` for the given `$data`
+`isNumber(string $string)` | bool | checks if a string qualifies for `Number`
+`isAlphaNum(string $string)` | bool | checks if a string qualifies for `AlphaNum`
+`isKanji(string $string)` | bool | checks if a string qualifies for `Kanji`
+
+#### `QRCode` constants
+name | description
+---- | -----------
+`VERSION_AUTO` | `QROptions::$version`
+`MASK_PATTERN_AUTO` | `QROptions::$maskPattern`
+`OUTPUT_MARKUP_SVG`, `OUTPUT_MARKUP_HTML` | `QROptions::$outputType` markup
+`OUTPUT_IMAGE_PNG`, `OUTPUT_IMAGE_JPG`, `OUTPUT_IMAGE_GIF` | `QROptions::$outputType` image
+`OUTPUT_STRING_JSON`, `OUTPUT_STRING_TEXT` | `QROptions::$outputType` string
+`OUTPUT_IMAGICK` | `QROptions::$outputType` ImageMagick
+`OUTPUT_FPDF` | `QROptions::$outputType` PDF, using [FPDF](https://github.com/setasign/fpdf)
+`OUTPUT_CUSTOM` | `QROptions::$outputType`, requires `QROptions::$outputInterface`
+`ECC_L`, `ECC_M`, `ECC_Q`, `ECC_H`, | ECC-Level: 7%, 15%, 25%, 30% in `QROptions::$eccLevel`
+`DATA_NUMBER`, `DATA_ALPHANUM`, `DATA_BYTE`, `DATA_KANJI` | `QRDataInterface::$datamode`
+
+#### `QROptions` properties
+property | type | default | allowed | description
+-------- | ---- | ------- | ------- | -----------
+`$version` | int | `QRCode::VERSION_AUTO` | 1...40 | the [QR Code version number](http://www.qrcode.com/en/about/version.html)
+`$versionMin` | int | 1 | 1...40 | Minimum QR version (if `$version = QRCode::VERSION_AUTO`)
+`$versionMax` | int | 40 | 1...40 | Maximum QR version (if `$version = QRCode::VERSION_AUTO`)
+`$eccLevel` | int | `QRCode::ECC_L` | `QRCode::ECC_X` | Error correct level, where X = L (7%), M (15%), Q (25%), H (30%)
+`$maskPattern` | int | `QRCode::MASK_PATTERN_AUTO` | 0...7 | Mask Pattern to use
+`$addQuietzone` | bool | `true` | - | Add a "quiet zone" (margin) according to the QR code spec
+`$quietzoneSize` | int | 4 | clamped to 0 ... `$matrixSize / 2` | Size of the quiet zone
+`$dataMode` | string | `null` | `Number`, `AlphaNum`, `Kanji`, `Byte` | allows overriding the data type detection
+`$outputType` | string | `QRCode::OUTPUT_IMAGE_PNG` | `QRCode::OUTPUT_*` | built-in output type
+`$outputInterface` | string | `null` | * | FQCN of the custom `QROutputInterface` if `QROptions::$outputType` is set to `QRCode::OUTPUT_CUSTOM`
+`$cachefile` | string | `null` | * | optional cache file path
+`$eol` | string | `PHP_EOL` | * | newline string (HTML, SVG, TEXT)
+`$scale` | int | 5 | * | size of a QR code pixel (SVG, IMAGE_*), HTML -> via CSS
+`$cssClass` | string | `null` | * | a common css class
+`$svgOpacity` | float | 1.0 | 0...1 |
+`$svgDefs` | string | * | * | anything between [``](https://developer.mozilla.org/docs/Web/SVG/Element/defs)
+`$svgViewBoxSize` | int | `null` | * | a positive integer which defines width/height of the [viewBox attribute](https://css-tricks.com/scale-svg/#article-header-id-3)
+`$textDark` | string | '🔴' | * | string substitute for dark
+`$textLight` | string | 'â•' | * | string substitute for light
+`$markupDark` | string | '#000' | * | markup substitute for dark (CSS value)
+`$markupLight` | string | '#fff' | * | markup substitute for light (CSS value)
+`$imageBase64` | bool | `true` | - | whether to return the image data as base64 or raw like from `file_get_contents()`
+`$imageTransparent` | bool | `true` | - | toggle transparency (no jpeg support)
+`$imageTransparencyBG` | array | `[255, 255, 255]` | `[R, G, B]` | the RGB values for the transparent color, see [`imagecolortransparent()`](http://php.net/manual/function.imagecolortransparent.php)
+`$pngCompression` | int | -1 | -1 ... 9 | `imagepng()` compression level, -1 = auto
+`$jpegQuality` | int | 85 | 0 - 100 | `imagejpeg()` quality
+`$imagickFormat` | string | 'png' | * | ImageMagick output type, see `Imagick::setType()`
+`$imagickBG` | string | `null` | * | ImageMagick background color, see `ImagickPixel::__construct()`
+`$moduleValues` | array | `null` | * | Module values map, see [Custom output modules](#custom-qroutputinterface) and `QROutputInterface::DEFAULT_MODULE_VALUES`
+
+#### `QRMatrix` methods
+method | return | description
+------ | ------ | -----------
+`__construct(int $version, int $eclevel)` | - | -
+`matrix()` | array | the internal matrix representation as a 2 dimensional array
+`version()` | int | the current QR Code version
+`eccLevel()` | int | current ECC level
+`maskPattern()` | int | the used mask pattern
+`size()` | int | the absoulute size of the matrix, including quiet zone (if set). `$version * 4 + 17 + 2 * $quietzone`
+`get(int $x, int $y)` | int | returns the value of the module
+`set(int $x, int $y, bool $value, int $M_TYPE)` | `QRMatrix` | sets the `$M_TYPE` value for the module
+`check(int $x, int $y)` | bool | checks whether a module is true (dark) or false (light)
+`setLogoSpace(int $width, int $height, int $startX = null, int $startY = null)` | `QRMatrix` | creates a logo space in the matrix
+
+#### `QRMatrix` constants
+name | light (false) | dark (true) | description
+---- | ------------- | ----------- | -----------
+`M_NULL` | 0 | - | module not set (should never appear. if so, there's an error)
+`M_DARKMODULE` | - | 512 | once per matrix at `$xy = [8, 4 * $version + 9]`
+`M_DATA` | 4 | 1024 | the actual encoded data
+`M_FINDER` | 6 | 1536 | the 7x7 finder patterns
+`M_SEPARATOR` | 8 | - | separator lines around the finder patterns
+`M_ALIGNMENT` | 10 | 2560 | the 5x5 alignment patterns
+`M_TIMING` | 12 | 3072 | the timing pattern lines
+`M_FORMAT` | 14 | 3584 | format information pattern
+`M_VERSION` | 16 | 4096 | version information pattern
+`M_QUIETZONE` | 18 | - | margin around the QR Code
+`M_LOGO` | 20 | - | space for a logo image (not used yet)
+`M_TEST` | 255 | 65280 | test value
+
+
+### Notes
+The QR encoder, especially the subroutines for mask pattern testing, can cause high CPU load on increased matrix size.
+You can avoid a part of this load by choosing a fast output module, like `OUTPUT_IMAGE_*` and setting the mask pattern manually (which may result in unreadable QR Codes).
+Oh hey and don't forget to sanitize any user input!
+
+### Disclaimer!
+I don't take responsibility for molten CPUs, misled applications, failed log-ins etc.. Use at your own risk!
+
+#### Trademark Notice
+
+The word "QR Code" is registered trademark of *DENSO WAVE INCORPORATED*
+http://www.denso-wave.com/qrcode/faqpatent-e.html
+
+### Framework Integration
+- Drupal [Google Authenticator Login `ga_login`](https://www.drupal.org/project/ga_login)
+- WordPress [`wp-two-factor-auth`](https://github.com/sjinks/wp-two-factor-auth)
+- WordPress [Simple 2FA `simple-2fa`](https://wordpress.org/plugins/simple-2fa/)
+- WoltLab Suite [two-step-verification](http://pluginstore.woltlab.com/file/3007-two-step-verification/)
+- [Cachet](https://github.com/CachetHQ/Cachet)
+- [Appwrite](https://github.com/appwrite/appwrite)
+- other uses: [dependents](https://github.com/chillerlan/php-qrcode/network/dependents) / [packages](https://github.com/chillerlan/php-qrcode/network/dependents?dependent_type=PACKAGE)
+
+
+Hi, please check out my other projects that are way cooler than qrcodes!
+
+- [php-oauth-core](https://github.com/chillerlan/php-oauth-core) - an OAuth 1/2 client library along with a bunch of [providers](https://github.com/chillerlan/php-oauth-providers)
+- [php-httpinterface](https://github.com/chillerlan/php-httpinterface) - a PSR-7/15/17/18 implemetation
+- [php-database](https://github.com/chillerlan/php-database) - a database client & querybuilder for MySQL, Postgres, SQLite, MSSQL, Firebird
+
diff --git a/vendor/chillerlan/php-qrcode/composer.json b/vendor/chillerlan/php-qrcode/composer.json
new file mode 100644
index 000000000..c2299a350
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/composer.json
@@ -0,0 +1,51 @@
+{
+ "name": "chillerlan/php-qrcode",
+ "description": "A QR code generator. PHP 7.2+",
+ "homepage": "https://github.com/chillerlan/php-qrcode",
+ "license": "MIT",
+ "minimum-stability": "stable",
+ "type": "library",
+ "keywords": [
+ "QR code", "qrcode", "qr", "qrcode-generator", "phpqrcode"
+ ],
+ "authors": [
+ {
+ "name": "Kazuhiko Arase",
+ "homepage": "https://github.com/kazuhikoarase"
+ },
+ {
+ "name": "Smiley",
+ "email": "smiley@chillerlan.net",
+ "homepage": "https://github.com/codemasher"
+ },
+ {
+ "name": "Contributors",
+ "homepage":"https://github.com/chillerlan/php-qrcode/graphs/contributors"
+ }
+ ],
+ "require": {
+ "php": "^7.2",
+ "ext-mbstring": "*",
+ "chillerlan/php-settings-container": "^1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5",
+ "setasign/fpdf": "^1.8.2"
+ },
+ "suggest": {
+ "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.",
+ "setasign/fpdf": "Required to use the QR FPDF output."
+ },
+ "autoload": {
+ "psr-4": {
+ "chillerlan\\QRCode\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "chillerlan\\QRCodePublic\\": "public/",
+ "chillerlan\\QRCodeTest\\": "tests/",
+ "chillerlan\\QRCodeExamples\\": "examples/"
+ }
+ }
+}
diff --git a/vendor/chillerlan/php-qrcode/examples/MyCustomOutput.php b/vendor/chillerlan/php-qrcode/examples/MyCustomOutput.php
new file mode 100644
index 000000000..3c01f8646
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/MyCustomOutput.php
@@ -0,0 +1,36 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\Output\QROutputAbstract;
+
+class MyCustomOutput extends QROutputAbstract{
+
+ protected function setModuleValues():void{
+ // TODO: Implement setModuleValues() method.
+ }
+
+ public function dump(string $file = null){
+
+ $output = '';
+
+ for($row = 0; $row < $this->moduleCount; $row++){
+ for($col = 0; $col < $this->moduleCount; $col++){
+ $output .= (int)$this->matrix->check($col, $row);
+ }
+ }
+
+ return $output;
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/examples/QRImageWithLogo.php b/vendor/chillerlan/php-qrcode/examples/QRImageWithLogo.php
new file mode 100644
index 000000000..f9d94ae34
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/QRImageWithLogo.php
@@ -0,0 +1,81 @@
+
+ * @copyright 2020 smiley
+ * @license MIT
+ *
+ * @noinspection PhpComposerExtensionStubsInspection
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\Output\{QRCodeOutputException, QRImage};
+
+use function imagecopyresampled, imagecreatefrompng, imagesx, imagesy, is_file, is_readable;
+
+/**
+ * @property \chillerlan\QRCodeExamples\LogoOptions $options
+ */
+class QRImageWithLogo extends QRImage{
+
+ /**
+ * @param string|null $file
+ * @param string|null $logo
+ *
+ * @return string
+ * @throws \chillerlan\QRCode\Output\QRCodeOutputException
+ */
+ public function dump(string $file = null, string $logo = null):string{
+ // set returnResource to true to skip further processing for now
+ $this->options->returnResource = true;
+
+ // of course you could accept other formats too (such as resource or Imagick)
+ // i'm not checking for the file type either for simplicity reasons (assuming PNG)
+ if(!is_file($logo) || !is_readable($logo)){
+ throw new QRCodeOutputException('invalid logo');
+ }
+
+ $this->matrix->setLogoSpace(
+ $this->options->logoWidth,
+ $this->options->logoHeight
+ // not utilizing the position here
+ );
+
+ // there's no need to save the result of dump() into $this->image here
+ parent::dump($file);
+
+ $im = imagecreatefrompng($logo);
+
+ // get logo image size
+ $w = imagesx($im);
+ $h = imagesy($im);
+
+ // set new logo size, leave a border of 1 module
+ $lw = ($this->options->logoWidth - 2) * $this->options->scale;
+ $lh = ($this->options->logoHeight - 2) * $this->options->scale;
+
+ // get the qrcode size
+ $ql = $this->matrix->size() * $this->options->scale;
+
+ // scale the logo and copy it over. done!
+ imagecopyresampled($this->image, $im, ($ql - $lw) / 2, ($ql - $lh) / 2, 0, 0, $lw, $lh, $w, $h);
+
+ $imageData = $this->dumpImage();
+
+ if($file !== null){
+ $this->saveToFile($imageData, $file);
+ }
+
+ if($this->options->imageBase64){
+ $imageData = 'data:image/'.$this->options->outputType.';base64,'.base64_encode($imageData);
+ }
+
+ return $imageData;
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/examples/QRImageWithText.php b/vendor/chillerlan/php-qrcode/examples/QRImageWithText.php
new file mode 100644
index 000000000..5ca572f30
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/QRImageWithText.php
@@ -0,0 +1,104 @@
+
+ * @copyright 2019 smiley
+ * @license MIT
+ *
+ * @noinspection PhpComposerExtensionStubsInspection
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\Output\QRImage;
+use function base64_encode, imagechar, imagecolorallocate, imagecolortransparent, imagecopymerge, imagecreatetruecolor,
+ imagedestroy, imagefilledrectangle, imagefontwidth, in_array, round, str_split, strlen;
+
+class QRImageWithText extends QRImage{
+
+ /**
+ * @param string|null $file
+ * @param string|null $text
+ *
+ * @return string
+ */
+ public function dump(string $file = null, string $text = null):string{
+ $this->image = imagecreatetruecolor($this->length, $this->length);
+ $background = imagecolorallocate($this->image, ...$this->options->imageTransparencyBG);
+
+ if((bool)$this->options->imageTransparent && in_array($this->options->outputType, $this::TRANSPARENCY_TYPES, true)){
+ imagecolortransparent($this->image, $background);
+ }
+
+ imagefilledrectangle($this->image, 0, 0, $this->length, $this->length, $background);
+
+ foreach($this->matrix->matrix() as $y => $row){
+ foreach($row as $x => $M_TYPE){
+ $this->setPixel($x, $y, $this->moduleValues[$M_TYPE]);
+ }
+ }
+
+ // render text output if a string is given
+ if($text !== null){
+ $this->addText($text);
+ }
+
+ $imageData = $this->dumpImage($file);
+
+ if((bool)$this->options->imageBase64){
+ $imageData = 'data:image/'.$this->options->outputType.';base64,'.base64_encode($imageData);
+ }
+
+ return $imageData;
+ }
+
+ /**
+ * @param string $text
+ */
+ protected function addText(string $text):void{
+ // save the qrcode image
+ $qrcode = $this->image;
+
+ // options things
+ $textSize = 3; // see imagefontheight() and imagefontwidth()
+ $textBG = [200, 200, 200];
+ $textColor = [50, 50, 50];
+
+ $bgWidth = $this->length;
+ $bgHeight = $bgWidth + 20; // 20px extra space
+
+ // create a new image with additional space
+ $this->image = imagecreatetruecolor($bgWidth, $bgHeight);
+ $background = imagecolorallocate($this->image, ...$textBG);
+
+ // allow transparency
+ if((bool)$this->options->imageTransparent && in_array($this->options->outputType, $this::TRANSPARENCY_TYPES, true)){
+ imagecolortransparent($this->image, $background);
+ }
+
+ // fill the background
+ imagefilledrectangle($this->image, 0, 0, $bgWidth, $bgHeight, $background);
+
+ // copy over the qrcode
+ imagecopymerge($this->image, $qrcode, 0, 0, 0, 0, $this->length, $this->length, 100);
+ imagedestroy($qrcode);
+
+ $fontColor = imagecolorallocate($this->image, ...$textColor);
+ $w = imagefontwidth($textSize);
+ $x = round(($bgWidth - strlen($text) * $w) / 2);
+
+ // loop through the string and draw the letters
+ foreach(str_split($text) as $i => $chr){
+ imagechar($this->image, $textSize, $i * $w + $x, $this->length, $chr, $fontColor);
+ }
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/examples/custom_output.php b/vendor/chillerlan/php-qrcode/examples/custom_output.php
new file mode 100644
index 000000000..71ea62682
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/custom_output.php
@@ -0,0 +1,38 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+
+// invoke the QROutputInterface manually
+$options = new QROptions([
+ 'version' => 5,
+ 'eccLevel' => QRCode::ECC_L,
+]);
+
+$qrOutputInterface = new MyCustomOutput($options, (new QRCode($options))->getMatrix($data));
+
+var_dump($qrOutputInterface->dump());
+
+
+// or just
+$options = new QROptions([
+ 'version' => 5,
+ 'eccLevel' => QRCode::ECC_L,
+ 'outputType' => QRCode::OUTPUT_CUSTOM,
+ 'outputInterface' => MyCustomOutput::class,
+]);
+
+var_dump((new QRCode($options))->render($data));
diff --git a/vendor/chillerlan/php-qrcode/examples/example_image.png b/vendor/chillerlan/php-qrcode/examples/example_image.png
new file mode 100644
index 000000000..b4a80f2ab
Binary files /dev/null and b/vendor/chillerlan/php-qrcode/examples/example_image.png differ
diff --git a/vendor/chillerlan/php-qrcode/examples/example_svg.png b/vendor/chillerlan/php-qrcode/examples/example_svg.png
new file mode 100644
index 000000000..f1e7b32f7
Binary files /dev/null and b/vendor/chillerlan/php-qrcode/examples/example_svg.png differ
diff --git a/vendor/chillerlan/php-qrcode/examples/fpdf.php b/vendor/chillerlan/php-qrcode/examples/fpdf.php
new file mode 100644
index 000000000..9c690a7f7
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/fpdf.php
@@ -0,0 +1,47 @@
+ 7,
+ 'outputType' => QRCode::OUTPUT_FPDF,
+ 'eccLevel' => QRCode::ECC_L,
+ 'scale' => 5,
+ 'imageBase64' => false,
+ 'moduleValues' => [
+ // finder
+ 1536 => [0, 63, 255], // dark (true)
+ 6 => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
+ // alignment
+ 2560 => [255, 0, 255],
+ 10 => [255, 255, 255],
+ // timing
+ 3072 => [255, 0, 0],
+ 12 => [255, 255, 255],
+ // format
+ 3584 => [67, 191, 84],
+ 14 => [255, 255, 255],
+ // version
+ 4096 => [62, 174, 190],
+ 16 => [255, 255, 255],
+ // data
+ 1024 => [0, 0, 0],
+ 4 => [255, 255, 255],
+ // darkmodule
+ 512 => [0, 0, 0],
+ // separator
+ 8 => [255, 255, 255],
+ // quietzone
+ 18 => [255, 255, 255],
+ ],
+]);
+
+\header('Content-type: application/pdf');
+
+echo (new QRCode($options))->render($data);
diff --git a/vendor/chillerlan/php-qrcode/examples/html.php b/vendor/chillerlan/php-qrcode/examples/html.php
new file mode 100644
index 000000000..aa5305d24
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/html.php
@@ -0,0 +1,102 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once '../vendor/autoload.php';
+
+header('Content-Type: text/html; charset=utf-8');
+
+?>
+
+
+
+
+
+ QRCode test
+
+
+
+
+ 5,
+ 'outputType' => QRCode::OUTPUT_MARKUP_HTML,
+ 'eccLevel' => QRCode::ECC_L,
+ 'moduleValues' => [
+ // finder
+ 1536 => '#A71111', // dark (true)
+ 6 => '#FFBFBF', // light (false)
+ // alignment
+ 2560 => '#A70364',
+ 10 => '#FFC9C9',
+ // timing
+ 3072 => '#98005D',
+ 12 => '#FFB8E9',
+ // format
+ 3584 => '#003804',
+ 14 => '#00FB12',
+ // version
+ 4096 => '#650098',
+ 16 => '#E0B8FF',
+ // data
+ 1024 => '#4A6000',
+ 4 => '#ECF9BE',
+ // darkmodule
+ 512 => '#080063',
+ // separator
+ 8 => '#AFBFBF',
+ // quietzone
+ 18 => '#FFFFFF',
+ ],
+ ]);
+
+ echo (new QRCode($options))->render($data);
+
+?>
+
+
+
+
+
+
diff --git a/vendor/chillerlan/php-qrcode/examples/image.php b/vendor/chillerlan/php-qrcode/examples/image.php
new file mode 100644
index 000000000..89ba2a9a8
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/image.php
@@ -0,0 +1,60 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+
+$options = new QROptions([
+ 'version' => 7,
+ 'outputType' => QRCode::OUTPUT_IMAGE_PNG,
+ 'eccLevel' => QRCode::ECC_L,
+ 'scale' => 5,
+ 'imageBase64' => false,
+ 'moduleValues' => [
+ // finder
+ 1536 => [0, 63, 255], // dark (true)
+ 6 => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
+ // alignment
+ 2560 => [255, 0, 255],
+ 10 => [255, 255, 255],
+ // timing
+ 3072 => [255, 0, 0],
+ 12 => [255, 255, 255],
+ // format
+ 3584 => [67, 191, 84],
+ 14 => [255, 255, 255],
+ // version
+ 4096 => [62, 174, 190],
+ 16 => [255, 255, 255],
+ // data
+ 1024 => [0, 0, 0],
+ 4 => [255, 255, 255],
+ // darkmodule
+ 512 => [0, 0, 0],
+ // separator
+ 8 => [255, 255, 255],
+ // quietzone
+ 18 => [255, 255, 255],
+ ],
+]);
+
+header('Content-type: image/png');
+
+echo (new QRCode($options))->render($data);
+
+
+
+
+
diff --git a/vendor/chillerlan/php-qrcode/examples/imageWithLogo.php b/vendor/chillerlan/php-qrcode/examples/imageWithLogo.php
new file mode 100644
index 000000000..987e10c11
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/imageWithLogo.php
@@ -0,0 +1,44 @@
+
+ * @copyright 2020 smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+/**
+ * @property int $logoWidth
+ * @property int $logoHeight
+ *
+ * @noinspection PhpIllegalPsrClassPathInspection
+ */
+class LogoOptions extends QROptions{
+ protected $logoWidth;
+ protected $logoHeight;
+}
+
+$options = new LogoOptions;
+
+$options->version = 7;
+$options->eccLevel = QRCode::ECC_H;
+$options->imageBase64 = false;
+$options->logoWidth = 13;
+$options->logoHeight = 13;
+$options->scale = 5;
+$options->imageTransparent = false;
+
+header('Content-type: image/png');
+
+$qrOutputInterface = new QRImageWithLogo($options, (new QRCode($options))->getMatrix($data));
+
+// dump the output, with an additional logo
+echo $qrOutputInterface->dump(null, __DIR__.'/octocat.png');
diff --git a/vendor/chillerlan/php-qrcode/examples/imageWithText.php b/vendor/chillerlan/php-qrcode/examples/imageWithText.php
new file mode 100644
index 000000000..050781cba
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/imageWithText.php
@@ -0,0 +1,33 @@
+
+ * @copyright 2019 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+
+$options = new QROptions([
+ 'version' => 7,
+ 'outputType' => QRCode::OUTPUT_IMAGE_PNG,
+ 'scale' => 3,
+ 'imageBase64' => false,
+]);
+
+header('Content-type: image/png');
+
+$qrOutputInterface = new QRImageWithText($options, (new QRCode($options))->getMatrix($data));
+
+// dump the output, with additional text
+echo $qrOutputInterface->dump(null, 'example text');
diff --git a/vendor/chillerlan/php-qrcode/examples/imagick.php b/vendor/chillerlan/php-qrcode/examples/imagick.php
new file mode 100644
index 000000000..6bec4d02e
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/imagick.php
@@ -0,0 +1,59 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+
+$options = new QROptions([
+ 'version' => 7,
+ 'outputType' => QRCode::OUTPUT_IMAGICK,
+ 'eccLevel' => QRCode::ECC_L,
+ 'scale' => 5,
+ 'moduleValues' => [
+ // finder
+ 1536 => '#A71111', // dark (true)
+ 6 => '#FFBFBF', // light (false)
+ // alignment
+ 2560 => '#A70364',
+ 10 => '#FFC9C9',
+ // timing
+ 3072 => '#98005D',
+ 12 => '#FFB8E9',
+ // format
+ 3584 => '#003804',
+ 14 => '#00FB12',
+ // version
+ 4096 => '#650098',
+ 16 => '#E0B8FF',
+ // data
+ 1024 => '#4A6000',
+ 4 => '#ECF9BE',
+ // darkmodule
+ 512 => '#080063',
+ // separator
+ 8 => '#DDDDDD',
+ // quietzone
+ 18 => '#DDDDDD',
+ ],
+]);
+
+header('Content-type: image/png');
+
+echo (new QRCode($options))->render($data);
+
+
+
+
+
diff --git a/vendor/chillerlan/php-qrcode/examples/octocat.png b/vendor/chillerlan/php-qrcode/examples/octocat.png
new file mode 100644
index 000000000..f9050b935
Binary files /dev/null and b/vendor/chillerlan/php-qrcode/examples/octocat.png differ
diff --git a/vendor/chillerlan/php-qrcode/examples/svg.php b/vendor/chillerlan/php-qrcode/examples/svg.php
new file mode 100644
index 000000000..a7a159d70
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/svg.php
@@ -0,0 +1,77 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+$gzip = true;
+
+$options = new QROptions([
+ 'version' => 7,
+ 'outputType' => QRCode::OUTPUT_MARKUP_SVG,
+ 'eccLevel' => QRCode::ECC_L,
+ 'svgViewBoxSize' => 530,
+ 'addQuietzone' => true,
+ 'cssClass' => 'my-css-class',
+ 'svgOpacity' => 1.0,
+ 'svgDefs' => '
+
+
+
+
+
+
+
+
+ ',
+ 'moduleValues' => [
+ // finder
+ 1536 => 'url(#g1)', // dark (true)
+ 6 => '#fff', // light (false)
+ // alignment
+ 2560 => 'url(#g1)',
+ 10 => '#fff',
+ // timing
+ 3072 => 'url(#g1)',
+ 12 => '#fff',
+ // format
+ 3584 => 'url(#g1)',
+ 14 => '#fff',
+ // version
+ 4096 => 'url(#g1)',
+ 16 => '#fff',
+ // data
+ 1024 => 'url(#g2)',
+ 4 => '#fff',
+ // darkmodule
+ 512 => 'url(#g1)',
+ // separator
+ 8 => '#fff',
+ // quietzone
+ 18 => '#fff',
+ ],
+]);
+
+$qrcode = (new QRCode($options))->render($data);
+
+header('Content-type: image/svg+xml');
+
+if($gzip === true){
+ header('Vary: Accept-Encoding');
+ header('Content-Encoding: gzip');
+ $qrcode = gzencode($qrcode ,9);
+}
+echo $qrcode;
+
+
diff --git a/vendor/chillerlan/php-qrcode/examples/text.php b/vendor/chillerlan/php-qrcode/examples/text.php
new file mode 100644
index 000000000..9bdf154f0
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/examples/text.php
@@ -0,0 +1,68 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeExamples;
+
+use chillerlan\QRCode\{QRCode, QROptions};
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
+
+$options = new QROptions([
+ 'version' => 5,
+ 'outputType' => QRCode::OUTPUT_STRING_TEXT,
+ 'eccLevel' => QRCode::ECC_L,
+]);
+
+// to view it in a browser
+echo ''.(new QRCode($options))->render($data).'
';
+
+
+// custom values
+$options = new QROptions([
+ 'version' => 5,
+ 'outputType' => QRCode::OUTPUT_STRING_TEXT,
+ 'eccLevel' => QRCode::ECC_L,
+ 'moduleValues' => [
+ // finder
+ 1536 => 'A', // dark (true)
+ 6 => 'a', // light (false)
+ // alignment
+ 2560 => 'B',
+ 10 => 'b',
+ // timing
+ 3072 => 'C',
+ 12 => 'c',
+ // format
+ 3584 => 'D',
+ 14 => 'd',
+ // version
+ 4096 => 'E',
+ 16 => 'e',
+ // data
+ 1024 => 'F',
+ 4 => 'f',
+ // darkmodule
+ 512 => 'G',
+ // separator
+ 8 => 'h',
+ // quietzone
+ 18 => 'i',
+ ],
+]);
+
+// to view it in a browser
+echo ''.(new QRCode($options))->render($data).'
';
+
+
+
+
+
diff --git a/vendor/chillerlan/php-qrcode/phpdoc.xml b/vendor/chillerlan/php-qrcode/phpdoc.xml
new file mode 100644
index 000000000..d191e98ee
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/phpdoc.xml
@@ -0,0 +1,15 @@
+
+
+
+ public/docs
+
+
+ public/docs
+
+
+ src
+
+
+
+
+
\ No newline at end of file
diff --git a/vendor/chillerlan/php-qrcode/phpmd.xml b/vendor/chillerlan/php-qrcode/phpmd.xml
new file mode 100644
index 000000000..a70f7e3a1
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/phpmd.xml
@@ -0,0 +1,34 @@
+
+
+ codemasher/php-qrcode PMD ruleset
+ */examples/*
+ */tests/*
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/chillerlan/php-qrcode/phpunit.xml b/vendor/chillerlan/php-qrcode/phpunit.xml
new file mode 100644
index 000000000..3a9b678d2
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/phpunit.xml
@@ -0,0 +1,23 @@
+
+
+
+ ./src
+
+
+
+
+ ./tests/
+
+
+
+
+
+
+
+
diff --git a/vendor/chillerlan/php-qrcode/public/index.html b/vendor/chillerlan/php-qrcode/public/index.html
new file mode 100644
index 000000000..d7bf6c891
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/public/index.html
@@ -0,0 +1,163 @@
+
+
+
+
+
+ QR Code Generator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vendor/chillerlan/php-qrcode/public/qrcode.php b/vendor/chillerlan/php-qrcode/public/qrcode.php
new file mode 100644
index 000000000..1f8427c7e
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/public/qrcode.php
@@ -0,0 +1,97 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodePublic;
+
+use chillerlan\QRCode\QRCode;
+use chillerlan\QRCode\QROptions;
+
+require_once '../vendor/autoload.php';
+
+try{
+
+ $moduleValues = [
+ // finder
+ 1536 => $_POST['m_finder_dark'],
+ 6 => $_POST['m_finder_light'],
+ // alignment
+ 2560 => $_POST['m_alignment_dark'],
+ 10 => $_POST['m_alignment_light'],
+ // timing
+ 3072 => $_POST['m_timing_dark'],
+ 12 => $_POST['m_timing_light'],
+ // format
+ 3584 => $_POST['m_format_dark'],
+ 14 => $_POST['m_format_light'],
+ // version
+ 4096 => $_POST['m_version_dark'],
+ 16 => $_POST['m_version_light'],
+ // data
+ 1024 => $_POST['m_data_dark'],
+ 4 => $_POST['m_data_light'],
+ // darkmodule
+ 512 => $_POST['m_darkmodule_dark'],
+ // separator
+ 8 => $_POST['m_separator_light'],
+ // quietzone
+ 18 => $_POST['m_quietzone_light'],
+ ];
+
+ $moduleValues = array_map(function($v){
+ if(preg_match('/[a-f\d]{6}/i', $v) === 1){
+ return in_array($_POST['output_type'], ['png', 'jpg', 'gif'])
+ ? array_map('hexdec', str_split($v, 2))
+ : '#'.$v ;
+ }
+ return null;
+ }, $moduleValues);
+
+
+ $ecc = in_array($_POST['ecc'], ['L', 'M', 'Q', 'H'], true) ? $_POST['ecc'] : 'L';
+
+ $qro = new QROptions;
+
+ $qro->version = (int)$_POST['version'];
+ $qro->eccLevel = constant('chillerlan\\QRCode\\QRCode::ECC_'.$ecc);
+ $qro->maskPattern = (int)$_POST['maskpattern'];
+ $qro->addQuietzone = isset($_POST['quietzone']);
+ $qro->quietzoneSize = (int)$_POST['quietzonesize'];
+ $qro->moduleValues = $moduleValues;
+ $qro->outputType = $_POST['output_type'];
+ $qro->scale = (int)$_POST['scale'];
+ $qro->imageTransparent = false;
+
+ $qrcode = (new QRCode($qro))->render($_POST['inputstring']);
+
+ if(in_array($_POST['output_type'], ['png', 'jpg', 'gif'])){
+ $qrcode = '';
+ }
+ elseif($_POST['output_type'] === 'text'){
+ $qrcode = ''.$qrcode.'
';
+ }
+ elseif($_POST['output_type'] === 'json'){
+ $qrcode = ''.$qrcode.'
';
+ }
+
+ send_response(['qrcode' => $qrcode]);
+}
+// Pokémon exception handler
+catch(\Exception $e){
+ header('HTTP/1.1 500 Internal Server Error');
+ send_response(['error' => $e->getMessage()]);
+}
+
+/**
+ * @param array $response
+ */
+function send_response(array $response){
+ header('Content-type: application/json;charset=utf-8;');
+ echo json_encode($response);
+ exit;
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php b/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php
new file mode 100644
index 000000000..c6d34e76f
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php
@@ -0,0 +1,65 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+use chillerlan\QRCode\QRCode;
+
+use function array_search, ord, sprintf;
+
+/**
+ * Alphanumeric mode: 0 to 9, A to Z, space, $ % * + - . / :
+ */
+class AlphaNum extends QRDataAbstract{
+
+ /**
+ * @inheritdoc
+ */
+ protected $datamode = QRCode::DATA_ALPHANUM;
+
+ /**
+ * @inheritdoc
+ */
+ protected $lengthBits = [9, 11, 13];
+
+ /**
+ * @inheritdoc
+ */
+ protected function write(string $data):void{
+
+ for($i = 0; $i + 1 < $this->strlen; $i += 2){
+ $this->bitBuffer->put($this->getCharCode($data[$i]) * 45 + $this->getCharCode($data[$i + 1]), 11);
+ }
+
+ if($i < $this->strlen){
+ $this->bitBuffer->put($this->getCharCode($data[$i]), 6);
+ }
+
+ }
+
+ /**
+ * @param string $chr
+ *
+ * @return int
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ */
+ protected function getCharCode(string $chr):int{
+ $i = array_search($chr, $this::ALPHANUM_CHAR_MAP);
+
+ if($i !== false){
+ return $i;
+ }
+
+ throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $chr, ord($chr)));
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Data/Byte.php b/vendor/chillerlan/php-qrcode/src/Data/Byte.php
new file mode 100644
index 000000000..f1955645a
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Data/Byte.php
@@ -0,0 +1,47 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+use chillerlan\QRCode\QRCode;
+
+use function ord;
+
+/**
+ * Byte mode, ISO-8859-1 or UTF-8
+ */
+class Byte extends QRDataAbstract{
+
+ /**
+ * @inheritdoc
+ */
+ protected $datamode = QRCode::DATA_BYTE;
+
+ /**
+ * @inheritdoc
+ */
+ protected $lengthBits = [8, 16, 16];
+
+ /**
+ * @inheritdoc
+ */
+ protected function write(string $data):void{
+ $i = 0;
+
+ while($i < $this->strlen){
+ $this->bitBuffer->put(ord($data[$i]), 8);
+ $i++;
+ }
+
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Data/Kanji.php b/vendor/chillerlan/php-qrcode/src/Data/Kanji.php
new file mode 100644
index 000000000..ce600d4ff
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Data/Kanji.php
@@ -0,0 +1,70 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+use chillerlan\QRCode\QRCode;
+
+use function mb_strlen, ord, sprintf, strlen;
+
+/**
+ * Kanji mode: double-byte characters from the Shift JIS character set
+ */
+class Kanji extends QRDataAbstract{
+
+ /**
+ * @inheritdoc
+ */
+ protected $datamode = QRCode::DATA_KANJI;
+
+ /**
+ * @inheritdoc
+ */
+ protected $lengthBits = [8, 10, 12];
+
+ /**
+ * @inheritdoc
+ */
+ protected function getLength(string $data):int{
+ return mb_strlen($data, 'SJIS');
+ }
+
+ /**
+ * @inheritdoc
+ */
+ protected function write(string $data):void{
+ $len = strlen($data);
+
+ for($i = 0; $i + 1 < $len; $i += 2){
+ $c = ((0xff & ord($data[$i])) << 8) | (0xff & ord($data[$i + 1]));
+
+ if(0x8140 <= $c && $c <= 0x9FFC){
+ $c -= 0x8140;
+ }
+ elseif(0xE040 <= $c && $c <= 0xEBBF){
+ $c -= 0xC140;
+ }
+ else{
+ throw new QRCodeDataException(sprintf('illegal char at %d [%d]', $i + 1, $c));
+ }
+
+ $this->bitBuffer->put((($c >> 8) & 0xff) * 0xC0 + ($c & 0xff), 13);
+
+ }
+
+ if($i < $len){
+ throw new QRCodeDataException(sprintf('illegal char at %d', $i + 1));
+ }
+
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php b/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php
new file mode 100644
index 000000000..8dfd24180
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php
@@ -0,0 +1,203 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+use function abs, call_user_func_array;
+
+/**
+ * The sole purpose of this class is to receive a QRMatrix object and run the pattern tests on it.
+ *
+ * @link http://www.thonky.com/qr-code-tutorial/data-masking
+ */
+class MaskPatternTester{
+
+ /**
+ * @var \chillerlan\QRCode\Data\QRMatrix
+ */
+ protected $matrix;
+
+ /**
+ * @var int
+ */
+ protected $moduleCount;
+
+ /**
+ * Receives the matrix an sets the module count
+ *
+ * @see \chillerlan\QRCode\QROptions::$maskPattern
+ * @see \chillerlan\QRCode\Data\QRMatrix::$maskPattern
+ * @see \chillerlan\QRCode\QRCode::getBestMaskPattern()
+ *
+ * @param \chillerlan\QRCode\Data\QRMatrix $matrix
+ */
+ public function __construct(QRMatrix $matrix){
+ $this->matrix = $matrix;
+ $this->moduleCount = $this->matrix->size();
+ }
+
+ /**
+ * Returns the penalty for the given mask pattern
+ *
+ * @see \chillerlan\QRCode\QROptions::$maskPattern
+ * @see \chillerlan\QRCode\Data\QRMatrix::$maskPattern
+ * @see \chillerlan\QRCode\QRCode::getBestMaskPattern()
+ *
+ * @return int
+ */
+ public function testPattern():int{
+ $penalty = 0;
+
+ for($level = 1; $level <= 4; $level++){
+ $penalty += call_user_func_array([$this, 'testLevel'.$level], [$this->matrix->matrix(true)]);
+ }
+
+ return (int)$penalty;
+ }
+
+ /**
+ * Checks for each group of five or more same-colored modules in a row (or column)
+ *
+ * @return int
+ */
+ protected function testLevel1(array $m):int{
+ $penalty = 0;
+
+ foreach($m as $y => $row){
+ foreach($row as $x => $val){
+ $count = 0;
+
+ for($ry = -1; $ry <= 1; $ry++){
+
+ if($y + $ry < 0 || $this->moduleCount <= $y + $ry){
+ continue;
+ }
+
+ for($rx = -1; $rx <= 1; $rx++){
+
+ if(($ry === 0 && $rx === 0) || (($x + $rx) < 0 || $this->moduleCount <= ($x + $rx))){
+ continue;
+ }
+
+ if($m[$y + $ry][$x + $rx] === $val){
+ $count++;
+ }
+
+ }
+ }
+
+ if($count > 5){
+ $penalty += (3 + $count - 5);
+ }
+
+ }
+ }
+
+ return $penalty;
+ }
+
+ /**
+ * Checks for each 2x2 area of same-colored modules in the matrix
+ *
+ * @return int
+ */
+ protected function testLevel2(array $m):int{
+ $penalty = 0;
+
+ foreach($m as $y => $row){
+
+ if($y > ($this->moduleCount - 2)){
+ break;
+ }
+
+ foreach($row as $x => $val){
+
+ if($x > ($this->moduleCount - 2)){
+ break;
+ }
+
+ if(
+ $val === $m[$y][$x + 1]
+ && $val === $m[$y + 1][$x]
+ && $val === $m[$y + 1][$x + 1]
+ ){
+ $penalty++;
+ }
+ }
+ }
+
+ return 3 * $penalty;
+ }
+
+ /**
+ * Checks if there are patterns that look similar to the finder patterns (1:1:3:1:1 ratio)
+ *
+ * @return int
+ */
+ protected function testLevel3(array $m):int{
+ $penalties = 0;
+
+ foreach($m as $y => $row){
+ foreach($row as $x => $val){
+
+ if(
+ ($x + 6) < $this->moduleCount
+ && $val
+ && !$m[$y][$x + 1]
+ && $m[$y][$x + 2]
+ && $m[$y][$x + 3]
+ && $m[$y][$x + 4]
+ && !$m[$y][$x + 5]
+ && $m[$y][$x + 6]
+ ){
+ $penalties++;
+ }
+
+ if(
+ ($y + 6) < $this->moduleCount
+ && $val
+ && !$m[$y + 1][$x]
+ && $m[$y + 2][$x]
+ && $m[$y + 3][$x]
+ && $m[$y + 4][$x]
+ && !$m[$y + 5][$x]
+ && $m[$y + 6][$x]
+ ){
+ $penalties++;
+ }
+
+ }
+ }
+
+ return $penalties * 40;
+ }
+
+ /**
+ * Checks if more than half of the modules are dark or light, with a larger penalty for a larger difference
+ *
+ * @return float
+ */
+ protected function testLevel4(array $m):float{
+ $count = 0;
+
+ foreach($m as $y => $row){
+ foreach($row as $x => $val){
+ if($val){
+ $count++;
+ }
+ }
+ }
+
+ return (abs(100 * $count / $this->moduleCount / $this->moduleCount - 50) / 5) * 10;
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Data/Number.php b/vendor/chillerlan/php-qrcode/src/Data/Number.php
new file mode 100644
index 000000000..3936d12c3
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Data/Number.php
@@ -0,0 +1,82 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+use chillerlan\QRCode\QRCode;
+
+use function ord, sprintf, substr;
+
+/**
+ * Numeric mode: decimal digits 0 through 9
+ */
+class Number extends QRDataAbstract{
+
+ /**
+ * @inheritdoc
+ */
+ protected $datamode = QRCode::DATA_NUMBER;
+
+ /**
+ * @inheritdoc
+ */
+ protected $lengthBits = [10, 12, 14];
+
+ /**
+ * @inheritdoc
+ */
+ protected function write(string $data):void{
+ $i = 0;
+
+ while($i + 2 < $this->strlen){
+ $this->bitBuffer->put($this->parseInt(substr($data, $i, 3)), 10);
+ $i += 3;
+ }
+
+ if($i < $this->strlen){
+
+ if($this->strlen - $i === 1){
+ $this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 1)), 4);
+ }
+ elseif($this->strlen - $i === 2){
+ $this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 2)), 7);
+ }
+
+ }
+
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return int
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ */
+ protected function parseInt(string $string):int{
+ $num = 0;
+
+ $len = strlen($string);
+ for($i = 0; $i < $len; $i++){
+ $c = ord($string[$i]);
+
+ if(!in_array($string[$i], $this::NUMBER_CHAR_MAP, true)){
+ throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $string[$i], $c));
+ }
+
+ $c = $c - 48; // ord('0')
+ $num = $num * 10 + $c;
+ }
+
+ return $num;
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRCodeDataException.php b/vendor/chillerlan/php-qrcode/src/Data/QRCodeDataException.php
new file mode 100644
index 000000000..862f57ba0
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Data/QRCodeDataException.php
@@ -0,0 +1,17 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+use chillerlan\QRCode\QRCodeException;
+
+class QRCodeDataException extends QRCodeException{}
diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php b/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php
new file mode 100644
index 000000000..f52767e38
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php
@@ -0,0 +1,351 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+use chillerlan\QRCode\{QRCode, QRCodeException};
+use chillerlan\QRCode\Helpers\{BitBuffer, Polynomial};
+use chillerlan\Settings\SettingsContainerInterface;
+
+use function array_fill, array_merge, count, max, mb_convert_encoding, mb_detect_encoding, range, sprintf, strlen;
+
+/**
+ * Processes the binary data and maps it on a matrix which is then being returned
+ */
+abstract class QRDataAbstract implements QRDataInterface{
+
+ /**
+ * the string byte count
+ *
+ * @var int
+ */
+ protected $strlen;
+
+ /**
+ * the current data mode: Num, Alphanum, Kanji, Byte
+ *
+ * @var int
+ */
+ protected $datamode;
+
+ /**
+ * mode length bits for the version breakpoints 1-9, 10-26 and 27-40
+ *
+ * @var array
+ */
+ protected $lengthBits = [0, 0, 0];
+
+ /**
+ * current QR Code version
+ *
+ * @var int
+ */
+ protected $version;
+
+ /**
+ * the raw data that's being passed to QRMatrix::mapData()
+ *
+ * @var array
+ */
+ protected $matrixdata;
+
+ /**
+ * ECC temp data
+ *
+ * @var array
+ */
+ protected $ecdata;
+
+ /**
+ * ECC temp data
+ *
+ * @var array
+ */
+ protected $dcdata;
+
+ /**
+ * @var \chillerlan\QRCode\QROptions
+ */
+ protected $options;
+
+ /**
+ * @var \chillerlan\QRCode\Helpers\BitBuffer
+ */
+ protected $bitBuffer;
+
+ /**
+ * QRDataInterface constructor.
+ *
+ * @param \chillerlan\Settings\SettingsContainerInterface $options
+ * @param string|null $data
+ */
+ public function __construct(SettingsContainerInterface $options, string $data = null){
+ $this->options = $options;
+
+ if($data !== null){
+ $this->setData($data);
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function setData(string $data):QRDataInterface{
+
+ if($this->datamode === QRCode::DATA_KANJI){
+ $data = mb_convert_encoding($data, 'SJIS', mb_detect_encoding($data));
+ }
+
+ $this->strlen = $this->getLength($data);
+ $this->version = $this->options->version === QRCode::VERSION_AUTO
+ ? $this->getMinimumVersion()
+ : $this->options->version;
+
+ $this->matrixdata = $this
+ ->writeBitBuffer($data)
+ ->maskECC()
+ ;
+
+ return $this;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function initMatrix(int $maskPattern, bool $test = null):QRMatrix{
+ return (new QRMatrix($this->version, $this->options->eccLevel))
+ ->setFinderPattern()
+ ->setSeparators()
+ ->setAlignmentPattern()
+ ->setTimingPattern()
+ ->setVersionNumber($test)
+ ->setFormatInfo($maskPattern, $test)
+ ->setDarkModule()
+ ->mapData($this->matrixdata, $maskPattern)
+ ;
+ }
+
+ /**
+ * returns the length bits for the version breakpoints 1-9, 10-26 and 27-40
+ *
+ * @return int
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ * @codeCoverageIgnore
+ */
+ protected function getLengthBits():int{
+
+ foreach([9, 26, 40] as $key => $breakpoint){
+ if($this->version <= $breakpoint){
+ return $this->lengthBits[$key];
+ }
+ }
+
+ throw new QRCodeDataException(sprintf('invalid version number: %d', $this->version));
+ }
+
+ /**
+ * returns the byte count of the $data string
+ *
+ * @param string $data
+ *
+ * @return int
+ */
+ protected function getLength(string $data):int{
+ return strlen($data);
+ }
+
+ /**
+ * returns the minimum version number for the given string
+ *
+ * @return int
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ */
+ protected function getMinimumVersion():int{
+ $maxlength = 0;
+
+ // guess the version number within the given range
+ foreach(range($this->options->versionMin, $this->options->versionMax) as $version){
+ $maxlength = $this::MAX_LENGTH[$version][QRCode::DATA_MODES[$this->datamode]][QRCode::ECC_MODES[$this->options->eccLevel]];
+
+ if($this->strlen <= $maxlength){
+ return $version;
+ }
+ }
+
+ throw new QRCodeDataException(sprintf('data exceeds %d characters', $maxlength));
+ }
+
+ /**
+ * writes the actual data string to the BitBuffer
+ *
+ * @see \chillerlan\QRCode\Data\QRDataAbstract::writeBitBuffer()
+ *
+ * @param string $data
+ *
+ * @return void
+ */
+ abstract protected function write(string $data):void;
+
+ /**
+ * creates a BitBuffer and writes the string data to it
+ *
+ * @param string $data
+ *
+ * @return \chillerlan\QRCode\Data\QRDataAbstract
+ * @throws \chillerlan\QRCode\QRCodeException
+ */
+ protected function writeBitBuffer(string $data):QRDataInterface{
+ $this->bitBuffer = new BitBuffer;
+
+ $MAX_BITS = $this::MAX_BITS[$this->version][QRCode::ECC_MODES[$this->options->eccLevel]];
+
+ $this->bitBuffer
+ ->clear()
+ ->put($this->datamode, 4)
+ ->put($this->strlen, $this->getLengthBits())
+ ;
+
+ $this->write($data);
+
+ // there was an error writing the BitBuffer data, which is... unlikely.
+ if($this->bitBuffer->length > $MAX_BITS){
+ throw new QRCodeException(sprintf('code length overflow. (%d > %d bit)', $this->bitBuffer->length, $MAX_BITS)); // @codeCoverageIgnore
+ }
+
+ // end code.
+ if($this->bitBuffer->length + 4 <= $MAX_BITS){
+ $this->bitBuffer->put(0, 4);
+ }
+
+ // padding
+ while($this->bitBuffer->length % 8 !== 0){
+ $this->bitBuffer->putBit(false);
+ }
+
+ // padding
+ while(true){
+
+ if($this->bitBuffer->length >= $MAX_BITS){
+ break;
+ }
+
+ $this->bitBuffer->put(0xEC, 8);
+
+ if($this->bitBuffer->length >= $MAX_BITS){
+ break;
+ }
+
+ $this->bitBuffer->put(0x11, 8);
+ }
+
+ return $this;
+ }
+
+ /**
+ * ECC masking
+ *
+ * @link http://www.thonky.com/qr-code-tutorial/error-correction-coding
+ *
+ * @return array
+ */
+ protected function maskECC():array{
+ [$l1, $l2, $b1, $b2] = $this::RSBLOCKS[$this->version][QRCode::ECC_MODES[$this->options->eccLevel]];
+
+ $rsBlocks = array_fill(0, $l1, [$b1, $b2]);
+ $rsCount = $l1 + $l2;
+ $this->ecdata = array_fill(0, $rsCount, null);
+ $this->dcdata = $this->ecdata;
+
+ if($l2 > 0){
+ $rsBlocks = array_merge($rsBlocks, array_fill(0, $l2, [$b1 + 1, $b2 + 1]));
+ }
+
+ $totalCodeCount = 0;
+ $maxDcCount = 0;
+ $maxEcCount = 0;
+ $offset = 0;
+
+ foreach($rsBlocks as $key => $block){
+ [$rsBlockTotal, $dcCount] = $block;
+
+ $ecCount = $rsBlockTotal - $dcCount;
+ $maxDcCount = max($maxDcCount, $dcCount);
+ $maxEcCount = max($maxEcCount, $ecCount);
+ $this->dcdata[$key] = array_fill(0, $dcCount, null);
+
+ foreach($this->dcdata[$key] as $a => $_z){
+ $this->dcdata[$key][$a] = 0xff & $this->bitBuffer->buffer[$a + $offset];
+ }
+
+ [$num, $add] = $this->poly($key, $ecCount);
+
+ foreach($this->ecdata[$key] as $c => $_z){
+ $modIndex = $c + $add;
+ $this->ecdata[$key][$c] = $modIndex >= 0 ? $num[$modIndex] : 0;
+ }
+
+ $offset += $dcCount;
+ $totalCodeCount += $rsBlockTotal;
+ }
+
+ $data = array_fill(0, $totalCodeCount, null);
+ $index = 0;
+
+ $mask = function($arr, $count) use (&$data, &$index, $rsCount){
+ for($x = 0; $x < $count; $x++){
+ for($y = 0; $y < $rsCount; $y++){
+ if($x < count($arr[$y])){
+ $data[$index] = $arr[$y][$x];
+ $index++;
+ }
+ }
+ }
+ };
+
+ $mask($this->dcdata, $maxDcCount);
+ $mask($this->ecdata, $maxEcCount);
+
+ return $data;
+ }
+
+ /**
+ * @param int $key
+ * @param int $count
+ *
+ * @return int[]
+ */
+ protected function poly(int $key, int $count):array{
+ $rsPoly = new Polynomial;
+ $modPoly = new Polynomial;
+
+ for($i = 0; $i < $count; $i++){
+ $modPoly->setNum([1, $modPoly->gexp($i)]);
+ $rsPoly->multiply($modPoly->getNum());
+ }
+
+ $rsPolyCount = count($rsPoly->getNum());
+
+ $modPoly
+ ->setNum($this->dcdata[$key], $rsPolyCount - 1)
+ ->mod($rsPoly->getNum())
+ ;
+
+ $this->ecdata[$key] = array_fill(0, $rsPolyCount - 1, null);
+ $num = $modPoly->getNum();
+
+ return [
+ $num,
+ count($num) - count($this->ecdata[$key]),
+ ];
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php b/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php
new file mode 100644
index 000000000..653386222
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php
@@ -0,0 +1,187 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+/**
+ *
+ */
+interface QRDataInterface{
+
+ const NUMBER_CHAR_MAP = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
+
+ const ALPHANUM_CHAR_MAP = [
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+ 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
+ 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*',
+ '+', '-', '.', '/', ':',
+ ];
+
+ /**
+ * @link http://www.qrcode.com/en/about/version.html
+ */
+ const MAX_LENGTH =[
+ // v => [NUMERIC => [L, M, Q, H ], ALPHANUM => [L, M, Q, H], BINARY => [L, M, Q, H ], KANJI => [L, M, Q, H ]] // modules
+ 1 => [[ 41, 34, 27, 17], [ 25, 20, 16, 10], [ 17, 14, 11, 7], [ 10, 8, 7, 4]], // 21
+ 2 => [[ 77, 63, 48, 34], [ 47, 38, 29, 20], [ 32, 26, 20, 14], [ 20, 16, 12, 8]], // 25
+ 3 => [[ 127, 101, 77, 58], [ 77, 61, 47, 35], [ 53, 42, 32, 24], [ 32, 26, 20, 15]], // 29
+ 4 => [[ 187, 149, 111, 82], [ 114, 90, 67, 50], [ 78, 62, 46, 34], [ 48, 38, 28, 21]], // 33
+ 5 => [[ 255, 202, 144, 106], [ 154, 122, 87, 64], [ 106, 84, 60, 44], [ 65, 52, 37, 27]], // 37
+ 6 => [[ 322, 255, 178, 139], [ 195, 154, 108, 84], [ 134, 106, 74, 58], [ 82, 65, 45, 36]], // 41
+ 7 => [[ 370, 293, 207, 154], [ 224, 178, 125, 93], [ 154, 122, 86, 64], [ 95, 75, 53, 39]], // 45
+ 8 => [[ 461, 365, 259, 202], [ 279, 221, 157, 122], [ 192, 152, 108, 84], [ 118, 93, 66, 52]], // 49
+ 9 => [[ 552, 432, 312, 235], [ 335, 262, 189, 143], [ 230, 180, 130, 98], [ 141, 111, 80, 60]], // 53
+ 10 => [[ 652, 513, 364, 288], [ 395, 311, 221, 174], [ 271, 213, 151, 119], [ 167, 131, 93, 74]], // 57
+ 11 => [[ 772, 604, 427, 331], [ 468, 366, 259, 200], [ 321, 251, 177, 137], [ 198, 155, 109, 85]], // 61
+ 12 => [[ 883, 691, 489, 374], [ 535, 419, 296, 227], [ 367, 287, 203, 155], [ 226, 177, 125, 96]], // 65
+ 13 => [[1022, 796, 580, 427], [ 619, 483, 352, 259], [ 425, 331, 241, 177], [ 262, 204, 149, 109]], // 69 NICE!
+ 14 => [[1101, 871, 621, 468], [ 667, 528, 376, 283], [ 458, 362, 258, 194], [ 282, 223, 159, 120]], // 73
+ 15 => [[1250, 991, 703, 530], [ 758, 600, 426, 321], [ 520, 412, 292, 220], [ 320, 254, 180, 136]], // 77
+ 16 => [[1408, 1082, 775, 602], [ 854, 656, 470, 365], [ 586, 450, 322, 250], [ 361, 277, 198, 154]], // 81
+ 17 => [[1548, 1212, 876, 674], [ 938, 734, 531, 408], [ 644, 504, 364, 280], [ 397, 310, 224, 173]], // 85
+ 18 => [[1725, 1346, 948, 746], [1046, 816, 574, 452], [ 718, 560, 394, 310], [ 442, 345, 243, 191]], // 89
+ 19 => [[1903, 1500, 1063, 813], [1153, 909, 644, 493], [ 792, 624, 442, 338], [ 488, 384, 272, 208]], // 93
+ 20 => [[2061, 1600, 1159, 919], [1249, 970, 702, 557], [ 858, 666, 482, 382], [ 528, 410, 297, 235]], // 97
+ 21 => [[2232, 1708, 1224, 969], [1352, 1035, 742, 587], [ 929, 711, 509, 403], [ 572, 438, 314, 248]], // 101
+ 22 => [[2409, 1872, 1358, 1056], [1460, 1134, 823, 640], [1003, 779, 565, 439], [ 618, 480, 348, 270]], // 105
+ 23 => [[2620, 2059, 1468, 1108], [1588, 1248, 890, 672], [1091, 857, 611, 461], [ 672, 528, 376, 284]], // 109
+ 24 => [[2812, 2188, 1588, 1228], [1704, 1326, 963, 744], [1171, 911, 661, 511], [ 721, 561, 407, 315]], // 113
+ 25 => [[3057, 2395, 1718, 1286], [1853, 1451, 1041, 779], [1273, 997, 715, 535], [ 784, 614, 440, 330]], // 117
+ 26 => [[3283, 2544, 1804, 1425], [1990, 1542, 1094, 864], [1367, 1059, 751, 593], [ 842, 652, 462, 365]], // 121
+ 27 => [[3517, 2701, 1933, 1501], [2132, 1637, 1172, 910], [1465, 1125, 805, 625], [ 902, 692, 496, 385]], // 125
+ 28 => [[3669, 2857, 2085, 1581], [2223, 1732, 1263, 958], [1528, 1190, 868, 658], [ 940, 732, 534, 405]], // 129
+ 29 => [[3909, 3035, 2181, 1677], [2369, 1839, 1322, 1016], [1628, 1264, 908, 698], [1002, 778, 559, 430]], // 133
+ 30 => [[4158, 3289, 2358, 1782], [2520, 1994, 1429, 1080], [1732, 1370, 982, 742], [1066, 843, 604, 457]], // 137
+ 31 => [[4417, 3486, 2473, 1897], [2677, 2113, 1499, 1150], [1840, 1452, 1030, 790], [1132, 894, 634, 486]], // 141
+ 32 => [[4686, 3693, 2670, 2022], [2840, 2238, 1618, 1226], [1952, 1538, 1112, 842], [1201, 947, 684, 518]], // 145
+ 33 => [[4965, 3909, 2805, 2157], [3009, 2369, 1700, 1307], [2068, 1628, 1168, 898], [1273, 1002, 719, 553]], // 149
+ 34 => [[5253, 4134, 2949, 2301], [3183, 2506, 1787, 1394], [2188, 1722, 1228, 958], [1347, 1060, 756, 590]], // 153
+ 35 => [[5529, 4343, 3081, 2361], [3351, 2632, 1867, 1431], [2303, 1809, 1283, 983], [1417, 1113, 790, 605]], // 157
+ 36 => [[5836, 4588, 3244, 2524], [3537, 2780, 1966, 1530], [2431, 1911, 1351, 1051], [1496, 1176, 832, 647]], // 161
+ 37 => [[6153, 4775, 3417, 2625], [3729, 2894, 2071, 1591], [2563, 1989, 1423, 1093], [1577, 1224, 876, 673]], // 165
+ 38 => [[6479, 5039, 3599, 2735], [3927, 3054, 2181, 1658], [2699, 2099, 1499, 1139], [1661, 1292, 923, 701]], // 169
+ 39 => [[6743, 5313, 3791, 2927], [4087, 3220, 2298, 1774], [2809, 2213, 1579, 1219], [1729, 1362, 972, 750]], // 173
+ 40 => [[7089, 5596, 3993, 3057], [4296, 3391, 2420, 1852], [2953, 2331, 1663, 1273], [1817, 1435, 1024, 784]], // 177
+ ];
+
+ const MAX_BITS = [
+ // version => [L, M, Q, H ]
+ 1 => [ 152, 128, 104, 72],
+ 2 => [ 272, 224, 176, 128],
+ 3 => [ 440, 352, 272, 208],
+ 4 => [ 640, 512, 384, 288],
+ 5 => [ 864, 688, 496, 368],
+ 6 => [ 1088, 864, 608, 480],
+ 7 => [ 1248, 992, 704, 528],
+ 8 => [ 1552, 1232, 880, 688],
+ 9 => [ 1856, 1456, 1056, 800],
+ 10 => [ 2192, 1728, 1232, 976],
+ 11 => [ 2592, 2032, 1440, 1120],
+ 12 => [ 2960, 2320, 1648, 1264],
+ 13 => [ 3424, 2672, 1952, 1440],
+ 14 => [ 3688, 2920, 2088, 1576],
+ 15 => [ 4184, 3320, 2360, 1784],
+ 16 => [ 4712, 3624, 2600, 2024],
+ 17 => [ 5176, 4056, 2936, 2264],
+ 18 => [ 5768, 4504, 3176, 2504],
+ 19 => [ 6360, 5016, 3560, 2728],
+ 20 => [ 6888, 5352, 3880, 3080],
+ 21 => [ 7456, 5712, 4096, 3248],
+ 22 => [ 8048, 6256, 4544, 3536],
+ 23 => [ 8752, 6880, 4912, 3712],
+ 24 => [ 9392, 7312, 5312, 4112],
+ 25 => [10208, 8000, 5744, 4304],
+ 26 => [10960, 8496, 6032, 4768],
+ 27 => [11744, 9024, 6464, 5024],
+ 28 => [12248, 9544, 6968, 5288],
+ 29 => [13048, 10136, 7288, 5608],
+ 30 => [13880, 10984, 7880, 5960],
+ 31 => [14744, 11640, 8264, 6344],
+ 32 => [15640, 12328, 8920, 6760],
+ 33 => [16568, 13048, 9368, 7208],
+ 34 => [17528, 13800, 9848, 7688],
+ 35 => [18448, 14496, 10288, 7888],
+ 36 => [19472, 15312, 10832, 8432],
+ 37 => [20528, 15936, 11408, 8768],
+ 38 => [21616, 16816, 12016, 9136],
+ 39 => [22496, 17728, 12656, 9776],
+ 40 => [23648, 18672, 13328, 10208],
+ ];
+
+ /**
+ * @link http://www.thonky.com/qr-code-tutorial/error-correction-table
+ */
+ const RSBLOCKS = [
+ 1 => [[ 1, 0, 26, 19], [ 1, 0, 26, 16], [ 1, 0, 26, 13], [ 1, 0, 26, 9]],
+ 2 => [[ 1, 0, 44, 34], [ 1, 0, 44, 28], [ 1, 0, 44, 22], [ 1, 0, 44, 16]],
+ 3 => [[ 1, 0, 70, 55], [ 1, 0, 70, 44], [ 2, 0, 35, 17], [ 2, 0, 35, 13]],
+ 4 => [[ 1, 0, 100, 80], [ 2, 0, 50, 32], [ 2, 0, 50, 24], [ 4, 0, 25, 9]],
+ 5 => [[ 1, 0, 134, 108], [ 2, 0, 67, 43], [ 2, 2, 33, 15], [ 2, 2, 33, 11]],
+ 6 => [[ 2, 0, 86, 68], [ 4, 0, 43, 27], [ 4, 0, 43, 19], [ 4, 0, 43, 15]],
+ 7 => [[ 2, 0, 98, 78], [ 4, 0, 49, 31], [ 2, 4, 32, 14], [ 4, 1, 39, 13]],
+ 8 => [[ 2, 0, 121, 97], [ 2, 2, 60, 38], [ 4, 2, 40, 18], [ 4, 2, 40, 14]],
+ 9 => [[ 2, 0, 146, 116], [ 3, 2, 58, 36], [ 4, 4, 36, 16], [ 4, 4, 36, 12]],
+ 10 => [[ 2, 2, 86, 68], [ 4, 1, 69, 43], [ 6, 2, 43, 19], [ 6, 2, 43, 15]],
+ 11 => [[ 4, 0, 101, 81], [ 1, 4, 80, 50], [ 4, 4, 50, 22], [ 3, 8, 36, 12]],
+ 12 => [[ 2, 2, 116, 92], [ 6, 2, 58, 36], [ 4, 6, 46, 20], [ 7, 4, 42, 14]],
+ 13 => [[ 4, 0, 133, 107], [ 8, 1, 59, 37], [ 8, 4, 44, 20], [12, 4, 33, 11]],
+ 14 => [[ 3, 1, 145, 115], [ 4, 5, 64, 40], [11, 5, 36, 16], [11, 5, 36, 12]],
+ 15 => [[ 5, 1, 109, 87], [ 5, 5, 65, 41], [ 5, 7, 54, 24], [11, 7, 36, 12]],
+ 16 => [[ 5, 1, 122, 98], [ 7, 3, 73, 45], [15, 2, 43, 19], [ 3, 13, 45, 15]],
+ 17 => [[ 1, 5, 135, 107], [10, 1, 74, 46], [ 1, 15, 50, 22], [ 2, 17, 42, 14]],
+ 18 => [[ 5, 1, 150, 120], [ 9, 4, 69, 43], [17, 1, 50, 22], [ 2, 19, 42, 14]],
+ 19 => [[ 3, 4, 141, 113], [ 3, 11, 70, 44], [17, 4, 47, 21], [ 9, 16, 39, 13]],
+ 20 => [[ 3, 5, 135, 107], [ 3, 13, 67, 41], [15, 5, 54, 24], [15, 10, 43, 15]],
+ 21 => [[ 4, 4, 144, 116], [17, 0, 68, 42], [17, 6, 50, 22], [19, 6, 46, 16]],
+ 22 => [[ 2, 7, 139, 111], [17, 0, 74, 46], [ 7, 16, 54, 24], [34, 0, 37, 13]],
+ 23 => [[ 4, 5, 151, 121], [ 4, 14, 75, 47], [11, 14, 54, 24], [16, 14, 45, 15]],
+ 24 => [[ 6, 4, 147, 117], [ 6, 14, 73, 45], [11, 16, 54, 24], [30, 2, 46, 16]],
+ 25 => [[ 8, 4, 132, 106], [ 8, 13, 75, 47], [ 7, 22, 54, 24], [22, 13, 45, 15]],
+ 26 => [[10, 2, 142, 114], [19, 4, 74, 46], [28, 6, 50, 22], [33, 4, 46, 16]],
+ 27 => [[ 8, 4, 152, 122], [22, 3, 73, 45], [ 8, 26, 53, 23], [12, 28, 45, 15]],
+ 28 => [[ 3, 10, 147, 117], [ 3, 23, 73, 45], [ 4, 31, 54, 24], [11, 31, 45, 15]],
+ 29 => [[ 7, 7, 146, 116], [21, 7, 73, 45], [ 1, 37, 53, 23], [19, 26, 45, 15]],
+ 30 => [[ 5, 10, 145, 115], [19, 10, 75, 47], [15, 25, 54, 24], [23, 25, 45, 15]],
+ 31 => [[13, 3, 145, 115], [ 2, 29, 74, 46], [42, 1, 54, 24], [23, 28, 45, 15]],
+ 32 => [[17, 0, 145, 115], [10, 23, 74, 46], [10, 35, 54, 24], [19, 35, 45, 15]],
+ 33 => [[17, 1, 145, 115], [14, 21, 74, 46], [29, 19, 54, 24], [11, 46, 45, 15]],
+ 34 => [[13, 6, 145, 115], [14, 23, 74, 46], [44, 7, 54, 24], [59, 1, 46, 16]],
+ 35 => [[12, 7, 151, 121], [12, 26, 75, 47], [39, 14, 54, 24], [22, 41, 45, 15]],
+ 36 => [[ 6, 14, 151, 121], [ 6, 34, 75, 47], [46, 10, 54, 24], [ 2, 64, 45, 15]],
+ 37 => [[17, 4, 152, 122], [29, 14, 74, 46], [49, 10, 54, 24], [24, 46, 45, 15]],
+ 38 => [[ 4, 18, 152, 122], [13, 32, 74, 46], [48, 14, 54, 24], [42, 32, 45, 15]],
+ 39 => [[20, 4, 147, 117], [40, 7, 75, 47], [43, 22, 54, 24], [10, 67, 45, 15]],
+ 40 => [[19, 6, 148, 118], [18, 31, 75, 47], [34, 34, 54, 24], [20, 61, 45, 15]],
+ ];
+
+ /**
+ * Sets the data string (internally called by the constructor)
+ *
+ * @param string $data
+ *
+ * @return \chillerlan\QRCode\Data\QRDataInterface
+ */
+ public function setData(string $data):QRDataInterface;
+
+ /**
+ * returns a fresh matrix object with the data written for the given $maskPattern
+ *
+ * @param int $maskPattern
+ * @param bool|null $test
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function initMatrix(int $maskPattern, bool $test = null):QRMatrix;
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php b/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php
new file mode 100644
index 000000000..a6d8b09e2
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php
@@ -0,0 +1,733 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Data;
+
+use chillerlan\QRCode\QRCode;
+use Closure;
+
+use function array_fill, array_key_exists, array_push, array_unshift, count, floor, in_array, max, min, range;
+
+/**
+ * @link http://www.thonky.com/qr-code-tutorial/format-version-information
+ */
+class QRMatrix{
+
+ public const M_NULL = 0x00;
+ public const M_DARKMODULE = 0x02;
+ public const M_DATA = 0x04;
+ public const M_FINDER = 0x06;
+ public const M_SEPARATOR = 0x08;
+ public const M_ALIGNMENT = 0x0a;
+ public const M_TIMING = 0x0c;
+ public const M_FORMAT = 0x0e;
+ public const M_VERSION = 0x10;
+ public const M_QUIETZONE = 0x12;
+ public const M_LOGO = 0x14;
+ public const M_FINDER_DOT = 0x16;
+
+ public const M_TEST = 0xff;
+
+ /**
+ * @link http://www.thonky.com/qr-code-tutorial/alignment-pattern-locations
+ *
+ * version -> pattern
+ */
+ protected const alignmentPattern = [
+ 1 => [],
+ 2 => [6, 18],
+ 3 => [6, 22],
+ 4 => [6, 26],
+ 5 => [6, 30],
+ 6 => [6, 34],
+ 7 => [6, 22, 38],
+ 8 => [6, 24, 42],
+ 9 => [6, 26, 46],
+ 10 => [6, 28, 50],
+ 11 => [6, 30, 54],
+ 12 => [6, 32, 58],
+ 13 => [6, 34, 62],
+ 14 => [6, 26, 46, 66],
+ 15 => [6, 26, 48, 70],
+ 16 => [6, 26, 50, 74],
+ 17 => [6, 30, 54, 78],
+ 18 => [6, 30, 56, 82],
+ 19 => [6, 30, 58, 86],
+ 20 => [6, 34, 62, 90],
+ 21 => [6, 28, 50, 72, 94],
+ 22 => [6, 26, 50, 74, 98],
+ 23 => [6, 30, 54, 78, 102],
+ 24 => [6, 28, 54, 80, 106],
+ 25 => [6, 32, 58, 84, 110],
+ 26 => [6, 30, 58, 86, 114],
+ 27 => [6, 34, 62, 90, 118],
+ 28 => [6, 26, 50, 74, 98, 122],
+ 29 => [6, 30, 54, 78, 102, 126],
+ 30 => [6, 26, 52, 78, 104, 130],
+ 31 => [6, 30, 56, 82, 108, 134],
+ 32 => [6, 34, 60, 86, 112, 138],
+ 33 => [6, 30, 58, 86, 114, 142],
+ 34 => [6, 34, 62, 90, 118, 146],
+ 35 => [6, 30, 54, 78, 102, 126, 150],
+ 36 => [6, 24, 50, 76, 102, 128, 154],
+ 37 => [6, 28, 54, 80, 106, 132, 158],
+ 38 => [6, 32, 58, 84, 110, 136, 162],
+ 39 => [6, 26, 54, 82, 110, 138, 166],
+ 40 => [6, 30, 58, 86, 114, 142, 170],
+ ];
+
+ /**
+ * @link http://www.thonky.com/qr-code-tutorial/format-version-tables
+ *
+ * no version pattern for QR Codes < 7
+ */
+ protected const versionPattern = [
+ 7 => 0b000111110010010100,
+ 8 => 0b001000010110111100,
+ 9 => 0b001001101010011001,
+ 10 => 0b001010010011010011,
+ 11 => 0b001011101111110110,
+ 12 => 0b001100011101100010,
+ 13 => 0b001101100001000111,
+ 14 => 0b001110011000001101,
+ 15 => 0b001111100100101000,
+ 16 => 0b010000101101111000,
+ 17 => 0b010001010001011101,
+ 18 => 0b010010101000010111,
+ 19 => 0b010011010100110010,
+ 20 => 0b010100100110100110,
+ 21 => 0b010101011010000011,
+ 22 => 0b010110100011001001,
+ 23 => 0b010111011111101100,
+ 24 => 0b011000111011000100,
+ 25 => 0b011001000111100001,
+ 26 => 0b011010111110101011,
+ 27 => 0b011011000010001110,
+ 28 => 0b011100110000011010,
+ 29 => 0b011101001100111111,
+ 30 => 0b011110110101110101,
+ 31 => 0b011111001001010000,
+ 32 => 0b100000100111010101,
+ 33 => 0b100001011011110000,
+ 34 => 0b100010100010111010,
+ 35 => 0b100011011110011111,
+ 36 => 0b100100101100001011,
+ 37 => 0b100101010000101110,
+ 38 => 0b100110101001100100,
+ 39 => 0b100111010101000001,
+ 40 => 0b101000110001101001,
+ ];
+
+ // ECC level -> mask pattern
+ protected const formatPattern = [
+ [ // L
+ 0b111011111000100,
+ 0b111001011110011,
+ 0b111110110101010,
+ 0b111100010011101,
+ 0b110011000101111,
+ 0b110001100011000,
+ 0b110110001000001,
+ 0b110100101110110,
+ ],
+ [ // M
+ 0b101010000010010,
+ 0b101000100100101,
+ 0b101111001111100,
+ 0b101101101001011,
+ 0b100010111111001,
+ 0b100000011001110,
+ 0b100111110010111,
+ 0b100101010100000,
+ ],
+ [ // Q
+ 0b011010101011111,
+ 0b011000001101000,
+ 0b011111100110001,
+ 0b011101000000110,
+ 0b010010010110100,
+ 0b010000110000011,
+ 0b010111011011010,
+ 0b010101111101101,
+ ],
+ [ // H
+ 0b001011010001001,
+ 0b001001110111110,
+ 0b001110011100111,
+ 0b001100111010000,
+ 0b000011101100010,
+ 0b000001001010101,
+ 0b000110100001100,
+ 0b000100000111011,
+ ],
+ ];
+
+ /**
+ * @var int
+ */
+ protected $version;
+
+ /**
+ * @var int
+ */
+ protected $eclevel;
+
+ /**
+ * @var int
+ */
+ protected $maskPattern = QRCode::MASK_PATTERN_AUTO;
+
+ /**
+ * @var int
+ */
+ protected $moduleCount;
+
+ /**
+ * @var mixed[]
+ */
+ protected $matrix;
+
+ /**
+ * QRMatrix constructor.
+ *
+ * @param int $version
+ * @param int $eclevel
+ *
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ */
+ public function __construct(int $version, int $eclevel){
+
+ if(!in_array($version, range(1, 40), true)){
+ throw new QRCodeDataException('invalid QR Code version');
+ }
+
+ if(!array_key_exists($eclevel, QRCode::ECC_MODES)){
+ throw new QRCodeDataException('invalid ecc level');
+ }
+
+ $this->version = $version;
+ $this->eclevel = $eclevel;
+ $this->moduleCount = $this->version * 4 + 17;
+ $this->matrix = array_fill(0, $this->moduleCount, array_fill(0, $this->moduleCount, $this::M_NULL));
+ }
+
+ /**
+ * Returns the data matrix, returns a pure boolean representation if $boolean is set to true
+ *
+ * @return int[][]|bool[][]
+ */
+ public function matrix(bool $boolean = false):array{
+
+ if(!$boolean){
+ return $this->matrix;
+ }
+
+ $matrix = [];
+
+ foreach($this->matrix as $y => $row){
+ $matrix[$y] = [];
+
+ foreach($row as $x => $val){
+ $matrix[$y][$x] = ($val >> 8) > 0;
+ }
+ }
+
+ return $matrix;
+ }
+
+ /**
+ * @return int
+ */
+ public function version():int{
+ return $this->version;
+ }
+
+ /**
+ * @return int
+ */
+ public function eccLevel():int{
+ return $this->eclevel;
+ }
+
+ /**
+ * @return int
+ */
+ public function maskPattern():int{
+ return $this->maskPattern;
+ }
+
+ /**
+ * Returns the absoulute size of the matrix, including quiet zone (after setting it).
+ *
+ * size = version * 4 + 17 [ + 2 * quietzone size]
+ *
+ * @return int
+ */
+ public function size():int{
+ return $this->moduleCount;
+ }
+
+ /**
+ * Returns the value of the module at position [$x, $y]
+ *
+ * @param int $x
+ * @param int $y
+ *
+ * @return int
+ */
+ public function get(int $x, int $y):int{
+ return $this->matrix[$y][$x];
+ }
+
+ /**
+ * Sets the $M_TYPE value for the module at position [$x, $y]
+ *
+ * true => $M_TYPE << 8
+ * false => $M_TYPE
+ *
+ * @param int $x
+ * @param int $y
+ * @param int $M_TYPE
+ * @param bool $value
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function set(int $x, int $y, bool $value, int $M_TYPE):QRMatrix{
+ $this->matrix[$y][$x] = $M_TYPE << ($value ? 8 : 0);
+
+ return $this;
+ }
+
+ /**
+ * Checks whether a module is true (dark) or false (light)
+ *
+ * true => $value >> 8 === $M_TYPE
+ * $value >> 8 > 0
+ *
+ * false => $value === $M_TYPE
+ * $value >> 8 === 0
+ *
+ * @param int $x
+ * @param int $y
+ *
+ * @return bool
+ */
+ public function check(int $x, int $y):bool{
+ return $this->matrix[$y][$x] >> 8 > 0;
+ }
+
+
+ /**
+ * Sets the "dark module", that is always on the same position 1x1px away from the bottom left finder
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function setDarkModule():QRMatrix{
+ $this->set(8, 4 * $this->version + 9, true, $this::M_DARKMODULE);
+
+ return $this;
+ }
+
+ /**
+ * Draws the 7x7 finder patterns in the corners top left/right and bottom left
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function setFinderPattern():QRMatrix{
+
+ $pos = [
+ [0, 0], // top left
+ [$this->moduleCount - 7, 0], // bottom left
+ [0, $this->moduleCount - 7], // top right
+ ];
+
+ foreach($pos as $c){
+ for($y = 0; $y < 7; $y++){
+ for($x = 0; $x < 7; $x++){
+ // outer (dark) 7*7 square
+ if($x === 0 || $x === 6 || $y === 0 || $y === 6){
+ $this->set($c[0] + $y, $c[1] + $x, true, $this::M_FINDER);
+ }
+ // inner (light) 5*5 square
+ elseif($x === 1 || $x === 5 || $y === 1 || $y === 5){
+ $this->set($c[0] + $y, $c[1] + $x, false, $this::M_FINDER);
+ }
+ // 3*3 dot
+ else{
+ $this->set($c[0] + $y, $c[1] + $x, true, $this::M_FINDER_DOT);
+ }
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Draws the separator lines around the finder patterns
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function setSeparators():QRMatrix{
+
+ $h = [
+ [7, 0],
+ [$this->moduleCount - 8, 0],
+ [7, $this->moduleCount - 8],
+ ];
+
+ $v = [
+ [7, 7],
+ [$this->moduleCount - 1, 7],
+ [7, $this->moduleCount - 8],
+ ];
+
+ for($c = 0; $c < 3; $c++){
+ for($i = 0; $i < 8; $i++){
+ $this->set($h[$c][0] , $h[$c][1] + $i, false, $this::M_SEPARATOR);
+ $this->set($v[$c][0] - $i, $v[$c][1] , false, $this::M_SEPARATOR);
+ }
+ }
+
+ return $this;
+ }
+
+
+ /**
+ * Draws the 5x5 alignment patterns
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function setAlignmentPattern():QRMatrix{
+
+ foreach($this::alignmentPattern[$this->version] as $y){
+ foreach($this::alignmentPattern[$this->version] as $x){
+
+ // skip existing patterns
+ if($this->matrix[$y][$x] !== $this::M_NULL){
+ continue;
+ }
+
+ for($ry = -2; $ry <= 2; $ry++){
+ for($rx = -2; $rx <= 2; $rx++){
+ $v = ($ry === 0 && $rx === 0) || $ry === 2 || $ry === -2 || $rx === 2 || $rx === -2;
+
+ $this->set($x + $rx, $y + $ry, $v, $this::M_ALIGNMENT);
+ }
+ }
+
+ }
+ }
+
+ return $this;
+ }
+
+
+ /**
+ * Draws the timing pattern (h/v checkered line between the finder patterns)
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function setTimingPattern():QRMatrix{
+
+ foreach(range(8, $this->moduleCount - 8 - 1) as $i){
+
+ if($this->matrix[6][$i] !== $this::M_NULL || $this->matrix[$i][6] !== $this::M_NULL){
+ continue;
+ }
+
+ $v = $i % 2 === 0;
+
+ $this->set($i, 6, $v, $this::M_TIMING); // h
+ $this->set(6, $i, $v, $this::M_TIMING); // v
+ }
+
+ return $this;
+ }
+
+ /**
+ * Draws the version information, 2x 3x6 pixel
+ *
+ * @param bool|null $test
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function setVersionNumber(bool $test = null):QRMatrix{
+ $bits = $this::versionPattern[$this->version] ?? false;
+
+ if($bits !== false){
+
+ for($i = 0; $i < 18; $i++){
+ $a = (int)floor($i / 3);
+ $b = $i % 3 + $this->moduleCount - 8 - 3;
+ $v = !$test && (($bits >> $i) & 1) === 1;
+
+ $this->set($b, $a, $v, $this::M_VERSION); // ne
+ $this->set($a, $b, $v, $this::M_VERSION); // sw
+ }
+
+ }
+
+ return $this;
+ }
+
+ /**
+ * Draws the format info along the finder patterns
+ *
+ * @param int $maskPattern
+ * @param bool|null $test
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function setFormatInfo(int $maskPattern, bool $test = null):QRMatrix{
+ $bits = $this::formatPattern[QRCode::ECC_MODES[$this->eclevel]][$maskPattern] ?? 0;
+
+ for($i = 0; $i < 15; $i++){
+ $v = !$test && (($bits >> $i) & 1) === 1;
+
+ if($i < 6){
+ $this->set(8, $i, $v, $this::M_FORMAT);
+ }
+ elseif($i < 8){
+ $this->set(8, $i + 1, $v, $this::M_FORMAT);
+ }
+ else{
+ $this->set(8, $this->moduleCount - 15 + $i, $v, $this::M_FORMAT);
+ }
+
+ if($i < 8){
+ $this->set($this->moduleCount - $i - 1, 8, $v, $this::M_FORMAT);
+ }
+ elseif($i < 9){
+ $this->set(15 - $i, 8, $v, $this::M_FORMAT);
+ }
+ else{
+ $this->set(15 - $i - 1, 8, $v, $this::M_FORMAT);
+ }
+
+ }
+
+ $this->set(8, $this->moduleCount - 8, !$test, $this::M_FORMAT);
+
+ return $this;
+ }
+
+ /**
+ * Draws the "quiet zone" of $size around the matrix
+ *
+ * @param int|null $size
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ */
+ public function setQuietZone(int $size = null):QRMatrix{
+
+ if($this->matrix[$this->moduleCount - 1][$this->moduleCount - 1] === $this::M_NULL){
+ throw new QRCodeDataException('use only after writing data');
+ }
+
+ $size = $size !== null
+ ? max(0, min($size, floor($this->moduleCount / 2)))
+ : 4;
+
+ for($y = 0; $y < $this->moduleCount; $y++){
+ for($i = 0; $i < $size; $i++){
+ array_unshift($this->matrix[$y], $this::M_QUIETZONE);
+ array_push($this->matrix[$y], $this::M_QUIETZONE);
+ }
+ }
+
+ $this->moduleCount += ($size * 2);
+
+ $r = array_fill(0, $this->moduleCount, $this::M_QUIETZONE);
+
+ for($i = 0; $i < $size; $i++){
+ array_unshift($this->matrix, $r);
+ array_push($this->matrix, $r);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Clears a space of $width * $height in order to add a logo or text.
+ *
+ * Additionally, the logo space can be positioned within the QR Code - respecting the main functional patterns -
+ * using $startX and $startY. If either of these are null, the logo space will be centered in that direction.
+ * ECC level "H" (30%) is required.
+ *
+ * Please note that adding a logo space minimizes the error correction capacity of the QR Code and
+ * created images may become unreadable, especially when printed with a chance to receive damage.
+ * Please test thoroughly before using this feature in production.
+ *
+ * This method should be called from within an output module (after the matrix has been filled with data).
+ * Note that there is no restiction on how many times this method could be called on the same matrix instance.
+ *
+ * @link https://github.com/chillerlan/php-qrcode/issues/52
+ *
+ * @param int $width
+ * @param int $height
+ * @param int|null $startX
+ * @param int|null $startY
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ */
+ public function setLogoSpace(int $width, int $height, int $startX = null, int $startY = null):QRMatrix{
+
+ // for logos we operate in ECC H (30%) only
+ if($this->eclevel !== 0b10){
+ throw new QRCodeDataException('ECC level "H" required to add logo space');
+ }
+
+ // we need uneven sizes, adjust if needed
+ if(($width % 2) === 0){
+ $width++;
+ }
+
+ if(($height % 2) === 0){
+ $height++;
+ }
+
+ // $this->moduleCount includes the quiet zone (if created), we need the QR size here
+ $length = $this->version * 4 + 17;
+
+ // throw if the logo space exceeds the maximum error correction capacity
+ if($width * $height > floor($length * $length * 0.2)){
+ throw new QRCodeDataException('logo space exceeds the maximum error correction capacity');
+ }
+
+ // quiet zone size
+ $qz = ($this->moduleCount - $length) / 2;
+ // skip quiet zone and the first 9 rows/columns (finder-, mode-, version- and timing patterns)
+ $start = $qz + 9;
+ // skip quiet zone
+ $end = $this->moduleCount - $qz;
+
+ // determine start coordinates
+ $startX = ($startX !== null ? $startX : ($length - $width) / 2) + $qz;
+ $startY = ($startY !== null ? $startY : ($length - $height) / 2) + $qz;
+
+ // clear the space
+ foreach($this->matrix as $y => $row){
+ foreach($row as $x => $val){
+ // out of bounds, skip
+ if($x < $start || $y < $start ||$x >= $end || $y >= $end){
+ continue;
+ }
+ // a match
+ if($x >= $startX && $x < ($startX + $width) && $y >= $startY && $y < ($startY + $height)){
+ $this->set($x, $y, false, $this::M_LOGO);
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Maps the binary $data array from QRDataInterface::maskECC() on the matrix, using $maskPattern
+ *
+ * @see \chillerlan\QRCode\Data\QRDataAbstract::maskECC()
+ *
+ * @param int[] $data
+ * @param int $maskPattern
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ */
+ public function mapData(array $data, int $maskPattern):QRMatrix{
+ $this->maskPattern = $maskPattern;
+ $byteCount = count($data);
+ $size = $this->moduleCount - 1;
+ $mask = $this->getMask($this->maskPattern);
+
+ for($i = $size, $y = $size, $inc = -1, $byteIndex = 0, $bitIndex = 7; $i > 0; $i -= 2){
+
+ if($i === 6){
+ $i--;
+ }
+
+ while(true){
+ for($c = 0; $c < 2; $c++){
+ $x = $i - $c;
+
+ if($this->matrix[$y][$x] === $this::M_NULL){
+ $v = false;
+
+ if($byteIndex < $byteCount){
+ $v = (($data[$byteIndex] >> $bitIndex) & 1) === 1;
+ }
+
+ if($mask($x, $y) === 0){
+ $v = !$v;
+ }
+
+ $this->matrix[$y][$x] = $this::M_DATA << ($v ? 8 : 0);
+ $bitIndex--;
+
+ if($bitIndex === -1){
+ $byteIndex++;
+ $bitIndex = 7;
+ }
+
+ }
+ }
+
+ $y += $inc;
+
+ if($y < 0 || $this->moduleCount <= $y){
+ $y -= $inc;
+ $inc = -$inc;
+
+ break;
+ }
+
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * ISO/IEC 18004:2000 Section 8.8.1
+ *
+ * Note that some versions of the QR code standard have had errors in the section about mask patterns.
+ * The information below has been corrected. (https://www.thonky.com/qr-code-tutorial/mask-patterns)
+ *
+ * @see \chillerlan\QRCode\QRMatrix::mapData()
+ *
+ * @internal
+ *
+ * @param int $maskPattern
+ *
+ * @return \Closure
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ */
+ protected function getMask(int $maskPattern):Closure{
+
+ if((0b111 & $maskPattern) !== $maskPattern){
+ throw new QRCodeDataException('invalid mask pattern'); // @codeCoverageIgnore
+ }
+
+ return [
+ 0b000 => function($x, $y):int{ return ($x + $y) % 2; },
+ 0b001 => function($x, $y):int{ return $y % 2; },
+ 0b010 => function($x, $y):int{ return $x % 3; },
+ 0b011 => function($x, $y):int{ return ($x + $y) % 3; },
+ 0b100 => function($x, $y):int{ return ((int)($y / 2) + (int)($x / 3)) % 2; },
+ 0b101 => function($x, $y):int{ return (($x * $y) % 2) + (($x * $y) % 3); },
+ 0b110 => function($x, $y):int{ return ((($x * $y) % 2) + (($x * $y) % 3)) % 2; },
+ 0b111 => function($x, $y):int{ return ((($x * $y) % 3) + (($x + $y) % 2)) % 2; },
+ ][$maskPattern];
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Helpers/BitBuffer.php b/vendor/chillerlan/php-qrcode/src/Helpers/BitBuffer.php
new file mode 100644
index 000000000..0b4ff6a77
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Helpers/BitBuffer.php
@@ -0,0 +1,75 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Helpers;
+
+use function count, floor;
+
+class BitBuffer{
+
+ /**
+ * @var int[]
+ */
+ public $buffer = [];
+
+ /**
+ * @var int
+ */
+ public $length = 0;
+
+ /**
+ * @return \chillerlan\QRCode\Helpers\BitBuffer
+ */
+ public function clear():BitBuffer{
+ $this->buffer = [];
+ $this->length = 0;
+
+ return $this;
+ }
+
+ /**
+ * @param int $num
+ * @param int $length
+ *
+ * @return \chillerlan\QRCode\Helpers\BitBuffer
+ */
+ public function put(int $num, int $length):BitBuffer{
+
+ for($i = 0; $i < $length; $i++){
+ $this->putBit((($num >> ($length - $i - 1)) & 1) === 1);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param bool $bit
+ *
+ * @return \chillerlan\QRCode\Helpers\BitBuffer
+ */
+ public function putBit(bool $bit):BitBuffer{
+ $bufIndex = floor($this->length / 8);
+
+ if(count($this->buffer) <= $bufIndex){
+ $this->buffer[] = 0;
+ }
+
+ if($bit === true){
+ $this->buffer[(int)$bufIndex] |= (0x80 >> ($this->length % 8));
+ }
+
+ $this->length++;
+
+ return $this;
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Helpers/Polynomial.php b/vendor/chillerlan/php-qrcode/src/Helpers/Polynomial.php
new file mode 100644
index 000000000..abe11d0cc
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Helpers/Polynomial.php
@@ -0,0 +1,184 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Helpers;
+
+use chillerlan\QRCode\QRCodeException;
+
+use function array_fill, count, sprintf;
+
+/**
+ * @link http://www.thonky.com/qr-code-tutorial/error-correction-coding
+ */
+class Polynomial{
+
+ /**
+ * @link http://www.thonky.com/qr-code-tutorial/log-antilog-table
+ */
+ protected const table = [
+ [ 1, 0], [ 2, 0], [ 4, 1], [ 8, 25], [ 16, 2], [ 32, 50], [ 64, 26], [128, 198],
+ [ 29, 3], [ 58, 223], [116, 51], [232, 238], [205, 27], [135, 104], [ 19, 199], [ 38, 75],
+ [ 76, 4], [152, 100], [ 45, 224], [ 90, 14], [180, 52], [117, 141], [234, 239], [201, 129],
+ [143, 28], [ 3, 193], [ 6, 105], [ 12, 248], [ 24, 200], [ 48, 8], [ 96, 76], [192, 113],
+ [157, 5], [ 39, 138], [ 78, 101], [156, 47], [ 37, 225], [ 74, 36], [148, 15], [ 53, 33],
+ [106, 53], [212, 147], [181, 142], [119, 218], [238, 240], [193, 18], [159, 130], [ 35, 69],
+ [ 70, 29], [140, 181], [ 5, 194], [ 10, 125], [ 20, 106], [ 40, 39], [ 80, 249], [160, 185],
+ [ 93, 201], [186, 154], [105, 9], [210, 120], [185, 77], [111, 228], [222, 114], [161, 166],
+ [ 95, 6], [190, 191], [ 97, 139], [194, 98], [153, 102], [ 47, 221], [ 94, 48], [188, 253],
+ [101, 226], [202, 152], [137, 37], [ 15, 179], [ 30, 16], [ 60, 145], [120, 34], [240, 136],
+ [253, 54], [231, 208], [211, 148], [187, 206], [107, 143], [214, 150], [177, 219], [127, 189],
+ [254, 241], [225, 210], [223, 19], [163, 92], [ 91, 131], [182, 56], [113, 70], [226, 64],
+ [217, 30], [175, 66], [ 67, 182], [134, 163], [ 17, 195], [ 34, 72], [ 68, 126], [136, 110],
+ [ 13, 107], [ 26, 58], [ 52, 40], [104, 84], [208, 250], [189, 133], [103, 186], [206, 61],
+ [129, 202], [ 31, 94], [ 62, 155], [124, 159], [248, 10], [237, 21], [199, 121], [147, 43],
+ [ 59, 78], [118, 212], [236, 229], [197, 172], [151, 115], [ 51, 243], [102, 167], [204, 87],
+ [133, 7], [ 23, 112], [ 46, 192], [ 92, 247], [184, 140], [109, 128], [218, 99], [169, 13],
+ [ 79, 103], [158, 74], [ 33, 222], [ 66, 237], [132, 49], [ 21, 197], [ 42, 254], [ 84, 24],
+ [168, 227], [ 77, 165], [154, 153], [ 41, 119], [ 82, 38], [164, 184], [ 85, 180], [170, 124],
+ [ 73, 17], [146, 68], [ 57, 146], [114, 217], [228, 35], [213, 32], [183, 137], [115, 46],
+ [230, 55], [209, 63], [191, 209], [ 99, 91], [198, 149], [145, 188], [ 63, 207], [126, 205],
+ [252, 144], [229, 135], [215, 151], [179, 178], [123, 220], [246, 252], [241, 190], [255, 97],
+ [227, 242], [219, 86], [171, 211], [ 75, 171], [150, 20], [ 49, 42], [ 98, 93], [196, 158],
+ [149, 132], [ 55, 60], [110, 57], [220, 83], [165, 71], [ 87, 109], [174, 65], [ 65, 162],
+ [130, 31], [ 25, 45], [ 50, 67], [100, 216], [200, 183], [141, 123], [ 7, 164], [ 14, 118],
+ [ 28, 196], [ 56, 23], [112, 73], [224, 236], [221, 127], [167, 12], [ 83, 111], [166, 246],
+ [ 81, 108], [162, 161], [ 89, 59], [178, 82], [121, 41], [242, 157], [249, 85], [239, 170],
+ [195, 251], [155, 96], [ 43, 134], [ 86, 177], [172, 187], [ 69, 204], [138, 62], [ 9, 90],
+ [ 18, 203], [ 36, 89], [ 72, 95], [144, 176], [ 61, 156], [122, 169], [244, 160], [245, 81],
+ [247, 11], [243, 245], [251, 22], [235, 235], [203, 122], [139, 117], [ 11, 44], [ 22, 215],
+ [ 44, 79], [ 88, 174], [176, 213], [125, 233], [250, 230], [233, 231], [207, 173], [131, 232],
+ [ 27, 116], [ 54, 214], [108, 244], [216, 234], [173, 168], [ 71, 80], [142, 88], [ 1, 175],
+ ];
+
+ /**
+ * @var array
+ */
+ protected $num = [];
+
+ /**
+ * Polynomial constructor.
+ *
+ * @param array|null $num
+ * @param int|null $shift
+ */
+ public function __construct(array $num = null, int $shift = null){
+ $this->setNum($num ?? [1], $shift);
+ }
+
+ /**
+ * @return array
+ */
+ public function getNum():array{
+ return $this->num;
+ }
+
+ /**
+ * @param array $num
+ * @param int|null $shift
+ *
+ * @return \chillerlan\QRCode\Helpers\Polynomial
+ */
+ public function setNum(array $num, int $shift = null):Polynomial{
+ $offset = 0;
+ $numCount = count($num);
+
+ while($offset < $numCount && $num[$offset] === 0){
+ $offset++;
+ }
+
+ $this->num = array_fill(0, $numCount - $offset + ($shift ?? 0), 0);
+
+ for($i = 0; $i < $numCount - $offset; $i++){
+ $this->num[$i] = $num[$i + $offset];
+ }
+
+ return $this;
+ }
+
+ /**
+ * @param array $e
+ *
+ * @return \chillerlan\QRCode\Helpers\Polynomial
+ */
+ public function multiply(array $e):Polynomial{
+ $n = array_fill(0, count($this->num) + count($e) - 1, 0);
+
+ foreach($this->num as $i => $vi){
+ $vi = $this->glog($vi);
+
+ foreach($e as $j => $vj){
+ $n[$i + $j] ^= $this->gexp($vi + $this->glog($vj));
+ }
+
+ }
+
+ $this->setNum($n);
+
+ return $this;
+ }
+
+ /**
+ * @param array $e
+ *
+ * @return \chillerlan\QRCode\Helpers\Polynomial
+ */
+ public function mod(array $e):Polynomial{
+ $n = $this->num;
+
+ if(count($n) - count($e) < 0){
+ return $this;
+ }
+
+ $ratio = $this->glog($n[0]) - $this->glog($e[0]);
+
+ foreach($e as $i => $v){
+ $n[$i] ^= $this->gexp($this->glog($v) + $ratio);
+ }
+
+ $this->setNum($n)->mod($e);
+
+ return $this;
+ }
+
+ /**
+ * @param int $n
+ *
+ * @return int
+ * @throws \chillerlan\QRCode\QRCodeException
+ */
+ public function glog(int $n):int{
+
+ if($n < 1){
+ throw new QRCodeException(sprintf('log(%s)', $n));
+ }
+
+ return Polynomial::table[$n][1];
+ }
+
+ /**
+ * @param int $n
+ *
+ * @return int
+ */
+ public function gexp(int $n):int{
+
+ if($n < 0){
+ $n += 255;
+ }
+ elseif($n >= 256){
+ $n -= 255;
+ }
+
+ return Polynomial::table[$n][0];
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRCodeOutputException.php b/vendor/chillerlan/php-qrcode/src/Output/QRCodeOutputException.php
new file mode 100644
index 000000000..639bdd111
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Output/QRCodeOutputException.php
@@ -0,0 +1,17 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Output;
+
+use chillerlan\QRCode\QRCodeException;
+
+class QRCodeOutputException extends QRCodeException{}
diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRFpdf.php b/vendor/chillerlan/php-qrcode/src/Output/QRFpdf.php
new file mode 100644
index 000000000..a706685af
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Output/QRFpdf.php
@@ -0,0 +1,112 @@
+ $defaultValue){
+ $v = $this->options->moduleValues[$M_TYPE] ?? null;
+
+ if(!is_array($v) || count($v) < 3){
+ $this->moduleValues[$M_TYPE] = $defaultValue
+ ? [0, 0, 0]
+ : [255, 255, 255];
+ }
+ else{
+ $this->moduleValues[$M_TYPE] = array_values($v);
+ }
+
+ }
+
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @return string|\FPDF
+ */
+ public function dump(string $file = null){
+ $file = $file ?? $this->options->cachefile;
+
+ $fpdf = new FPDF('P', $this->options->fpdfMeasureUnit, [$this->length, $this->length]);
+ $fpdf->AddPage();
+
+ $prevColor = null;
+
+ foreach($this->matrix->matrix() as $y => $row){
+
+ foreach($row as $x => $M_TYPE){
+ /** @var int $M_TYPE */
+ $color = $this->moduleValues[$M_TYPE];
+
+ if($prevColor === null || $prevColor !== $color){
+ $fpdf->SetFillColor(...$color);
+ $prevColor = $color;
+ }
+
+ $fpdf->Rect($x * $this->scale, $y * $this->scale, 1 * $this->scale, 1 * $this->scale, 'F');
+ }
+
+ }
+
+ if($this->options->returnResource){
+ return $fpdf;
+ }
+
+ $pdfData = $fpdf->Output('S');
+
+ if($file !== null){
+ $this->saveToFile($pdfData, $file);
+ }
+
+ if($this->options->imageBase64){
+ $pdfData = sprintf('data:application/pdf;base64,%s', base64_encode($pdfData));
+ }
+
+ return $pdfData;
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRImage.php b/vendor/chillerlan/php-qrcode/src/Output/QRImage.php
new file mode 100644
index 000000000..598948c94
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Output/QRImage.php
@@ -0,0 +1,208 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ *
+ * @noinspection PhpComposerExtensionStubsInspection
+ */
+
+namespace chillerlan\QRCode\Output;
+
+use chillerlan\QRCode\Data\QRMatrix;
+use chillerlan\QRCode\{QRCode, QRCodeException};
+use chillerlan\Settings\SettingsContainerInterface;
+use Exception;
+
+use function array_values, base64_encode, call_user_func, count, imagecolorallocate, imagecolortransparent,
+ imagecreatetruecolor, imagedestroy, imagefilledrectangle, imagegif, imagejpeg, imagepng, in_array,
+ is_array, ob_end_clean, ob_get_contents, ob_start, range, sprintf;
+
+/**
+ * Converts the matrix into GD images, raw or base64 output
+ * requires ext-gd
+ * @link http://php.net/manual/book.image.php
+ */
+class QRImage extends QROutputAbstract{
+
+ protected const TRANSPARENCY_TYPES = [
+ QRCode::OUTPUT_IMAGE_PNG,
+ QRCode::OUTPUT_IMAGE_GIF,
+ ];
+
+ /**
+ * @var string
+ */
+ protected $defaultMode = QRCode::OUTPUT_IMAGE_PNG;
+
+ /**
+ * @see imagecreatetruecolor()
+ * @var resource
+ */
+ protected $image;
+
+ /**
+ * @inheritDoc
+ *
+ * @throws \chillerlan\QRCode\QRCodeException
+ */
+ public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
+
+ if(!extension_loaded('gd')){
+ throw new QRCodeException('ext-gd not loaded'); // @codeCoverageIgnore
+ }
+
+ parent::__construct($options, $matrix);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ protected function setModuleValues():void{
+
+ foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
+ $v = $this->options->moduleValues[$M_TYPE] ?? null;
+
+ if(!is_array($v) || count($v) < 3){
+ $this->moduleValues[$M_TYPE] = $defaultValue
+ ? [0, 0, 0]
+ : [255, 255, 255];
+ }
+ else{
+ $this->moduleValues[$M_TYPE] = array_values($v);
+ }
+
+ }
+
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @return string|resource
+ */
+ public function dump(string $file = null){
+ $this->image = imagecreatetruecolor($this->length, $this->length);
+
+ // avoid: Indirect modification of overloaded property $imageTransparencyBG has no effect
+ // https://stackoverflow.com/a/10455217
+ $tbg = $this->options->imageTransparencyBG;
+ $background = imagecolorallocate($this->image, ...$tbg);
+
+ if((bool)$this->options->imageTransparent && in_array($this->options->outputType, $this::TRANSPARENCY_TYPES, true)){
+ imagecolortransparent($this->image, $background);
+ }
+
+ imagefilledrectangle($this->image, 0, 0, $this->length, $this->length, $background);
+
+ foreach($this->matrix->matrix() as $y => $row){
+ foreach($row as $x => $M_TYPE){
+ $this->setPixel($x, $y, $this->moduleValues[$M_TYPE]);
+ }
+ }
+
+ if($this->options->returnResource){
+ return $this->image;
+ }
+
+ $imageData = $this->dumpImage($file);
+
+ if($this->options->imageBase64){
+ $imageData = sprintf('data:image/%s;base64,%s', $this->options->outputType, base64_encode($imageData));
+ }
+
+ return $imageData;
+ }
+
+ /**
+ * @param int $x
+ * @param int $y
+ * @param array $rgb
+ *
+ * @return void
+ */
+ protected function setPixel(int $x, int $y, array $rgb):void{
+ imagefilledrectangle(
+ $this->image,
+ $x * $this->scale,
+ $y * $this->scale,
+ ($x + 1) * $this->scale,
+ ($y + 1) * $this->scale,
+ imagecolorallocate($this->image, ...$rgb)
+ );
+ }
+
+ /**
+ * @param string|null $file
+ *
+ * @return string
+
+ * @throws \chillerlan\QRCode\Output\QRCodeOutputException
+ */
+ protected function dumpImage(string $file = null):string{
+ $file = $file ?? $this->options->cachefile;
+
+ ob_start();
+
+ try{
+ call_user_func([$this, $this->outputMode ?? $this->defaultMode]);
+ }
+ // not going to cover edge cases
+ // @codeCoverageIgnoreStart
+ catch(Exception $e){
+ throw new QRCodeOutputException($e->getMessage());
+ }
+ // @codeCoverageIgnoreEnd
+
+ $imageData = ob_get_contents();
+ imagedestroy($this->image);
+
+ ob_end_clean();
+
+ if($file !== null){
+ $this->saveToFile($imageData, $file);
+ }
+
+ return $imageData;
+ }
+
+ /**
+ * @return void
+ */
+ protected function png():void{
+ imagepng(
+ $this->image,
+ null,
+ in_array($this->options->pngCompression, range(-1, 9), true)
+ ? $this->options->pngCompression
+ : -1
+ );
+ }
+
+ /**
+ * Jiff - like... JitHub!
+ * @return void
+ */
+ protected function gif():void{
+ imagegif($this->image);
+ }
+
+ /**
+ * @return void
+ */
+ protected function jpg():void{
+ imagejpeg(
+ $this->image,
+ null,
+ in_array($this->options->jpegQuality, range(0, 100), true)
+ ? $this->options->jpegQuality
+ : 85
+ );
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRImagick.php b/vendor/chillerlan/php-qrcode/src/Output/QRImagick.php
new file mode 100644
index 000000000..03886cf3b
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Output/QRImagick.php
@@ -0,0 +1,123 @@
+
+ * @copyright 2018 smiley
+ * @license MIT
+ *
+ * @noinspection PhpComposerExtensionStubsInspection
+ */
+
+namespace chillerlan\QRCode\Output;
+
+use chillerlan\QRCode\Data\QRMatrix;
+use chillerlan\QRCode\QRCodeException;
+use chillerlan\Settings\SettingsContainerInterface;
+use Imagick, ImagickDraw, ImagickPixel;
+
+use function is_string;
+
+/**
+ * ImageMagick output module
+ * requires ext-imagick
+ * @link http://php.net/manual/book.imagick.php
+ * @link http://phpimagick.com
+ */
+class QRImagick extends QROutputAbstract{
+
+ /**
+ * @var \Imagick
+ */
+ protected $imagick;
+
+ /**
+ * @inheritDoc
+ * @throws \chillerlan\QRCode\QRCodeException
+ */
+ public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
+
+ if(!extension_loaded('imagick')){
+ throw new QRCodeException('ext-imagick not loaded'); // @codeCoverageIgnore
+ }
+
+ parent::__construct($options, $matrix);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ protected function setModuleValues():void{
+
+ foreach($this::DEFAULT_MODULE_VALUES as $type => $defaultValue){
+ $v = $this->options->moduleValues[$type] ?? null;
+
+ if(!is_string($v)){
+ $this->moduleValues[$type] = $defaultValue
+ ? new ImagickPixel($this->options->markupDark)
+ : new ImagickPixel($this->options->markupLight);
+ }
+ else{
+ $this->moduleValues[$type] = new ImagickPixel($v);
+ }
+ }
+ }
+
+ /**
+ * @inheritDoc
+ *
+ * @return string|\Imagick
+ */
+ public function dump(string $file = null){
+ $file = $file ?? $this->options->cachefile;
+ $this->imagick = new Imagick;
+
+ $this->imagick->newImage(
+ $this->length,
+ $this->length,
+ new ImagickPixel($this->options->imagickBG ?? 'transparent'),
+ $this->options->imagickFormat
+ );
+
+ $this->drawImage();
+
+ if($this->options->returnResource){
+ return $this->imagick;
+ }
+
+ $imageData = $this->imagick->getImageBlob();
+
+ if($file !== null){
+ $this->saveToFile($imageData, $file);
+ }
+
+ return $imageData;
+ }
+
+ /**
+ * @return void
+ */
+ protected function drawImage():void{
+ $draw = new ImagickDraw;
+
+ foreach($this->matrix->matrix() as $y => $row){
+ foreach($row as $x => $M_TYPE){
+ $draw->setStrokeColor($this->moduleValues[$M_TYPE]);
+ $draw->setFillColor($this->moduleValues[$M_TYPE]);
+ $draw->rectangle(
+ $x * $this->scale,
+ $y * $this->scale,
+ ($x + 1) * $this->scale,
+ ($y + 1) * $this->scale
+ );
+
+ }
+ }
+
+ $this->imagick->drawImage($draw);
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRMarkup.php b/vendor/chillerlan/php-qrcode/src/Output/QRMarkup.php
new file mode 100644
index 000000000..15559dae0
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Output/QRMarkup.php
@@ -0,0 +1,151 @@
+
+ * @copyright 2016 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Output;
+
+use chillerlan\QRCode\QRCode;
+
+use function is_string, sprintf, strip_tags, trim;
+
+/**
+ * Converts the matrix into markup types: HTML, SVG, ...
+ */
+class QRMarkup extends QROutputAbstract{
+
+ /**
+ * @var string
+ */
+ protected $defaultMode = QRCode::OUTPUT_MARKUP_SVG;
+
+ /**
+ * @see \sprintf()
+ *
+ * @var string
+ */
+ protected $svgHeader = ''.$this->options->eol;
+
+ // if saving to file, append the correct headers
+ if($this->options->cachefile){
+ return ''.$this->options->eol.$svg;
+ }
+
+ if($this->options->imageBase64){
+ $svg = sprintf('data:image/svg+xml;base64,%s', base64_encode($svg));
+ }
+
+ return $svg;
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Output/QROutputAbstract.php b/vendor/chillerlan/php-qrcode/src/Output/QROutputAbstract.php
new file mode 100644
index 000000000..4ec47de24
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Output/QROutputAbstract.php
@@ -0,0 +1,130 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Output;
+
+use chillerlan\QRCode\{Data\QRMatrix, QRCode};
+use chillerlan\Settings\SettingsContainerInterface;
+
+use function call_user_func, dirname, file_put_contents, get_called_class, in_array, is_writable, sprintf;
+
+/**
+ * common output abstract
+ */
+abstract class QROutputAbstract implements QROutputInterface{
+
+ /**
+ * @var int
+ */
+ protected $moduleCount;
+
+ /**
+ * @param \chillerlan\QRCode\Data\QRMatrix $matrix
+ */
+ protected $matrix;
+
+ /**
+ * @var \chillerlan\QRCode\QROptions
+ */
+ protected $options;
+
+ /**
+ * @var string
+ */
+ protected $outputMode;
+
+ /**
+ * @var string;
+ */
+ protected $defaultMode;
+
+ /**
+ * @var int
+ */
+ protected $scale;
+
+ /**
+ * @var int
+ */
+ protected $length;
+
+ /**
+ * @var array
+ */
+ protected $moduleValues;
+
+ /**
+ * QROutputAbstract constructor.
+ *
+ * @param \chillerlan\Settings\SettingsContainerInterface $options
+ * @param \chillerlan\QRCode\Data\QRMatrix $matrix
+ */
+ public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
+ $this->options = $options;
+ $this->matrix = $matrix;
+ $this->moduleCount = $this->matrix->size();
+ $this->scale = $this->options->scale;
+ $this->length = $this->moduleCount * $this->scale;
+
+ $class = get_called_class();
+
+ if(isset(QRCode::OUTPUT_MODES[$class]) && in_array($this->options->outputType, QRCode::OUTPUT_MODES[$class])){
+ $this->outputMode = $this->options->outputType;
+ }
+
+ $this->setModuleValues();
+ }
+
+ /**
+ * Sets the initial module values (clean-up & defaults)
+ *
+ * @return void
+ */
+ abstract protected function setModuleValues():void;
+
+ /**
+ * saves the qr data to a file
+ *
+ * @see file_put_contents()
+ * @see \chillerlan\QRCode\QROptions::cachefile
+ *
+ * @param string $data
+ * @param string $file
+ *
+ * @return bool
+ * @throws \chillerlan\QRCode\Output\QRCodeOutputException
+ */
+ protected function saveToFile(string $data, string $file):bool{
+
+ if(!is_writable(dirname($file))){
+ throw new QRCodeOutputException(sprintf('Could not write data to cache file: %s', $file));
+ }
+
+ return (bool)file_put_contents($file, $data);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function dump(string $file = null){
+ // call the built-in output method
+ $data = call_user_func([$this, $this->outputMode ?? $this->defaultMode]);
+ $file = $file ?? $this->options->cachefile;
+
+ if($file !== null){
+ $this->saveToFile($data, $file);
+ }
+
+ return $data;
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Output/QROutputInterface.php b/vendor/chillerlan/php-qrcode/src/Output/QROutputInterface.php
new file mode 100644
index 000000000..d9149b0f7
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Output/QROutputInterface.php
@@ -0,0 +1,55 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Output;
+
+use chillerlan\QRCode\Data\QRMatrix;
+
+/**
+ * Converts the data matrix into readable output
+ */
+interface QROutputInterface{
+
+ const DEFAULT_MODULE_VALUES = [
+ // light
+ QRMatrix::M_DATA => false, // 4
+ QRMatrix::M_FINDER => false, // 6
+ QRMatrix::M_SEPARATOR => false, // 8
+ QRMatrix::M_ALIGNMENT => false, // 10
+ QRMatrix::M_TIMING => false, // 12
+ QRMatrix::M_FORMAT => false, // 14
+ QRMatrix::M_VERSION => false, // 16
+ QRMatrix::M_QUIETZONE => false, // 18
+ QRMatrix::M_LOGO => false, // 20
+ QRMatrix::M_TEST => false, // 255
+ // dark
+ QRMatrix::M_DARKMODULE << 8 => true, // 512
+ QRMatrix::M_DATA << 8 => true, // 1024
+ QRMatrix::M_FINDER << 8 => true, // 1536
+ QRMatrix::M_ALIGNMENT << 8 => true, // 2560
+ QRMatrix::M_TIMING << 8 => true, // 3072
+ QRMatrix::M_FORMAT << 8 => true, // 3584
+ QRMatrix::M_VERSION << 8 => true, // 4096
+ QRMatrix::M_FINDER_DOT << 8 => true, // 5632
+ QRMatrix::M_TEST << 8 => true, // 65280
+ ];
+
+ /**
+ * generates the output, optionally dumps it to a file, and returns it
+ *
+ * @param string|null $file
+ *
+ * @return mixed
+ */
+ public function dump(string $file = null);
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/Output/QRString.php b/vendor/chillerlan/php-qrcode/src/Output/QRString.php
new file mode 100644
index 000000000..ba8d83675
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/Output/QRString.php
@@ -0,0 +1,76 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode\Output;
+
+use chillerlan\QRCode\QRCode;
+
+use function implode, is_string, json_encode;
+
+/**
+ * Converts the matrix data into string types
+ */
+class QRString extends QROutputAbstract{
+
+ /**
+ * @var string
+ */
+ protected $defaultMode = QRCode::OUTPUT_STRING_TEXT;
+
+ /**
+ * @inheritDoc
+ */
+ protected function setModuleValues():void{
+
+ foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
+ $v = $this->options->moduleValues[$M_TYPE] ?? null;
+
+ if(!is_string($v)){
+ $this->moduleValues[$M_TYPE] = $defaultValue
+ ? $this->options->textDark
+ : $this->options->textLight;
+ }
+ else{
+ $this->moduleValues[$M_TYPE] = $v;
+ }
+
+ }
+
+ }
+
+ /**
+ * @return string
+ */
+ protected function text():string{
+ $str = [];
+
+ foreach($this->matrix->matrix() as $row){
+ $r = [];
+
+ foreach($row as $M_TYPE){
+ $r[] = $this->moduleValues[$M_TYPE];
+ }
+
+ $str[] = implode('', $r);
+ }
+
+ return implode($this->options->eol, $str);
+ }
+
+ /**
+ * @return string
+ */
+ protected function json():string{
+ return json_encode($this->matrix->matrix());
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/QRCode.php b/vendor/chillerlan/php-qrcode/src/QRCode.php
new file mode 100644
index 000000000..91f7aa0eb
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/QRCode.php
@@ -0,0 +1,310 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode;
+
+use chillerlan\QRCode\Data\{
+ MaskPatternTester, QRCodeDataException, QRDataInterface, QRMatrix
+};
+use chillerlan\QRCode\Output\{
+ QRCodeOutputException, QRFpdf, QRImage, QRImagick, QRMarkup, QROutputInterface, QRString
+};
+use chillerlan\Settings\SettingsContainerInterface;
+
+use function array_search, call_user_func_array, class_exists, in_array, min, ord, strlen;
+
+/**
+ * Turns a text string into a Model 2 QR Code
+ *
+ * @link https://github.com/kazuhikoarase/qrcode-generator/tree/master/php
+ * @link http://www.qrcode.com/en/codes/model12.html
+ * @link http://www.thonky.com/qr-code-tutorial/
+ */
+class QRCode{
+
+ /**
+ * API constants
+ */
+ public const OUTPUT_MARKUP_HTML = 'html';
+ public const OUTPUT_MARKUP_SVG = 'svg';
+ public const OUTPUT_IMAGE_PNG = 'png';
+ public const OUTPUT_IMAGE_JPG = 'jpg';
+ public const OUTPUT_IMAGE_GIF = 'gif';
+ public const OUTPUT_STRING_JSON = 'json';
+ public const OUTPUT_STRING_TEXT = 'text';
+ public const OUTPUT_IMAGICK = 'imagick';
+ public const OUTPUT_FPDF = 'fpdf';
+ public const OUTPUT_CUSTOM = 'custom';
+
+ public const VERSION_AUTO = -1;
+ public const MASK_PATTERN_AUTO = -1;
+
+ public const ECC_L = 0b01; // 7%.
+ public const ECC_M = 0b00; // 15%.
+ public const ECC_Q = 0b11; // 25%.
+ public const ECC_H = 0b10; // 30%.
+
+ public const DATA_NUMBER = 0b0001;
+ public const DATA_ALPHANUM = 0b0010;
+ public const DATA_BYTE = 0b0100;
+ public const DATA_KANJI = 0b1000;
+
+ public const ECC_MODES = [
+ self::ECC_L => 0,
+ self::ECC_M => 1,
+ self::ECC_Q => 2,
+ self::ECC_H => 3,
+ ];
+
+ public const DATA_MODES = [
+ self::DATA_NUMBER => 0,
+ self::DATA_ALPHANUM => 1,
+ self::DATA_BYTE => 2,
+ self::DATA_KANJI => 3,
+ ];
+
+ public const OUTPUT_MODES = [
+ QRMarkup::class => [
+ self::OUTPUT_MARKUP_SVG,
+ self::OUTPUT_MARKUP_HTML,
+ ],
+ QRImage::class => [
+ self::OUTPUT_IMAGE_PNG,
+ self::OUTPUT_IMAGE_GIF,
+ self::OUTPUT_IMAGE_JPG,
+ ],
+ QRString::class => [
+ self::OUTPUT_STRING_JSON,
+ self::OUTPUT_STRING_TEXT,
+ ],
+ QRImagick::class => [
+ self::OUTPUT_IMAGICK,
+ ],
+ QRFpdf::class => [
+ self::OUTPUT_FPDF
+ ]
+ ];
+
+ /**
+ * @var \chillerlan\QRCode\QROptions|\chillerlan\Settings\SettingsContainerInterface
+ */
+ protected $options;
+
+ /**
+ * @var \chillerlan\QRCode\Data\QRDataInterface
+ */
+ protected $dataInterface;
+
+ /**
+ * QRCode constructor.
+ *
+ * @param \chillerlan\Settings\SettingsContainerInterface|null $options
+ */
+ public function __construct(SettingsContainerInterface $options = null){
+ $this->options = $options ?? new QROptions;
+ }
+
+ /**
+ * Renders a QR Code for the given $data and QROptions
+ *
+ * @param string $data
+ * @param string|null $file
+ *
+ * @return mixed
+ */
+ public function render(string $data, string $file = null){
+ return $this->initOutputInterface($data)->dump($file);
+ }
+
+ /**
+ * Returns a QRMatrix object for the given $data and current QROptions
+ *
+ * @param string $data
+ *
+ * @return \chillerlan\QRCode\Data\QRMatrix
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ */
+ public function getMatrix(string $data):QRMatrix{
+
+ if(empty($data)){
+ throw new QRCodeDataException('QRCode::getMatrix() No data given.');
+ }
+
+ $this->dataInterface = $this->initDataInterface($data);
+
+ $maskPattern = $this->options->maskPattern === $this::MASK_PATTERN_AUTO
+ ? $this->getBestMaskPattern()
+ : $this->options->maskPattern;
+
+ $matrix = $this->dataInterface->initMatrix($maskPattern);
+
+ if((bool)$this->options->addQuietzone){
+ $matrix->setQuietZone($this->options->quietzoneSize);
+ }
+
+ return $matrix;
+ }
+
+ /**
+ * shoves a QRMatrix through the MaskPatternTester to find the lowest penalty mask pattern
+ *
+ * @see \chillerlan\QRCode\Data\MaskPatternTester
+ *
+ * @return int
+ */
+ protected function getBestMaskPattern():int{
+ $penalties = [];
+
+ for($pattern = 0; $pattern < 8; $pattern++){
+ $tester = new MaskPatternTester($this->dataInterface->initMatrix($pattern, true));
+
+ $penalties[$pattern] = $tester->testPattern();
+ }
+
+ return array_search(min($penalties), $penalties, true);
+ }
+
+ /**
+ * returns a fresh QRDataInterface for the given $data
+ *
+ * @param string $data
+ *
+ * @return \chillerlan\QRCode\Data\QRDataInterface
+ * @throws \chillerlan\QRCode\Data\QRCodeDataException
+ */
+ public function initDataInterface(string $data):QRDataInterface{
+ $dataModes = ['Number', 'AlphaNum', 'Kanji', 'Byte'];
+ $dataNamespace = __NAMESPACE__.'\\Data\\';
+
+ // allow forcing the data mode
+ // see https://github.com/chillerlan/php-qrcode/issues/39
+ if(in_array($this->options->dataMode, $dataModes, true)){
+ $dataInterface = $dataNamespace.$this->options->dataMode;
+
+ return new $dataInterface($this->options, $data);
+ }
+
+ foreach($dataModes as $mode){
+ $dataInterface = $dataNamespace.$mode;
+
+ if(call_user_func_array([$this, 'is'.$mode], [$data]) && class_exists($dataInterface)){
+ return new $dataInterface($this->options, $data);
+ }
+
+ }
+
+ throw new QRCodeDataException('invalid data type'); // @codeCoverageIgnore
+ }
+
+ /**
+ * returns a fresh (built-in) QROutputInterface
+ *
+ * @param string $data
+ *
+ * @return \chillerlan\QRCode\Output\QROutputInterface
+ * @throws \chillerlan\QRCode\Output\QRCodeOutputException
+ */
+ protected function initOutputInterface(string $data):QROutputInterface{
+
+ if($this->options->outputType === $this::OUTPUT_CUSTOM && class_exists($this->options->outputInterface)){
+ return new $this->options->outputInterface($this->options, $this->getMatrix($data));
+ }
+
+ foreach($this::OUTPUT_MODES as $outputInterface => $modes){
+
+ if(in_array($this->options->outputType, $modes, true) && class_exists($outputInterface)){
+ return new $outputInterface($this->options, $this->getMatrix($data));
+ }
+
+ }
+
+ throw new QRCodeOutputException('invalid output type');
+ }
+
+ /**
+ * checks if a string qualifies as numeric
+ *
+ * @param string $string
+ *
+ * @return bool
+ */
+ public function isNumber(string $string):bool{
+ return $this->checkString($string, QRDataInterface::NUMBER_CHAR_MAP);
+ }
+
+ /**
+ * checks if a string qualifies as alphanumeric
+ *
+ * @param string $string
+ *
+ * @return bool
+ */
+ public function isAlphaNum(string $string):bool{
+ return $this->checkString($string, QRDataInterface::ALPHANUM_CHAR_MAP);
+ }
+
+ /**
+ * checks is a given $string matches the characters of a given $charmap, returns false on the first invalid occurence.
+ *
+ * @param string $string
+ * @param array $charmap
+ *
+ * @return bool
+ */
+ protected function checkString(string $string, array $charmap):bool{
+ $len = strlen($string);
+
+ for($i = 0; $i < $len; $i++){
+ if(!in_array($string[$i], $charmap, true)){
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * checks if a string qualifies as Kanji
+ *
+ * @param string $string
+ *
+ * @return bool
+ */
+ public function isKanji(string $string):bool{
+ $i = 0;
+ $len = strlen($string);
+
+ while($i + 1 < $len){
+ $c = ((0xff & ord($string[$i])) << 8) | (0xff & ord($string[$i + 1]));
+
+ if(!($c >= 0x8140 && $c <= 0x9FFC) && !($c >= 0xE040 && $c <= 0xEBBF)){
+ return false;
+ }
+
+ $i += 2;
+ }
+
+ return $i >= $len;
+ }
+
+ /**
+ * a dummy
+ *
+ * @param $data
+ *
+ * @return bool
+ */
+ protected function isByte(string $data):bool{
+ return !empty($data);
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/src/QRCodeException.php b/vendor/chillerlan/php-qrcode/src/QRCodeException.php
new file mode 100644
index 000000000..68af380ff
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/QRCodeException.php
@@ -0,0 +1,15 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode;
+
+class QRCodeException extends \Exception{}
diff --git a/vendor/chillerlan/php-qrcode/src/QROptions.php b/vendor/chillerlan/php-qrcode/src/QROptions.php
new file mode 100644
index 000000000..778ae0407
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/QROptions.php
@@ -0,0 +1,61 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode;
+
+use chillerlan\Settings\SettingsContainerAbstract;
+
+/**
+ * @property int $version
+ * @property int $versionMin
+ * @property int $versionMax
+ * @property int $eccLevel
+ * @property int $maskPattern
+ * @property bool $addQuietzone
+ * @property bool $quietzoneSize
+ *
+ * @property string $dataMode
+ * @property string $outputType
+ * @property string $outputInterface
+ * @property string $cachefile
+ *
+ * @property string $eol
+ * @property int $scale
+ *
+ * @property string $cssClass
+ * @property string $svgOpacity
+ * @property string $svgDefs
+ * @property int $svgViewBoxSize
+ *
+ * @property string $textDark
+ * @property string $textLight
+ *
+ * @property string $markupDark
+ * @property string $markupLight
+ *
+ * @property bool $returnResource
+ * @property bool $imageBase64
+ * @property bool $imageTransparent
+ * @property array $imageTransparencyBG
+ * @property int $pngCompression
+ * @property int $jpegQuality
+ *
+ * @property string $imagickFormat
+ * @property string $imagickBG
+ *
+ * @property string $fpdfMeasureUnit
+ *
+ * @property array $moduleValues
+ */
+class QROptions extends SettingsContainerAbstract{
+ use QROptionsTrait;
+}
diff --git a/vendor/chillerlan/php-qrcode/src/QROptionsTrait.php b/vendor/chillerlan/php-qrcode/src/QROptionsTrait.php
new file mode 100644
index 000000000..45d4cb415
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/src/QROptionsTrait.php
@@ -0,0 +1,408 @@
+
+ * @copyright 2018 smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCode;
+
+use function array_values, count, in_array, is_array, is_numeric, max, min, sprintf, strtolower;
+
+trait QROptionsTrait{
+
+ /**
+ * QR Code version number
+ *
+ * [1 ... 40] or QRCode::VERSION_AUTO
+ *
+ * @var int
+ */
+ protected $version = QRCode::VERSION_AUTO;
+
+ /**
+ * Minimum QR version (if $version = QRCode::VERSION_AUTO)
+ *
+ * @var int
+ */
+ protected $versionMin = 1;
+
+ /**
+ * Maximum QR version
+ *
+ * @var int
+ */
+ protected $versionMax = 40;
+
+ /**
+ * Error correct level
+ *
+ * QRCode::ECC_X where X is
+ * L => 7%
+ * M => 15%
+ * Q => 25%
+ * H => 30%
+ *
+ * @var int
+ */
+ protected $eccLevel = QRCode::ECC_L;
+
+ /**
+ * Mask Pattern to use
+ *
+ * [0...7] or QRCode::MASK_PATTERN_AUTO
+ *
+ * @var int
+ */
+ protected $maskPattern = QRCode::MASK_PATTERN_AUTO;
+
+ /**
+ * Add a "quiet zone" (margin) according to the QR code spec
+ *
+ * @var bool
+ */
+ protected $addQuietzone = true;
+
+ /**
+ * Size of the quiet zone
+ *
+ * internally clamped to [0 ... $moduleCount / 2], defaults to 4 modules
+ *
+ * @var int
+ */
+ protected $quietzoneSize = 4;
+
+ /**
+ * Use this to circumvent the data mode detection and force the usage of the given mode.
+ * valid modes are: Number, AlphaNum, Kanji, Byte
+ *
+ * @see https://github.com/chillerlan/php-qrcode/issues/39
+ *
+ * @var string|null
+ */
+ protected $dataMode = null;
+
+ /**
+ * QRCode::OUTPUT_MARKUP_XXXX where XXXX = HTML, SVG
+ * QRCode::OUTPUT_IMAGE_XXX where XXX = PNG, GIF, JPG
+ * QRCode::OUTPUT_STRING_XXXX where XXXX = TEXT, JSON
+ * QRCode::OUTPUT_CUSTOM
+ *
+ * @var string
+ */
+ protected $outputType = QRCode::OUTPUT_IMAGE_PNG;
+
+ /**
+ * the FQCN of the custom QROutputInterface if $outputType is set to QRCode::OUTPUT_CUSTOM
+ *
+ * @var string|null
+ */
+ protected $outputInterface = null;
+
+ /**
+ * /path/to/cache.file
+ *
+ * @var string|null
+ */
+ protected $cachefile = null;
+
+ /**
+ * newline string [HTML, SVG, TEXT]
+ *
+ * @var string
+ */
+ protected $eol = PHP_EOL;
+
+ /**
+ * size of a QR code pixel [SVG, IMAGE_*]
+ * HTML -> via CSS
+ *
+ * @var int
+ */
+ protected $scale = 5;
+
+ /**
+ * a common css class
+ *
+ * @var string
+ */
+ protected $cssClass = '';
+
+ /**
+ * SVG opacity
+ *
+ * @var float
+ */
+ protected $svgOpacity = 1.0;
+
+ /**
+ * anything between
+ *
+ * @see https://developer.mozilla.org/docs/Web/SVG/Element/defs
+ *
+ * @var string
+ */
+ protected $svgDefs = '';
+
+ /**
+ * SVG viewBox size. a single integer number which defines width/height of the viewBox attribute.
+ *
+ * viewBox="0 0 x x"
+ *
+ * @see https://css-tricks.com/scale-svg/#article-header-id-3
+ *
+ * @var int|null
+ */
+ protected $svgViewBoxSize = null;
+
+ /**
+ * string substitute for dark
+ *
+ * @var string
+ */
+ protected $textDark = '🔴';
+
+ /**
+ * string substitute for light
+ *
+ * @var string
+ */
+ protected $textLight = 'â•';
+
+ /**
+ * markup substitute for dark (CSS value)
+ *
+ * @var string
+ */
+ protected $markupDark = '#000';
+
+ /**
+ * markup substitute for light (CSS value)
+ *
+ * @var string
+ */
+ protected $markupLight = '#fff';
+
+ /**
+ * Return the image resource instead of a render if applicable.
+ * This option overrides other output options, such as $cachefile and $imageBase64.
+ *
+ * Supported by the following modules:
+ *
+ * - QRImage: resource
+ * - QRImagick: Imagick
+ * - QRFpdf: FPDF
+ *
+ * @see \chillerlan\QRCode\Output\QROutputInterface::dump()
+ *
+ * @var bool
+ */
+ protected $returnResource = false;
+
+ /**
+ * toggle base64 or raw image data
+ *
+ * @var bool
+ */
+ protected $imageBase64 = true;
+
+ /**
+ * toggle transparency, not supported by jpg
+ *
+ * @var bool
+ */
+ protected $imageTransparent = true;
+
+ /**
+ * @see imagecolortransparent()
+ *
+ * @var array [R, G, B]
+ */
+ protected $imageTransparencyBG = [255, 255, 255];
+
+ /**
+ * @see imagepng()
+ *
+ * @var int
+ */
+ protected $pngCompression = -1;
+
+ /**
+ * @see imagejpeg()
+ *
+ * @var int
+ */
+ protected $jpegQuality = 85;
+
+ /**
+ * Imagick output format
+ *
+ * @see Imagick::setType()
+ *
+ * @var string
+ */
+ protected $imagickFormat = 'png';
+
+ /**
+ * Imagick background color (defaults to "transparent")
+ *
+ * @see \ImagickPixel::__construct()
+ *
+ * @var string|null
+ */
+ protected $imagickBG = null;
+
+ /**
+ * Measurement unit for FPDF output: pt, mm, cm, in (defaults to "pt")
+ *
+ * @see \FPDF::__construct()
+ */
+ protected $fpdfMeasureUnit = 'pt';
+
+ /**
+ * Module values map
+ *
+ * HTML, IMAGICK: #ABCDEF, cssname, rgb(), rgba()...
+ * IMAGE: [63, 127, 255] // R, G, B
+ *
+ * @var array|null
+ */
+ protected $moduleValues = null;
+
+ /**
+ * clamp min/max version number
+ *
+ * @param int $versionMin
+ * @param int $versionMax
+ *
+ * @return void
+ */
+ protected function setMinMaxVersion(int $versionMin, int $versionMax):void{
+ $min = max(1, min(40, $versionMin));
+ $max = max(1, min(40, $versionMax));
+
+ $this->versionMin = min($min, $max);
+ $this->versionMax = max($min, $max);
+ }
+
+ /**
+ * sets the minimum version number
+ *
+ * @param int $version
+ *
+ * @return void
+ */
+ protected function set_versionMin(int $version):void{
+ $this->setMinMaxVersion($version, $this->versionMax);
+ }
+
+ /**
+ * sets the maximum version number
+ *
+ * @param int $version
+ *
+ * @return void
+ */
+ protected function set_versionMax(int $version):void{
+ $this->setMinMaxVersion($this->versionMin, $version);
+ }
+
+ /**
+ * sets the error correction level
+ *
+ * @param int $eccLevel
+ *
+ * @return void
+ * @throws \chillerlan\QRCode\QRCodeException
+ */
+ protected function set_eccLevel(int $eccLevel):void{
+
+ if(!isset(QRCode::ECC_MODES[$eccLevel])){
+ throw new QRCodeException(sprintf('Invalid error correct level: %s', $eccLevel));
+ }
+
+ $this->eccLevel = $eccLevel;
+ }
+
+ /**
+ * sets/clamps the mask pattern
+ *
+ * @param int $maskPattern
+ *
+ * @return void
+ */
+ protected function set_maskPattern(int $maskPattern):void{
+
+ if($maskPattern !== QRCode::MASK_PATTERN_AUTO){
+ $this->maskPattern = max(0, min(7, $maskPattern));
+ }
+
+ }
+
+ /**
+ * sets the transparency background color
+ *
+ * @param mixed $imageTransparencyBG
+ *
+ * @return void
+ * @throws \chillerlan\QRCode\QRCodeException
+ */
+ protected function set_imageTransparencyBG($imageTransparencyBG):void{
+
+ // invalid value - set to white as default
+ if(!is_array($imageTransparencyBG) || count($imageTransparencyBG) < 3){
+ $this->imageTransparencyBG = [255, 255, 255];
+
+ return;
+ }
+
+ foreach($imageTransparencyBG as $k => $v){
+
+ if(!is_numeric($v)){
+ throw new QRCodeException('Invalid RGB value.');
+ }
+
+ // clamp the values
+ $this->imageTransparencyBG[$k] = max(0, min(255, (int)$v));
+ }
+
+ // use the array values to not run into errors with the spread operator (...$arr)
+ $this->imageTransparencyBG = array_values($this->imageTransparencyBG);
+ }
+
+ /**
+ * sets/clamps the version number
+ *
+ * @param int $version
+ *
+ * @return void
+ */
+ protected function set_version(int $version):void{
+
+ if($version !== QRCode::VERSION_AUTO){
+ $this->version = max(1, min(40, $version));
+ }
+
+ }
+
+ /**
+ * sets the FPDF measurement unit
+ *
+ * @codeCoverageIgnore
+ */
+ protected function set_fpdfMeasureUnit(string $unit):void{
+ $unit = strtolower($unit);
+
+ if(in_array($unit, ['cm', 'in', 'mm', 'pt'], true)){
+ $this->fpdfMeasureUnit = $unit;
+ }
+
+ // @todo throw or ignore silently?
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Data/AlphaNumTest.php b/vendor/chillerlan/php-qrcode/tests/Data/AlphaNumTest.php
new file mode 100644
index 000000000..c29b1f639
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Data/AlphaNumTest.php
@@ -0,0 +1,44 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\{AlphaNum, QRCodeDataException};
+
+class AlphaNumTest extends DatainterfaceTestAbstract{
+
+ protected $FQCN = AlphaNum::class;
+ protected $testdata = '0 $%*+-./:';
+ protected $expected = [
+ 32, 80, 36, 212, 252, 15, 175, 251,
+ 176, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 112, 43, 9, 248, 200, 194, 75, 25,
+ 205, 173, 154, 68, 191, 16, 128,
+ 92, 112, 20, 198, 27
+ ];
+
+ public function testGetCharCodeException(){
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('illegal char: "#" [35]');
+
+ $this->dataInterface->setData('#');
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Data/ByteTest.php b/vendor/chillerlan/php-qrcode/tests/Data/ByteTest.php
new file mode 100644
index 000000000..cbfe1fab2
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Data/ByteTest.php
@@ -0,0 +1,38 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\Byte;
+
+class ByteTest extends DatainterfaceTestAbstract{
+
+ protected $FQCN = Byte::class;
+ protected $testdata = '[¯\_(ツ)_/¯]';
+ protected $expected = [
+ 64, 245, 188, 42, 245, 197, 242, 142,
+ 56, 56, 66, 149, 242, 252, 42, 245,
+ 208, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 79, 89, 226, 48, 209, 89, 151, 1,
+ 12, 73, 42, 163, 11, 34, 255, 205,
+ 21, 47, 250, 101
+ ];
+
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Data/DatainterfaceTestAbstract.php b/vendor/chillerlan/php-qrcode/tests/Data/DatainterfaceTestAbstract.php
new file mode 100644
index 000000000..19d74617a
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Data/DatainterfaceTestAbstract.php
@@ -0,0 +1,65 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Data\{QRCodeDataException, QRDataInterface, QRMatrix};
+use chillerlan\QRCodeTest\QRTestAbstract;
+
+abstract class DatainterfaceTestAbstract extends QRTestAbstract{
+
+ /**
+ * @var \chillerlan\QRCode\Data\QRDataAbstract
+ */
+ protected $dataInterface;
+
+ protected $testdata;
+ protected $expected;
+
+ protected function setUp():void{
+ parent::setUp();
+
+ $this->dataInterface = $this->reflection->newInstanceArgs([new QROptions(['version' => 4])]);
+ }
+
+ public function testInstance(){
+ $this->dataInterface = $this->reflection->newInstanceArgs([new QROptions, $this->testdata]);
+
+ $this->assertInstanceOf(QRDataInterface::class, $this->dataInterface);
+ }
+
+ public function testSetData(){
+ $this->dataInterface->setData($this->testdata);
+
+ $this->assertSame($this->expected, $this->getProperty('matrixdata')->getValue($this->dataInterface));
+ }
+
+ public function testInitMatrix(){
+ $m = $this->dataInterface->setData($this->testdata)->initMatrix(0);
+
+ $this->assertInstanceOf(QRMatrix::class, $m);
+ }
+
+ public function testGetMinimumVersion(){
+ $this->assertSame(1, $this->getMethod('getMinimumVersion')->invoke($this->dataInterface));
+ }
+
+ public function testGetMinimumVersionException(){
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('data exceeds');
+
+ $this->getProperty('strlen')->setValue($this->dataInterface, 13370);
+ $this->getMethod('getMinimumVersion')->invoke($this->dataInterface);
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Data/KanjiTest.php b/vendor/chillerlan/php-qrcode/tests/Data/KanjiTest.php
new file mode 100644
index 000000000..108b8fed7
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Data/KanjiTest.php
@@ -0,0 +1,50 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\{Kanji, QRCodeDataException};
+
+class KanjiTest extends DatainterfaceTestAbstract{
+
+ protected $FQCN = Kanji::class;
+ protected $testdata = '茗è·èŒ—è·èŒ—è·èŒ—è·èŒ—è·';
+ protected $expected = [
+ 128, 173, 85, 26, 95, 85, 70, 151,
+ 213, 81, 165, 245, 84, 105, 125, 85,
+ 26, 92, 0, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 195, 11, 221, 91, 141, 220, 163, 46,
+ 165, 37, 163, 176, 79, 0, 64, 68,
+ 96, 113, 54, 191
+ ];
+
+ public function testIllegalCharException1(){
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('illegal char at 1 [16191]');
+
+ $this->dataInterface->setData('ÃÃ');
+ }
+
+ public function testIllegalCharException2(){
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('illegal char at 1');
+
+ $this->dataInterface->setData('Ã');
+ }
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Data/MaskPatternTesterTest.php b/vendor/chillerlan/php-qrcode/tests/Data/MaskPatternTesterTest.php
new file mode 100644
index 000000000..ae4af9f29
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Data/MaskPatternTesterTest.php
@@ -0,0 +1,29 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\{QROptions, Data\Byte, Data\MaskPatternTester};
+use chillerlan\QRCodeTest\QRTestAbstract;
+
+class MaskPatternTesterTest extends QRTestAbstract{
+
+ protected $FQCN = MaskPatternTester::class;
+
+ // coverage
+ public function testMaskpattern(){
+ $matrix = (new Byte(new QROptions(['version' => 10]), 'test'))->initMatrix(3, true);
+
+ $this->assertSame(4243, (new MaskPatternTester($matrix))->testPattern());
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Data/NumberTest.php b/vendor/chillerlan/php-qrcode/tests/Data/NumberTest.php
new file mode 100644
index 000000000..983346a34
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Data/NumberTest.php
@@ -0,0 +1,44 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\Data\{Number, QRCodeDataException};
+
+class NumberTest extends DatainterfaceTestAbstract{
+
+ protected $FQCN = Number::class;
+ protected $testdata = '0123456789';
+ protected $expected = [
+ 16, 40, 12, 86, 106, 105, 0, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 17, 236, 17, 236, 17, 236, 17, 236,
+ 201, 141, 102, 116, 238, 162, 239, 230,
+ 222, 37, 79, 192, 42, 109, 188, 72,
+ 89, 63, 168, 151
+ ];
+
+ public function testGetCharCodeException(){
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('illegal char: "#" [35]');
+
+ $this->dataInterface->setData('#');
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Data/QRMatrixTest.php b/vendor/chillerlan/php-qrcode/tests/Data/QRMatrixTest.php
new file mode 100644
index 000000000..531c82eb2
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Data/QRMatrixTest.php
@@ -0,0 +1,260 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Data;
+
+use chillerlan\QRCode\QRCode;
+use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Data\{QRCodeDataException, QRMatrix};
+use chillerlan\QRCodeTest\QRTestAbstract;
+use ReflectionClass;
+
+class QRMatrixTest extends QRTestAbstract{
+
+ protected $FQCN = QRMatrix::class;
+
+ protected $version = 7;
+
+ /**
+ * @var \chillerlan\QRCode\Data\QRMatrix
+ */
+ protected $matrix;
+
+ protected function setUp():void{
+ parent::setUp();
+
+ $this->matrix = $this->reflection->newInstanceArgs([$this->version, QRCode::ECC_L]);
+ }
+
+ public function testInvalidVersionException(){
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('invalid QR Code version');
+
+ $this->reflection->newInstanceArgs([42, 0]);
+ }
+
+ public function testInvalidEccException(){
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('invalid ecc level');
+
+ $this->reflection->newInstanceArgs([1, 42]);
+ }
+
+ public function testInstance(){
+ $this->assertInstanceOf($this->FQCN, $this->matrix);
+ }
+
+ public function testSize(){
+ $this->assertCount($this->matrix->size(), $this->matrix->matrix());
+ }
+
+ public function testVersion(){
+ $this->assertSame($this->version, $this->matrix->version());
+ }
+
+ public function testECC(){
+ $this->assertSame(QRCode::ECC_L, $this->matrix->eccLevel());
+ }
+
+ public function testMaskPattern(){
+ $this->assertSame(-1, $this->matrix->maskPattern());
+ }
+
+ public function testGetSetCheck(){
+ $this->matrix->set(10, 10, true, QRMatrix::M_TEST);
+ $this->assertSame(65280, $this->matrix->get(10, 10));
+ $this->assertTrue($this->matrix->check(10, 10));
+
+ $this->matrix->set(20, 20, false, QRMatrix::M_TEST);
+ $this->assertSame(255, $this->matrix->get(20, 20));
+ $this->assertFalse($this->matrix->check(20, 20));
+ }
+
+ public function testSetDarkModule(){
+ $this->matrix->setDarkModule();
+
+ $this->assertSame(QRMatrix::M_DARKMODULE << 8, $this->matrix->get(8, $this->matrix->size() - 8));
+ }
+
+ public function testSetFinderPattern(){
+ $this->matrix->setFinderPattern();
+
+ $this->assertSame(QRMatrix::M_FINDER << 8, $this->matrix->get(0, 0));
+ $this->assertSame(QRMatrix::M_FINDER << 8, $this->matrix->get(0, $this->matrix->size() - 1));
+ $this->assertSame(QRMatrix::M_FINDER << 8, $this->matrix->get($this->matrix->size() - 1, 0));
+ }
+
+ public function testSetSeparators(){
+ $this->matrix->setSeparators();
+
+ $this->assertSame(QRMatrix::M_SEPARATOR, $this->matrix->get(7, 0));
+ $this->assertSame(QRMatrix::M_SEPARATOR, $this->matrix->get(0, 7));
+ $this->assertSame(QRMatrix::M_SEPARATOR, $this->matrix->get(0, $this->matrix->size() - 8));
+ $this->assertSame(QRMatrix::M_SEPARATOR, $this->matrix->get($this->matrix->size() - 8, 0));
+ }
+
+ public function testSetAlignmentPattern(){
+ $this->matrix
+ ->setFinderPattern()
+ ->setAlignmentPattern()
+ ;
+
+ $alignmentPattern = (new ReflectionClass(QRMatrix::class))->getConstant('alignmentPattern')[$this->version];
+
+ foreach($alignmentPattern as $py){
+ foreach($alignmentPattern as $px){
+
+ if($this->matrix->get($px, $py) === QRMatrix::M_FINDER << 8){
+ $this->assertSame(QRMatrix::M_FINDER << 8, $this->matrix->get($px, $py), 'skipped finder pattern');
+ continue;
+ }
+
+ $this->assertSame(QRMatrix::M_ALIGNMENT << 8, $this->matrix->get($px, $py));
+ }
+ }
+
+ }
+
+ public function testSetTimingPattern(){
+ $this->matrix
+ ->setAlignmentPattern()
+ ->setTimingPattern()
+ ;
+
+ $size = $this->matrix->size();
+
+ for($i = 7; $i < $size - 7; $i++){
+ if($i % 2 === 0){
+ $p1 = $this->matrix->get(6, $i);
+
+ if($p1 === QRMatrix::M_ALIGNMENT << 8){
+ $this->assertSame(QRMatrix::M_ALIGNMENT << 8, $p1, 'skipped alignment pattern');
+ continue;
+ }
+
+ $this->assertSame(QRMatrix::M_TIMING << 8, $p1);
+ $this->assertSame(QRMatrix::M_TIMING << 8, $this->matrix->get($i, 6));
+ }
+ }
+ }
+
+ public function testSetVersionNumber(){
+ $this->matrix->setVersionNumber(true);
+
+ $this->assertSame(QRMatrix::M_VERSION, $this->matrix->get($this->matrix->size() - 9, 0));
+ $this->assertSame(QRMatrix::M_VERSION, $this->matrix->get($this->matrix->size() - 11, 5));
+ $this->assertSame(QRMatrix::M_VERSION, $this->matrix->get(0, $this->matrix->size() - 9));
+ $this->assertSame(QRMatrix::M_VERSION, $this->matrix->get(5, $this->matrix->size() - 11));
+ }
+
+ public function testSetFormatInfo(){
+ $this->matrix->setFormatInfo(0, true);
+
+ $this->assertSame(QRMatrix::M_FORMAT, $this->matrix->get(8, 0));
+ $this->assertSame(QRMatrix::M_FORMAT, $this->matrix->get(0, 8));
+ $this->assertSame(QRMatrix::M_FORMAT, $this->matrix->get($this->matrix->size() - 1, 8));
+ $this->assertSame(QRMatrix::M_FORMAT, $this->matrix->get($this->matrix->size() - 8, 8));
+ }
+
+ public function testSetQuietZone(){
+ $size = $this->matrix->size();
+ $q = 5;
+
+ $this->matrix->set(0, 0, true, QRMatrix::M_TEST);
+ $this->matrix->set($size - 1, $size - 1, true, QRMatrix::M_TEST);
+
+ $this->matrix->setQuietZone($q);
+
+ $this->assertCount($size + 2 * $q, $this->matrix->matrix());
+ $this->assertCount($size + 2 * $q, $this->matrix->matrix()[$size - 1]);
+
+ $size = $this->matrix->size();
+ $this->assertSame(QRMatrix::M_QUIETZONE, $this->matrix->get(0, 0));
+ $this->assertSame(QRMatrix::M_QUIETZONE, $this->matrix->get($size - 1, $size - 1));
+
+ $this->assertSame(QRMatrix::M_TEST << 8, $this->matrix->get($q, $q));
+ $this->assertSame(QRMatrix::M_TEST << 8, $this->matrix->get($size - 1 - $q, $size - 1 - $q));
+ }
+
+ public function testSetQuietZoneException(){
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('use only after writing data');
+
+ $this->matrix->setQuietZone();
+ }
+
+ public function testSetLogoSpaceOrientation():void{
+ $o = new QROptions;
+ $o->version = 10;
+ $o->eccLevel = QRCode::ECC_H;
+ $o->addQuietzone = false;
+
+ $matrix = (new QRCode($o))->getMatrix('testdata');
+ // also testing size adjustment to uneven numbers
+ $matrix->setLogoSpace(20, 14);
+
+ // NW corner
+ $this::assertNotSame(QRMatrix::M_LOGO, $matrix->get(17, 20));
+ $this::assertSame(QRMatrix::M_LOGO, $matrix->get(18, 21));
+
+ // SE corner
+ $this::assertSame(QRMatrix::M_LOGO, $matrix->get(38, 35));
+ $this::assertNotSame(QRMatrix::M_LOGO, $matrix->get(39, 36));
+ }
+
+ public function testSetLogoSpacePosition():void{
+ $o = new QROptions;
+ $o->version = 10;
+ $o->eccLevel = QRCode::ECC_H;
+ $o->addQuietzone = true;
+ $o->quietzoneSize = 10;
+
+ $m = (new QRCode($o))->getMatrix('testdata');
+
+ // logo space should not overwrite quiet zone & function patterns
+ $m->setLogoSpace(21, 21, -10, -10);
+ $this::assertSame(QRMatrix::M_QUIETZONE, $m->get(9, 9));
+ $this::assertSame(QRMatrix::M_FINDER << 8, $m->get(10, 10));
+ $this::assertSame(QRMatrix::M_FINDER << 8, $m->get(16, 16));
+ $this::assertSame(QRMatrix::M_SEPARATOR, $m->get(17, 17));
+ $this::assertSame(QRMatrix::M_FORMAT << 8, $m->get(18, 18));
+ $this::assertSame(QRMatrix::M_LOGO, $m->get(19, 19));
+ $this::assertSame(QRMatrix::M_LOGO, $m->get(20, 20));
+ $this::assertNotSame(QRMatrix::M_LOGO, $m->get(21, 21));
+
+ // i just realized that setLogoSpace() could be called multiple times
+ // on the same instance and i'm not going to do anything about it :P
+ $m->setLogoSpace(21, 21, 45, 45);
+ $this::assertNotSame(QRMatrix::M_LOGO, $m->get(54, 54));
+ $this::assertSame(QRMatrix::M_LOGO, $m->get(55, 55));
+ $this::assertSame(QRMatrix::M_QUIETZONE, $m->get(67, 67));
+ }
+
+ public function testSetLogoSpaceInvalidEccException():void{
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('ECC level "H" required to add logo space');
+
+ (new QRCode)->getMatrix('testdata')->setLogoSpace(50, 50);
+ }
+
+ public function testSetLogoSpaceMaxSizeException():void{
+ $this->expectException(QRCodeDataException::class);
+ $this->expectExceptionMessage('logo space exceeds the maximum error correction capacity');
+
+ $o = new QROptions;
+ $o->version = 5;
+ $o->eccLevel = QRCode::ECC_H;
+
+ (new QRCode($o))->getMatrix('testdata')->setLogoSpace(50, 50);
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Helpers/BitBufferTest.php b/vendor/chillerlan/php-qrcode/tests/Helpers/BitBufferTest.php
new file mode 100644
index 000000000..25d1c3504
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Helpers/BitBufferTest.php
@@ -0,0 +1,53 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Helpers;
+
+use chillerlan\QRCode\{QRCode, Helpers\BitBuffer};
+use chillerlan\QRCodeTest\QRTestAbstract;
+
+class BitBufferTest extends QRTestAbstract{
+
+ /**
+ * @var \chillerlan\QRCode\Helpers\BitBuffer
+ */
+ protected $bitBuffer;
+
+ protected function setUp():void{
+ $this->bitBuffer = new BitBuffer;
+ }
+
+ public function bitProvider(){
+ return [
+ 'number' => [QRCode::DATA_NUMBER, 16],
+ 'alphanum' => [QRCode::DATA_ALPHANUM, 32],
+ 'byte' => [QRCode::DATA_BYTE, 64],
+ 'kanji' => [QRCode::DATA_KANJI, 128],
+ ];
+ }
+
+ /**
+ * @dataProvider bitProvider
+ */
+ public function testPut($data, $value){
+ $this->bitBuffer->put($data, 4);
+ $this->assertSame($value, $this->bitBuffer->buffer[0]);
+ $this->assertSame(4, $this->bitBuffer->length);
+ }
+
+ public function testClear(){
+ $this->bitBuffer->clear();
+ $this->assertSame([], $this->bitBuffer->buffer);
+ $this->assertSame(0, $this->bitBuffer->length);
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Helpers/PolynomialTest.php b/vendor/chillerlan/php-qrcode/tests/Helpers/PolynomialTest.php
new file mode 100644
index 000000000..7f6da303c
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Helpers/PolynomialTest.php
@@ -0,0 +1,42 @@
+
+ * @copyright 2015 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Helpers;
+
+use chillerlan\QRCode\Helpers\Polynomial;
+use chillerlan\QRCode\QRCodeException;
+use chillerlan\QRCodeTest\QRTestAbstract;
+
+class PolynomialTest extends QRTestAbstract{
+
+ /**
+ * @var \chillerlan\QRCode\Helpers\Polynomial
+ */
+ protected $polynomial;
+
+ protected function setUp():void{
+ $this->polynomial = new Polynomial;
+ }
+
+ public function testGexp(){
+ $this->assertSame(142, $this->polynomial->gexp(-1));
+ $this->assertSame(133, $this->polynomial->gexp(128));
+ $this->assertSame(2, $this->polynomial->gexp(256));
+ }
+
+ public function testGlogException(){
+ $this->expectException(QRCodeException::class);
+ $this->expectExceptionMessage('log(0)');
+
+ $this->polynomial->glog(0);
+ }
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Output/QRFpdfTest.php b/vendor/chillerlan/php-qrcode/tests/Output/QRFpdfTest.php
new file mode 100644
index 000000000..1b49182d2
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Output/QRFpdfTest.php
@@ -0,0 +1,83 @@
+
+ * @copyright 2020 smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Output;
+
+use FPDF;
+use chillerlan\QRCode\Output\{QRFpdf, QROutputInterface};
+use chillerlan\QRCode\{QRCode, QROptions};
+
+use function class_exists, substr;
+
+/**
+ * Tests the QRFpdf output module
+ */
+class QRFpdfTest extends QROutputTestAbstract{
+
+ protected $FQCN = QRFpdf::class;
+
+ /**
+ * @inheritDoc
+ * @internal
+ */
+ public function setUp():void{
+
+ if(!class_exists(FPDF::class)){
+ $this->markTestSkipped('FPDF not available');
+ return;
+ }
+
+ parent::setUp();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function testSetModuleValues():void{
+
+ $this->options->moduleValues = [
+ // data
+ 1024 => [0, 0, 0],
+ 4 => [255, 255, 255],
+ ];
+
+ $this->outputInterface->dump();
+
+ $this::assertTrue(true); // tricking the code coverage
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function testRenderImage():void{
+ $type = QRCode::OUTPUT_FPDF;
+
+ $this->options->outputType = $type;
+ $this->options->imageBase64 = false;
+ $this->outputInterface->dump($this::cachefile.$type);
+
+ // substr() to avoid CreationDate
+ $expected = substr(file_get_contents($this::cachefile.$type), 0, 2000);
+ $actual = substr($this->outputInterface->dump(), 0, 2000);
+
+ $this::assertSame($expected, $actual);
+ }
+
+ public function testOutputGetResource():void{
+ $this->options->returnResource = true;
+
+ $this->setOutputInterface();
+
+ $this::assertInstanceOf(FPDF::class, $this->outputInterface->dump());
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Output/QRImageTest.php b/vendor/chillerlan/php-qrcode/tests/Output/QRImageTest.php
new file mode 100644
index 000000000..34ecf4f91
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Output/QRImageTest.php
@@ -0,0 +1,69 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Output;
+
+use chillerlan\QRCode\{QRCode, Output\QRImage};
+
+class QRImageTest extends QROutputTestAbstract{
+
+ protected $FQCN = QRImage::class;
+
+ public function types(){
+ return [
+ 'png' => [QRCode::OUTPUT_IMAGE_PNG],
+ 'gif' => [QRCode::OUTPUT_IMAGE_GIF],
+ 'jpg' => [QRCode::OUTPUT_IMAGE_JPG],
+ ];
+ }
+
+ /**
+ * @dataProvider types
+ * @param $type
+ */
+ public function testImageOutput($type){
+ $this->options->outputType = $type;
+ $this->options->imageBase64 = false;
+
+ $this->setOutputInterface();
+ $this->outputInterface->dump($this::cachefile.$type);
+ $img = $this->outputInterface->dump();
+
+ if($type === QRCode::OUTPUT_IMAGE_JPG){ // jpeg encoding may cause different results
+ $this->markAsRisky();
+ }
+
+ $this->assertSame($img, file_get_contents($this::cachefile.$type));
+ }
+
+ public function testSetModuleValues(){
+
+ $this->options->moduleValues = [
+ // data
+ 1024 => [0, 0, 0],
+ 4 => [255, 255, 255],
+ ];
+
+ $this->setOutputInterface()->dump();
+
+ $this->assertTrue(true); // tricking the code coverage
+ }
+
+ public function testOutputGetResource():void{
+ $this->options->returnResource = true;
+
+ $this->setOutputInterface();
+
+ $this::assertIsResource($this->outputInterface->dump());
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Output/QRImagickTest.php b/vendor/chillerlan/php-qrcode/tests/Output/QRImagickTest.php
new file mode 100644
index 000000000..c927cc64e
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Output/QRImagickTest.php
@@ -0,0 +1,66 @@
+
+ * @copyright 2018 smiley
+ * @license MIT
+ *
+ * @noinspection PhpComposerExtensionStubsInspection
+ */
+
+namespace chillerlan\QRCodeTest\Output;
+
+use Imagick;
+use chillerlan\QRCode\{QRCode, Output\QRImagick};
+
+class QRImagickTest extends QROutputTestAbstract{
+
+ protected $FQCN = QRImagick::class;
+
+ public function setUp():void{
+
+ if(!extension_loaded('imagick')){
+ $this->markTestSkipped('ext-imagick not loaded');
+ return;
+ }
+
+ parent::setUp();
+ }
+
+ public function testImageOutput(){
+ $type = QRCode::OUTPUT_IMAGICK;
+
+ $this->options->outputType = $type;
+ $this->setOutputInterface();
+ $this->outputInterface->dump($this::cachefile.$type);
+ $img = $this->outputInterface->dump();
+
+ $this->assertSame($img, file_get_contents($this::cachefile.$type));
+ }
+
+ public function testSetModuleValues(){
+
+ $this->options->moduleValues = [
+ // data
+ 1024 => '#4A6000',
+ 4 => '#ECF9BE',
+ ];
+
+ $this->setOutputInterface()->dump();
+
+ $this->assertTrue(true); // tricking the code coverage
+ }
+
+ public function testOutputGetResource():void{
+ $this->options->returnResource = true;
+
+ $this->setOutputInterface();
+
+ $this::assertInstanceOf(Imagick::class, $this->outputInterface->dump());
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Output/QRMarkupTest.php b/vendor/chillerlan/php-qrcode/tests/Output/QRMarkupTest.php
new file mode 100644
index 000000000..24fdc3ce6
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Output/QRMarkupTest.php
@@ -0,0 +1,79 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Output;
+
+use chillerlan\QRCode\{QRCode, Output\QRMarkup};
+
+class QRMarkupTest extends QROutputTestAbstract{
+
+ protected $FQCN = QRMarkup::class;
+
+ public function types(){
+ return [
+ 'html' => [QRCode::OUTPUT_MARKUP_HTML],
+ 'svg' => [QRCode::OUTPUT_MARKUP_SVG],
+ ];
+ }
+
+ /**
+ * @dataProvider types
+ * @param $type
+ */
+ public function testMarkupOutputFile($type){
+ $this->options->outputType = $type;
+ $this->options->cachefile = $this::cachefile.$type;
+ $this->setOutputInterface();
+ $data = $this->outputInterface->dump();
+
+ $this->assertSame($data, file_get_contents($this->options->cachefile));
+ }
+
+ /**
+ * @dataProvider types
+ * @param $type
+ */
+ public function testMarkupOutput($type){
+ $this->options->imageBase64 = false;
+ $this->options->outputType = $type;
+ $this->setOutputInterface();
+
+ $expected = explode($this->options->eol, file_get_contents($this::cachefile.$type));
+ // cut off the doctype & head
+ array_shift($expected);
+
+ if($type === QRCode::OUTPUT_MARKUP_HTML){
+ // cut off the tag
+ array_pop($expected);
+ }
+
+ $expected = implode($this->options->eol, $expected);
+
+ $this->assertSame(trim($expected), trim($this->outputInterface->dump()));
+ }
+
+ public function testSetModuleValues(){
+
+ $this->options->imageBase64 = false;
+ $this->options->moduleValues = [
+ // data
+ 1024 => '#4A6000',
+ 4 => '#ECF9BE',
+ ];
+
+ $this->setOutputInterface();
+ $data = $this->outputInterface->dump();
+ $this->assertStringContainsString('#4A6000', $data);
+ $this->assertStringContainsString('#ECF9BE', $data);
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Output/QROutputTestAbstract.php b/vendor/chillerlan/php-qrcode/tests/Output/QROutputTestAbstract.php
new file mode 100644
index 000000000..6cd95d080
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Output/QROutputTestAbstract.php
@@ -0,0 +1,71 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Output;
+
+use chillerlan\QRCode\QROptions;
+use chillerlan\QRCode\Data\Byte;
+use chillerlan\QRCode\Output\{QRCodeOutputException, QROutputInterface};
+use chillerlan\QRCodeTest\QRTestAbstract;
+
+use function dirname, file_exists, mkdir;
+
+abstract class QROutputTestAbstract extends QRTestAbstract{
+
+ const cachefile = __DIR__.'/../../.build/output_test/test.';
+
+ /**
+ * @var \chillerlan\QRCode\Output\QROutputInterface
+ */
+ protected $outputInterface;
+
+ /**
+ * @var \chillerlan\QRCode\QROptions
+ */
+ protected $options;
+
+ /**
+ * @var \chillerlan\QRCode\Data\QRMatrix
+ */
+ protected $matrix;
+
+ protected function setUp():void{
+ parent::setUp();
+
+ $buildDir = dirname($this::cachefile);
+ if(!file_exists($buildDir)){
+ mkdir($buildDir, 0777, true);
+ }
+
+ $this->options = new QROptions;
+ $this->setOutputInterface();
+ }
+
+ protected function setOutputInterface(){
+ $this->outputInterface = $this->reflection->newInstanceArgs([$this->options, (new Byte($this->options, 'testdata'))->initMatrix(0)]);
+ return $this->outputInterface;
+ }
+
+ public function testInstance(){
+ $this->assertInstanceOf(QROutputInterface::class, $this->outputInterface);
+ }
+
+ public function testSaveException(){
+ $this->expectException(QRCodeOutputException::class);
+ $this->expectExceptionMessage('Could not write data to cache file: /foo');
+
+ $this->options->cachefile = '/foo';
+ $this->setOutputInterface();
+ $this->outputInterface->dump();
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/Output/QRStringTest.php b/vendor/chillerlan/php-qrcode/tests/Output/QRStringTest.php
new file mode 100644
index 000000000..5dbd34010
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/Output/QRStringTest.php
@@ -0,0 +1,56 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest\Output;
+
+use chillerlan\QRCode\{QRCode, Output\QRString};
+
+class QRStringTest extends QROutputTestAbstract{
+
+ protected $FQCN = QRString::class;
+
+ public function types(){
+ return [
+ 'json' => [QRCode::OUTPUT_STRING_JSON],
+ 'text' => [QRCode::OUTPUT_STRING_TEXT],
+ ];
+ }
+
+ /**
+ * @dataProvider types
+ * @param $type
+ */
+ public function testStringOutput($type){
+ $this->options->outputType = $type;
+ $this->options->cachefile = $this::cachefile.$type;
+ $this->setOutputInterface();
+ $data = $this->outputInterface->dump();
+
+ $this->assertSame($data, file_get_contents($this->options->cachefile));
+ }
+
+ public function testSetModuleValues(){
+
+ $this->options->moduleValues = [
+ // data
+ 1024 => 'A',
+ 4 => 'B',
+ ];
+
+ $this->setOutputInterface();
+ $data = $this->outputInterface->dump();
+
+ $this->assertStringContainsString('A', $data);
+ $this->assertStringContainsString('B', $data);
+ }
+
+}
diff --git a/vendor/chillerlan/php-qrcode/tests/QRCodeTest.php b/vendor/chillerlan/php-qrcode/tests/QRCodeTest.php
new file mode 100644
index 000000000..8613c961f
--- /dev/null
+++ b/vendor/chillerlan/php-qrcode/tests/QRCodeTest.php
@@ -0,0 +1,140 @@
+
+ * @copyright 2017 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\QRCodeTest;
+
+use chillerlan\QRCode\{QROptions, QRCode};
+use chillerlan\QRCode\Data\{AlphaNum, Byte, Number, QRCodeDataException};
+use chillerlan\QRCode\Output\QRCodeOutputException;
+use chillerlan\QRCodeExamples\MyCustomOutput;
+
+use function random_bytes;
+
+class QRCodeTest extends QRTestAbstract{
+
+ protected $FQCN = QRCode::class;
+
+ /**
+ * @var \chillerlan\QRCode\QRCode
+ */
+ protected $qrcode;
+
+ protected function setUp():void{
+ parent::setUp();
+
+ $this->qrcode = $this->reflection->newInstance();
+ }
+
+ public function testIsNumber(){
+ $this->assertTrue($this->qrcode->isNumber('0123456789'));
+ $this->assertFalse($this->qrcode->isNumber('ABC'));
+ }
+
+ public function testIsAlphaNum(){
+ $this->assertTrue($this->qrcode->isAlphaNum('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 $%*+-./:'));
+ $this->assertFalse($this->qrcode->isAlphaNum('abc'));
+ }
+
+ public function testIsKanji(){
+ $this->assertTrue($this->qrcode->isKanji('茗è·'));
+ $this->assertFalse($this->qrcode->isKanji('Ã'));
+ }
+
+ // coverage
+
+ public function typeDataProvider(){
+ return [
+ 'png' => [QRCode::OUTPUT_IMAGE_PNG, 'data:image/png;base64,'],
+ 'gif' => [QRCode::OUTPUT_IMAGE_GIF, 'data:image/gif;base64,'],
+ 'jpg' => [QRCode::OUTPUT_IMAGE_JPG, 'data:image/jpg;base64,'],
+ 'svg' => [QRCode::OUTPUT_MARKUP_SVG, 'data:image/svg+xml;base64,'],
+ 'html' => [QRCode::OUTPUT_MARKUP_HTML, 'foo = 'what';
+$container->bar = 'foo';
+
+// which is equivalent to
+$container = new MyContainer(['bar' => 'foo', 'foo' => 'what']);
+// ...or try
+$container->fromJSON('{"foo": "what", "bar": "foo"}');
+
+
+// fetch all properties as array
+$container->toArray(); // -> ['foo' => 'what', 'bar' => 'foo']
+// or JSON
+$container->toJSON(); // -> {"foo": "what", "bar": "foo"}
+
+//non-existing properties will be ignored:
+$container->nope = 'what';
+
+var_dump($container->nope); // -> null
+```
+
+### Advanced usage
+```php
+trait SomeOptions{
+ protected $foo;
+ protected $what;
+
+ // this method will be called in SettingsContainerAbstract::construct()
+ // after the properties have been set
+ protected function SomeOptions(){
+ // just some constructor stuff...
+ $this->foo = strtoupper($this->foo);
+ }
+
+ // this method will be called from __set() when property $what is set
+ protected function set_what(string $value){
+ $this->what = md5($value);
+ }
+}
+
+trait MoreOptions{
+ protected $bar = 'whatever'; // provide default values
+}
+```
+
+```php
+$commonOptions = [
+ // SomeOptions
+ 'foo' => 'whatever',
+ // MoreOptions
+ 'bar' => 'nothing',
+];
+
+// now plug the several library options together to a single object
+$container = new class ($commonOptions) extends SettingsContainerAbstract{
+ use SomeOptions, MoreOptions;
+};
+
+var_dump($container->foo); // -> WHATEVER (constructor ran strtoupper on the value)
+var_dump($container->bar); // -> nothing
+
+$container->what = 'some value';
+var_dump($container->what); // -> md5 hash of "some value"
+```
+
+### API
+
+#### [`SettingsContainerAbstract`](https://github.com/chillerlan/php-settings-container/blob/master/src/SettingsContainerAbstract.php)
+
+method | return | info
+-------- | ---- | -----------
+`__construct(iterable $properties = null)` | - | calls `construct()` internally after the properties have been set
+(protected) `construct()` | void | calls a method with trait name as replacement constructor for each used trait
+`__get(string $property)` | mixed | calls `$this->{'get_'.$property}()` if such a method exists
+`__set(string $property, $value)` | void | calls `$this->{'set_'.$property}($value)` if such a method exists
+`__isset(string $property)` | bool |
+`__unset(string $property)` | void |
+`__toString()` | string | a JSON string
+`toArray()` | array |
+`fromIterable(iterable $properties)` | `SettingsContainerInterface` |
+`toJSON(int $jsonOptions = null)` | string | accepts [JSON options constants](http://php.net/manual/json.constants.php)
+`fromJSON(string $json)` | `SettingsContainerInterface` |
+`jsonSerialize()` | mixed | implements the [`JsonSerializable`](https://www.php.net/manual/en/jsonserializable.jsonserialize.php) interface
+
+## Disclaimer
+This might be either an utterly genius or completely stupid idea - you decide. However, i like it and it works.
+Also, this is not a dependency injection container. Stop using DI containers FFS.
diff --git a/vendor/chillerlan/php-settings-container/composer.json b/vendor/chillerlan/php-settings-container/composer.json
new file mode 100644
index 000000000..4dc758665
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/composer.json
@@ -0,0 +1,40 @@
+{
+ "name": "chillerlan/php-settings-container",
+ "description": "A container class for immutable settings objects. Not a DI container. PHP 7.2+",
+ "homepage": "https://github.com/chillerlan/php-settings-container",
+ "license": "MIT",
+ "type": "library",
+ "minimum-stability": "stable",
+ "keywords": [
+ "php7", "helper", "container", "settings"
+ ],
+ "authors": [
+ {
+ "name": "Smiley",
+ "email": "smiley@chillerlan.net",
+ "homepage": "https://github.com/codemasher"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/chillerlan/php-settings-container/issues",
+ "source": "https://github.com/chillerlan/php-settings-container"
+ },
+ "require": {
+ "php": "^7.2",
+ "ext-json": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.3"
+ },
+ "autoload": {
+ "psr-4": {
+ "chillerlan\\Settings\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "chillerlan\\SettingsTest\\": "tests/",
+ "chillerlan\\SettingsExamples\\": "examples/"
+ }
+ }
+}
diff --git a/vendor/chillerlan/php-settings-container/examples/advanced.php b/vendor/chillerlan/php-settings-container/examples/advanced.php
new file mode 100644
index 000000000..1030b0a29
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/examples/advanced.php
@@ -0,0 +1,46 @@
+
+ * @copyright 2018 smiley
+ * @license MIT
+ */
+
+namespace chillerlan\SettingsExamples;
+
+use chillerlan\Settings\SettingsContainerAbstract;
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+// from library #1
+trait SomeOptions{
+ protected $foo;
+
+ // this method will be called in SettingsContainerAbstract::__construct() after the properties have been set
+ protected function SomeOptions(){
+ // just some constructor stuff...
+ $this->foo = strtoupper($this->foo);
+ }
+}
+
+// from library #2
+trait MoreOptions{
+ protected $bar = 'whatever'; // provide default values
+}
+
+$commonOptions = [
+ // SomeOptions
+ 'foo' => 'whatever',
+ // MoreOptions
+ 'bar' => 'nothing',
+];
+
+// now plug the several library options together to a single object
+/** @var \chillerlan\Settings\SettingsContainerInterface $container */
+$container = new class ($commonOptions) extends SettingsContainerAbstract{
+ use SomeOptions, MoreOptions; // ...
+};
+
+var_dump($container->foo); // -> WHATEVER (constructor ran strtoupper on the value)
+var_dump($container->bar); // -> nothing
diff --git a/vendor/chillerlan/php-settings-container/examples/simple.php b/vendor/chillerlan/php-settings-container/examples/simple.php
new file mode 100644
index 000000000..d8d81095b
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/examples/simple.php
@@ -0,0 +1,30 @@
+
+ * @copyright 2018 smiley
+ * @license MIT
+ */
+
+namespace chillerlan\SettingsExamples;
+
+use chillerlan\Settings\SettingsContainerAbstract;
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+class MyContainer extends SettingsContainerAbstract{
+ protected $foo;
+ protected $bar;
+}
+
+/** @var \chillerlan\Settings\SettingsContainerInterface $container */
+$container = new MyContainer(['foo' => 'what']);
+$container->bar = 'foo';
+
+var_dump($container->toJSON()); // -> {"foo":"what","bar":"foo"}
+
+// non-existing properties will be ignored:
+$container->nope = 'what';
+
+var_dump($container->nope); // -> NULL
diff --git a/vendor/chillerlan/php-settings-container/phpmd.xml b/vendor/chillerlan/php-settings-container/phpmd.xml
new file mode 100644
index 000000000..3ba7e11b7
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/phpmd.xml
@@ -0,0 +1,35 @@
+
+
+ codemasher/php-settings-container PMD ruleset
+ */examples/*
+ */tests/*
+ */vendor/*
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/chillerlan/php-settings-container/phpunit.xml b/vendor/chillerlan/php-settings-container/phpunit.xml
new file mode 100644
index 000000000..bb05d1289
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/phpunit.xml
@@ -0,0 +1,22 @@
+
+
+
+
+ ./src
+
+
+
+
+ ./tests/
+
+
+
diff --git a/vendor/chillerlan/php-settings-container/src/SettingsContainerAbstract.php b/vendor/chillerlan/php-settings-container/src/SettingsContainerAbstract.php
new file mode 100644
index 000000000..1ccc1a0e2
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/src/SettingsContainerAbstract.php
@@ -0,0 +1,172 @@
+
+ * @copyright 2018 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\Settings;
+
+use Exception, ReflectionClass, ReflectionProperty;
+
+use function call_user_func, call_user_func_array, get_object_vars, json_decode, json_encode, method_exists, property_exists;
+
+abstract class SettingsContainerAbstract implements SettingsContainerInterface{
+
+ /**
+ * SettingsContainerAbstract constructor.
+ *
+ * @param iterable|null $properties
+ */
+ public function __construct(iterable $properties = null){
+
+ if(!empty($properties)){
+ $this->fromIterable($properties);
+ }
+
+ $this->construct();
+ }
+
+ /**
+ * calls a method with trait name as replacement constructor for each used trait
+ * (remember pre-php5 classname constructors? yeah, basically this.)
+ *
+ * @return void
+ */
+ protected function construct():void{
+ $traits = (new ReflectionClass($this))->getTraits();
+
+ foreach($traits as $trait){
+ $method = $trait->getShortName();
+
+ if(method_exists($this, $method)){
+ call_user_func([$this, $method]);
+ }
+ }
+
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function __get(string $property){
+
+ if(property_exists($this, $property) && !$this->isPrivate($property)){
+
+ if(method_exists($this, 'get_'.$property)){
+ return call_user_func([$this, 'get_'.$property]);
+ }
+
+ return $this->{$property};
+ }
+
+ return null;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function __set(string $property, $value):void{
+
+ if(!property_exists($this, $property) || $this->isPrivate($property)){
+ return;
+ }
+
+ if(method_exists($this, 'set_'.$property)){
+ call_user_func_array([$this, 'set_'.$property], [$value]);
+
+ return;
+ }
+
+ $this->{$property} = $value;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function __isset(string $property):bool{
+ return isset($this->{$property}) && !$this->isPrivate($property);
+ }
+
+ /**
+ * @internal Checks if a property is private
+ *
+ * @param string $property
+ *
+ * @return bool
+ */
+ protected function isPrivate(string $property):bool{
+ return (new ReflectionProperty($this, $property))->isPrivate();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function __unset(string $property):void{
+
+ if($this->__isset($property)){
+ unset($this->{$property});
+ }
+
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function __toString():string{
+ return $this->toJSON();
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function toArray():array{
+ return get_object_vars($this);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function fromIterable(iterable $properties):SettingsContainerInterface{
+
+ foreach($properties as $key => $value){
+ $this->__set($key, $value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function toJSON(int $jsonOptions = null):string{
+ return json_encode($this, $jsonOptions ?? 0);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function fromJSON(string $json):SettingsContainerInterface{
+
+ $data = json_decode($json, true); // as of PHP 7.3: JSON_THROW_ON_ERROR
+
+ if($data === false || $data === null){
+ throw new Exception('error while decoding JSON');
+ }
+
+ return $this->fromIterable($data);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function jsonSerialize(){
+ return $this->toArray();
+ }
+
+}
diff --git a/vendor/chillerlan/php-settings-container/src/SettingsContainerInterface.php b/vendor/chillerlan/php-settings-container/src/SettingsContainerInterface.php
new file mode 100644
index 000000000..59cef6232
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/src/SettingsContainerInterface.php
@@ -0,0 +1,104 @@
+
+ * @copyright 2018 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\Settings;
+
+use JsonSerializable;
+
+/**
+ * a generic container with magic getter and setter
+ */
+interface SettingsContainerInterface extends JsonSerializable{
+
+ /**
+ * Retrieve the value of $property
+ *
+ * @param string $property
+ *
+ * @return mixed
+ */
+ public function __get(string $property);
+
+ /**
+ * Set $property to $value while avoiding private and non-existing properties
+ *
+ * @param string $property
+ * @param mixed $value
+ *
+ * @return void
+ */
+ public function __set(string $property, $value):void;
+
+ /**
+ * Checks if $property is set (aka. not null), excluding private properties
+ *
+ * @param string $property
+ *
+ * @return bool
+ */
+ public function __isset(string $property):bool;
+
+ /**
+ * Unsets $property while avoiding private and non-existing properties
+ *
+ * @param string $property
+ *
+ * @return void
+ */
+ public function __unset(string $property):void;
+
+ /**
+ * @see SettingsContainerInterface::toJSON()
+ *
+ * @return string
+ */
+ public function __toString():string;
+
+ /**
+ * Returns an array representation of the settings object
+ *
+ * @return array
+ */
+ public function toArray():array;
+
+ /**
+ * Sets properties from a given iterable
+ *
+ * @param iterable $properties
+ *
+ * @return \chillerlan\Settings\SettingsContainerInterface
+ */
+ public function fromIterable(iterable $properties):SettingsContainerInterface;
+
+ /**
+ * Returns a JSON representation of the settings object
+ * @see \json_encode()
+ *
+ * @param int|null $jsonOptions
+ *
+ * @return string
+ */
+ public function toJSON(int $jsonOptions = null):string;
+
+ /**
+ * Sets properties from a given JSON string
+ *
+ * @param string $json
+ *
+ * @return \chillerlan\Settings\SettingsContainerInterface
+ *
+ * @throws \Exception
+ * @throws \JsonException
+ */
+ public function fromJSON(string $json):SettingsContainerInterface;
+
+}
diff --git a/vendor/chillerlan/php-settings-container/tests/ContainerTest.php b/vendor/chillerlan/php-settings-container/tests/ContainerTest.php
new file mode 100644
index 000000000..ddae538f3
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/tests/ContainerTest.php
@@ -0,0 +1,105 @@
+
+ * @copyright 2018 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\SettingsTest;
+
+use PHPUnit\Framework\TestCase;
+use Exception, TypeError;
+
+class ContainerTraitTest extends TestCase{
+
+ public function testConstruct(){
+ $container = new TestContainer([
+ 'test1' => 'test1',
+ 'test2' => 'test2',
+ 'test3' => 'test3',
+ 'test4' => 'test4',
+ ]);
+
+ $this->assertSame('test1', $container->test1);
+ $this->assertSame('test2', $container->test2);
+ $this->assertNull($container->test3);
+ $this->assertSame('test4', $container->test4);
+
+ $this->assertSame('success', $container->testConstruct);
+ }
+
+ public function testGet(){
+ $container = new TestContainer;
+
+ $this->assertSame('foo', $container->test1);
+ $this->assertNull($container->test2);
+ $this->assertNull($container->test3);
+ $this->assertNull($container->test4);
+ $this->assertNull($container->foo);
+
+ // isset test
+ $this->assertTrue(isset($container->test1));
+ $this->assertFalse(isset($container->test2));
+ $this->assertFalse(isset($container->test3));
+ $this->assertFalse(isset($container->test4));
+ $this->assertFalse(isset($container->foo));
+
+ // custom getter
+ $container->test6 = 'foo';
+ $this->assertSame(sha1('foo'), $container->test6);
+ // nullable/isset test
+ $container->test6 = null;
+ $this->assertFalse(isset($container->test6));
+ $this->assertSame('null', $container->test6);
+ }
+
+ public function testSet(){
+ $container = new TestContainer;
+ $container->test1 = 'bar';
+ $container->test2 = 'what';
+ $container->test3 = 'nope';
+
+ $this->assertSame('bar', $container->test1);
+ $this->assertSame('what', $container->test2);
+ $this->assertNull($container->test3);
+
+ // unset
+ unset($container->test1);
+ $this->assertFalse(isset($container->test1));
+
+ // custom setter
+ $container->test5 = 'bar';
+ $this->assertSame('bar_test5', $container->test5);
+ }
+
+ public function testToArray(){
+ $container = new TestContainer(['test1' => 'no', 'test2' => true, 'testConstruct' => 'success']);
+
+ $this->assertSame(['test1' => 'no', 'test2' => true, 'testConstruct' => 'success', 'test4' => null, 'test5' => null, 'test6' => null], $container->toArray());
+ }
+
+ public function testToJSON(){
+ $container = (new TestContainer)->fromJSON('{"test1":"no","test2":true,"testConstruct":"success"}');
+
+ $expected = '{"test1":"no","test2":true,"testConstruct":"success","test4":null,"test5":null,"test6":null}';
+
+ $this->assertSame($expected, $container->toJSON());
+ $this->assertSame($expected, (string)$container);
+ }
+
+ public function testFromJsonException(){
+ $this->expectException(Exception::class);
+ (new TestContainer)->fromJSON('-');
+
+ }
+ public function testFromJsonTypeError(){
+ $this->expectException(TypeError::class);
+ (new TestContainer)->fromJSON('2');
+ }
+
+}
diff --git a/vendor/chillerlan/php-settings-container/tests/TestContainer.php b/vendor/chillerlan/php-settings-container/tests/TestContainer.php
new file mode 100644
index 000000000..a35f75277
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/tests/TestContainer.php
@@ -0,0 +1,29 @@
+
+ * @copyright 2018 Smiley
+ * @license MIT
+ */
+
+namespace chillerlan\SettingsTest;
+
+use chillerlan\Settings\SettingsContainerAbstract;
+
+/**
+ * @property $test1
+ * @property $test2
+ * @property $test3
+ * @property $test4
+ * @property $test5
+ * @property $test6
+ */
+class TestContainer extends SettingsContainerAbstract{
+ use TestOptionsTrait;
+
+ private $test3 = 'what';
+}
diff --git a/vendor/chillerlan/php-settings-container/tests/TestOptionsTrait.php b/vendor/chillerlan/php-settings-container/tests/TestOptionsTrait.php
new file mode 100644
index 000000000..261f533ac
--- /dev/null
+++ b/vendor/chillerlan/php-settings-container/tests/TestOptionsTrait.php
@@ -0,0 +1,42 @@
+
+ * @copyright 2018 smiley
+ * @license MIT
+ */
+
+namespace chillerlan\SettingsTest;
+
+trait TestOptionsTrait{
+
+ protected $test1 = 'foo';
+
+ protected $test2;
+
+ protected $testConstruct;
+
+ protected $test4;
+
+ protected $test5;
+
+ protected $test6;
+
+ protected function TestOptionsTrait(){
+ $this->testConstruct = 'success';
+ }
+
+ protected function set_test5($value){
+ $this->test5 = $value.'_test5';
+ }
+
+ protected function get_test6(){
+ return $this->test6 === null
+ ? 'null'
+ : sha1($this->test6);
+ }
+}
diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php
new file mode 100644
index 000000000..247294d66
--- /dev/null
+++ b/vendor/composer/ClassLoader.php
@@ -0,0 +1,479 @@
+
+ * Jordi Boggiano
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier
+ * @author Jordi Boggiano
+ * @see https://www.php-fig.org/psr/psr-0/
+ * @see https://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ private $vendorDir;
+
+ // PSR-4
+ private $prefixLengthsPsr4 = array();
+ private $prefixDirsPsr4 = array();
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ private $prefixesPsr0 = array();
+ private $fallbackDirsPsr0 = array();
+
+ private $useIncludePath = false;
+ private $classMap = array();
+ private $classMapAuthoritative = false;
+ private $missingClasses = array();
+ private $apcuPrefix;
+
+ private static $registeredLoaders = array();
+
+ public function __construct($vendorDir = null)
+ {
+ $this->vendorDir = $vendorDir;
+ }
+
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
+ }
+
+ return array();
+ }
+
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array $classMap Class to filename map
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ (array) $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ (array) $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 base directories
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+
+ if (null === $this->vendorDir) {
+ return;
+ }
+
+ if ($prepend) {
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
+ } else {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ self::$registeredLoaders[$this->vendorDir] = $this;
+ }
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+
+ if (null !== $this->vendorDir) {
+ unset(self::$registeredLoaders[$this->vendorDir]);
+ }
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return bool|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ includeFile($file);
+
+ return true;
+ }
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ /**
+ * Returns the currently registered loaders indexed by their corresponding vendor directories.
+ *
+ * @return self[]
+ */
+ public static function getRegisteredLoaders()
+ {
+ return self::$registeredLoaders;
+ }
+
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath . '\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+
+ return false;
+ }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+ include $file;
+}
diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php
new file mode 100644
index 000000000..e23c30693
--- /dev/null
+++ b/vendor/composer/InstalledVersions.php
@@ -0,0 +1,337 @@
+
+ array (
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'bc4475b6698f5a74e475674aa7af43253c459892',
+ 'name' => '__root__',
+ ),
+ 'versions' =>
+ array (
+ '__root__' =>
+ array (
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'bc4475b6698f5a74e475674aa7af43253c459892',
+ ),
+ 'beberlei/assert' =>
+ array (
+ 'pretty_version' => 'v3.2.7',
+ 'version' => '3.2.7.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'd63a6943fc4fd1a2aedb65994e3548715105abcf',
+ ),
+ 'chillerlan/php-qrcode' =>
+ array (
+ 'pretty_version' => '3.4.0',
+ 'version' => '3.4.0.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'd8bf297e6843a53aeaa8f3285ce04fc349d133d6',
+ ),
+ 'chillerlan/php-settings-container' =>
+ array (
+ 'pretty_version' => '1.2.1',
+ 'version' => '1.2.1.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'b9b0431dffd74102ee92348a63b4c33fc8ba639b',
+ ),
+ 'paragonie/constant_time_encoding' =>
+ array (
+ 'pretty_version' => 'v2.4.0',
+ 'version' => '2.4.0.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c',
+ ),
+ 'spomky-labs/otphp' =>
+ array (
+ 'pretty_version' => 'v10.0.1',
+ 'version' => '10.0.1.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'f44cce5a9db4b8da410215d992110482c931232f',
+ ),
+ 'thecodingmachine/safe' =>
+ array (
+ 'pretty_version' => 'v1.3.3',
+ 'version' => '1.3.3.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'a8ab0876305a4cdaef31b2350fcb9811b5608dbc',
+ ),
+ ),
+);
+private static $canGetVendors;
+private static $installedByVendor = array();
+
+
+
+
+
+
+
+public static function getInstalledPackages()
+{
+$packages = array();
+foreach (self::getInstalled() as $installed) {
+$packages[] = array_keys($installed['versions']);
+}
+
+
+if (1 === \count($packages)) {
+return $packages[0];
+}
+
+return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
+}
+
+
+
+
+
+
+
+
+
+public static function isInstalled($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (isset($installed['versions'][$packageName])) {
+return true;
+}
+}
+
+return false;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+public static function satisfies(VersionParser $parser, $packageName, $constraint)
+{
+$constraint = $parser->parseConstraints($constraint);
+$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
+
+return $provided->matches($constraint);
+}
+
+
+
+
+
+
+
+
+
+
+public static function getVersionRanges($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (!isset($installed['versions'][$packageName])) {
+continue;
+}
+
+$ranges = array();
+if (isset($installed['versions'][$packageName]['pretty_version'])) {
+$ranges[] = $installed['versions'][$packageName]['pretty_version'];
+}
+if (array_key_exists('aliases', $installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
+}
+if (array_key_exists('replaced', $installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
+}
+if (array_key_exists('provided', $installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
+}
+
+return implode(' || ', $ranges);
+}
+
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+
+
+
+
+public static function getVersion($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (!isset($installed['versions'][$packageName])) {
+continue;
+}
+
+if (!isset($installed['versions'][$packageName]['version'])) {
+return null;
+}
+
+return $installed['versions'][$packageName]['version'];
+}
+
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+
+
+
+
+public static function getPrettyVersion($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (!isset($installed['versions'][$packageName])) {
+continue;
+}
+
+if (!isset($installed['versions'][$packageName]['pretty_version'])) {
+return null;
+}
+
+return $installed['versions'][$packageName]['pretty_version'];
+}
+
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+
+
+
+
+public static function getReference($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (!isset($installed['versions'][$packageName])) {
+continue;
+}
+
+if (!isset($installed['versions'][$packageName]['reference'])) {
+return null;
+}
+
+return $installed['versions'][$packageName]['reference'];
+}
+
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+
+
+
+
+public static function getRootPackage()
+{
+$installed = self::getInstalled();
+
+return $installed[0]['root'];
+}
+
+
+
+
+
+
+
+public static function getRawData()
+{
+return self::$installed;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+public static function reload($data)
+{
+self::$installed = $data;
+self::$installedByVendor = array();
+}
+
+
+
+
+private static function getInstalled()
+{
+if (null === self::$canGetVendors) {
+self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
+}
+
+$installed = array();
+
+if (self::$canGetVendors) {
+foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
+if (isset(self::$installedByVendor[$vendorDir])) {
+$installed[] = self::$installedByVendor[$vendorDir];
+} elseif (is_file($vendorDir.'/composer/installed.php')) {
+$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
+}
+}
+}
+
+$installed[] = self::$installed;
+
+return $installed;
+}
+}
diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE
new file mode 100644
index 000000000..f27399a04
--- /dev/null
+++ b/vendor/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
new file mode 100644
index 000000000..b26f1b13b
--- /dev/null
+++ b/vendor/composer/autoload_classmap.php
@@ -0,0 +1,10 @@
+ $vendorDir . '/composer/InstalledVersions.php',
+);
diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php
new file mode 100644
index 000000000..a2686669c
--- /dev/null
+++ b/vendor/composer/autoload_files.php
@@ -0,0 +1,99 @@
+ $vendorDir . '/beberlei/assert/lib/Assert/functions.php',
+ '51fcf4e06c07cc00c920b44bcd900e7a' => $vendorDir . '/thecodingmachine/safe/deprecated/apc.php',
+ '47f619d9197b36cf5ab70738d7743fe2' => $vendorDir . '/thecodingmachine/safe/deprecated/libevent.php',
+ 'ea6bb8a12ef9b68f6ada99058e530760' => $vendorDir . '/thecodingmachine/safe/deprecated/mssql.php',
+ '9a29089eb3ce41a446744c68a00f118c' => $vendorDir . '/thecodingmachine/safe/deprecated/stats.php',
+ '72243e5536b63e298acb6476f01f1aff' => $vendorDir . '/thecodingmachine/safe/lib/special_cases.php',
+ '3f648889e687f31c52f949ba8a9d0873' => $vendorDir . '/thecodingmachine/safe/generated/apache.php',
+ 'eeb4581d958421a4244aaa4167c6a575' => $vendorDir . '/thecodingmachine/safe/generated/apcu.php',
+ '04cb0b3c1dac5b5ddb23c14e3d66dbe9' => $vendorDir . '/thecodingmachine/safe/generated/array.php',
+ '450b332a74a9a21e043c5e953485a791' => $vendorDir . '/thecodingmachine/safe/generated/bzip2.php',
+ '6e9b7954ecfd7cbb9ca239319d1acdb6' => $vendorDir . '/thecodingmachine/safe/generated/calendar.php',
+ '2c6d7e8bd2de9a272a9d4d43b0a4304a' => $vendorDir . '/thecodingmachine/safe/generated/classobj.php',
+ '0b8231c1ad0865447c988a4c16b4001f' => $vendorDir . '/thecodingmachine/safe/generated/com.php',
+ '7643a71fe1c3256058c8fee234cb86e5' => $vendorDir . '/thecodingmachine/safe/generated/cubrid.php',
+ '68e1365710575942efc1d55000032cee' => $vendorDir . '/thecodingmachine/safe/generated/curl.php',
+ '02fd26bca803106c5b942a7197c3ad8b' => $vendorDir . '/thecodingmachine/safe/generated/datetime.php',
+ 'f4817dcbd956cd221b1c31f6fbd5749c' => $vendorDir . '/thecodingmachine/safe/generated/dir.php',
+ '51c3f2d10ca61a70dbcea0e38d8e902d' => $vendorDir . '/thecodingmachine/safe/generated/eio.php',
+ '1d34f34327ca3e81535963016e3be2c3' => $vendorDir . '/thecodingmachine/safe/generated/errorfunc.php',
+ '4fd0ba2d3717b0424d474bebfdafa2b4' => $vendorDir . '/thecodingmachine/safe/generated/exec.php',
+ '98f4dae054bc7fb19c13be14935cbdd3' => $vendorDir . '/thecodingmachine/safe/generated/fileinfo.php',
+ '5530ae063ba88323eaf0a07904efdf85' => $vendorDir . '/thecodingmachine/safe/generated/filesystem.php',
+ '633f4f134975d70e97bddad83348e91a' => $vendorDir . '/thecodingmachine/safe/generated/filter.php',
+ 'fbd163fc68c5faf73d5ed4002ffd836d' => $vendorDir . '/thecodingmachine/safe/generated/fpm.php',
+ '21b511999d61411fab0692ff8795bbed' => $vendorDir . '/thecodingmachine/safe/generated/ftp.php',
+ '85fbd73fc92365cd90526b0ea03cae3a' => $vendorDir . '/thecodingmachine/safe/generated/funchand.php',
+ '51df9c146e0b7dcbdf358d8abd24dbdc' => $vendorDir . '/thecodingmachine/safe/generated/gmp.php',
+ '93bb7fe678d7dcfb1322f8e3475a48b0' => $vendorDir . '/thecodingmachine/safe/generated/gnupg.php',
+ 'c171ba99cf316379ff66468392bf4950' => $vendorDir . '/thecodingmachine/safe/generated/hash.php',
+ '5ab4aad4c28e468209fbfcceb2e5e6a5' => $vendorDir . '/thecodingmachine/safe/generated/ibase.php',
+ '4d57409c5e8e576b0c64c08d9d731cfb' => $vendorDir . '/thecodingmachine/safe/generated/ibmDb2.php',
+ 'eeb246d5403972a9d62106e4a4883496' => $vendorDir . '/thecodingmachine/safe/generated/iconv.php',
+ 'c28a05f498c01b810a714f7214b7a8da' => $vendorDir . '/thecodingmachine/safe/generated/image.php',
+ '8063cd92acdf00fd978b5599eb7cc142' => $vendorDir . '/thecodingmachine/safe/generated/imap.php',
+ '8bd26dbe768e9c9599edad7b198e5446' => $vendorDir . '/thecodingmachine/safe/generated/info.php',
+ '0c577fe603b029d4b65c84376b15dbd5' => $vendorDir . '/thecodingmachine/safe/generated/ingres-ii.php',
+ 'd4362910bde43c0f956b52527effd7d4' => $vendorDir . '/thecodingmachine/safe/generated/inotify.php',
+ '696ba49197d9b55f0428a12bb5a818e1' => $vendorDir . '/thecodingmachine/safe/generated/json.php',
+ '9818aaa99c8647c63f8ef62b7a368160' => $vendorDir . '/thecodingmachine/safe/generated/ldap.php',
+ 'bcf523ff2a195eb08e0fbb668ed784d0' => $vendorDir . '/thecodingmachine/safe/generated/libxml.php',
+ '68be68a9a8b95bb56cab6109ff03bc88' => $vendorDir . '/thecodingmachine/safe/generated/lzf.php',
+ 'bdca804bb0904ea9f53f328dfc0bb8a5' => $vendorDir . '/thecodingmachine/safe/generated/mailparse.php',
+ 'b0a3fcac3eaf55445796d6af26b89366' => $vendorDir . '/thecodingmachine/safe/generated/mbstring.php',
+ '98de16b8db03eb0cb4d318b4402215a6' => $vendorDir . '/thecodingmachine/safe/generated/misc.php',
+ 'c112440003b56e243b192c11fa9d836e' => $vendorDir . '/thecodingmachine/safe/generated/msql.php',
+ '7cefd81607cd21b8b3a15656eb6465f5' => $vendorDir . '/thecodingmachine/safe/generated/mysql.php',
+ 'aaf438b080089c6d0686679cd34aa72e' => $vendorDir . '/thecodingmachine/safe/generated/mysqli.php',
+ 'df0ef890e9afbf95f3924feb1c7a89f3' => $vendorDir . '/thecodingmachine/safe/generated/mysqlndMs.php',
+ 'db595fee5972867e45c5327010d78735' => $vendorDir . '/thecodingmachine/safe/generated/mysqlndQc.php',
+ 'cbac956836b72483dcff1ac39d5c0a0f' => $vendorDir . '/thecodingmachine/safe/generated/network.php',
+ '6c8f89dfbdc117d7871f572269363f25' => $vendorDir . '/thecodingmachine/safe/generated/oci8.php',
+ '169a669966a45c06bf55ed029122729b' => $vendorDir . '/thecodingmachine/safe/generated/opcache.php',
+ 'def61bf4fecd4d4bca7354919cd69302' => $vendorDir . '/thecodingmachine/safe/generated/openssl.php',
+ '26bb010649a6d32d4120181458aa6ef2' => $vendorDir . '/thecodingmachine/safe/generated/outcontrol.php',
+ '1212c201fe43c7492a085b2c71505e0f' => $vendorDir . '/thecodingmachine/safe/generated/password.php',
+ '002ebcb842e2c0d5b7f67fe64cc93158' => $vendorDir . '/thecodingmachine/safe/generated/pcntl.php',
+ '86df38612982dade72c7085ce7eca81f' => $vendorDir . '/thecodingmachine/safe/generated/pcre.php',
+ '1cacc3e65f82a473fbd5507c7ce4385d' => $vendorDir . '/thecodingmachine/safe/generated/pdf.php',
+ '1fc22f445c69ea8706e82fce301c0831' => $vendorDir . '/thecodingmachine/safe/generated/pgsql.php',
+ 'c70b42561584f7144bff38cd63c4eef3' => $vendorDir . '/thecodingmachine/safe/generated/posix.php',
+ '9923214639c32ca5173db03a177d3b63' => $vendorDir . '/thecodingmachine/safe/generated/ps.php',
+ '7e9c3f8eae2b5bf42205c4f1295cb7a7' => $vendorDir . '/thecodingmachine/safe/generated/pspell.php',
+ '91aa91f6245c349c2e2e88bd0025f199' => $vendorDir . '/thecodingmachine/safe/generated/readline.php',
+ 'd43773cacb9e5e8e897aa255e32007d1' => $vendorDir . '/thecodingmachine/safe/generated/rpminfo.php',
+ 'f053a3849e9e8383762b34b91db0320b' => $vendorDir . '/thecodingmachine/safe/generated/rrd.php',
+ '775b964f72f827a1bf87c65ab5b10800' => $vendorDir . '/thecodingmachine/safe/generated/sem.php',
+ '816428bd69c29ab5e1ed622af5dca0cd' => $vendorDir . '/thecodingmachine/safe/generated/session.php',
+ '5093e233bedbefaef0df262bfbab0a5c' => $vendorDir . '/thecodingmachine/safe/generated/shmop.php',
+ '01352920b0151f17e671266e44b52536' => $vendorDir . '/thecodingmachine/safe/generated/simplexml.php',
+ 'b080617b1d949683c2e37f8f01dc0e15' => $vendorDir . '/thecodingmachine/safe/generated/sockets.php',
+ '2708aa182ddcfe6ce27c96acaaa40f69' => $vendorDir . '/thecodingmachine/safe/generated/sodium.php',
+ 'f1b96cb260a5baeea9a7285cda82a1ec' => $vendorDir . '/thecodingmachine/safe/generated/solr.php',
+ '3fd8853757d0fe3557c179efb807afeb' => $vendorDir . '/thecodingmachine/safe/generated/spl.php',
+ '9312ce96a51c846913fcda5f186d58dd' => $vendorDir . '/thecodingmachine/safe/generated/sqlsrv.php',
+ 'd3eb383ad0b8b962b29dc4afd29d6715' => $vendorDir . '/thecodingmachine/safe/generated/ssdeep.php',
+ '42a09bc448f441a0b9f9367ea975c0bf' => $vendorDir . '/thecodingmachine/safe/generated/ssh2.php',
+ 'ef711077d356d1b33ca0b10b67b0be8f' => $vendorDir . '/thecodingmachine/safe/generated/stream.php',
+ '764b09f6df081cbb2807b97c6ace3866' => $vendorDir . '/thecodingmachine/safe/generated/strings.php',
+ 'ef241678769fee4a44aaa288f3b78aa1' => $vendorDir . '/thecodingmachine/safe/generated/swoole.php',
+ '0efc8f6778cba932b9e2a89e28de2452' => $vendorDir . '/thecodingmachine/safe/generated/uodbc.php',
+ 'd383d32907b98af53ee9208c62204fd0' => $vendorDir . '/thecodingmachine/safe/generated/uopz.php',
+ '2fd2e4060f7fe772660f002ce38f0b71' => $vendorDir . '/thecodingmachine/safe/generated/url.php',
+ '782249e03deebeaf57b9991ff5493aa0' => $vendorDir . '/thecodingmachine/safe/generated/var.php',
+ '344440cd1cd7200fdb4f12af0d3c587f' => $vendorDir . '/thecodingmachine/safe/generated/xdiff.php',
+ '3599f369219c658a5fb6c4fe66832f62' => $vendorDir . '/thecodingmachine/safe/generated/xml.php',
+ '7fcd313da9fae337051b091b3492c21b' => $vendorDir . '/thecodingmachine/safe/generated/xmlrpc.php',
+ 'd668c74cfa92d893b582356733d9a80e' => $vendorDir . '/thecodingmachine/safe/generated/yaml.php',
+ '4af1dca6db8c527c6eed27bff85ff0e5' => $vendorDir . '/thecodingmachine/safe/generated/yaz.php',
+ 'fe43ca06499ac37bc2dedd823af71eb5' => $vendorDir . '/thecodingmachine/safe/generated/zip.php',
+ '356736db98a6834f0a886b8d509b0ecd' => $vendorDir . '/thecodingmachine/safe/generated/zlib.php',
+);
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
new file mode 100644
index 000000000..b7fc0125d
--- /dev/null
+++ b/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,9 @@
+ array($vendorDir . '/chillerlan/php-settings-container/src'),
+ 'chillerlan\\QRCode\\' => array($vendorDir . '/chillerlan/php-qrcode/src'),
+ 'Safe\\' => array($vendorDir . '/thecodingmachine/safe/lib', $vendorDir . '/thecodingmachine/safe/deprecated', $vendorDir . '/thecodingmachine/safe/generated'),
+ 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'),
+ 'OTPHP\\' => array($vendorDir . '/spomky-labs/otphp/src'),
+ 'Assert\\' => array($vendorDir . '/beberlei/assert/lib/Assert'),
+);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
new file mode 100644
index 000000000..34b3b7ad0
--- /dev/null
+++ b/vendor/composer/autoload_real.php
@@ -0,0 +1,75 @@
+= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
+ if ($useStaticLoader) {
+ require __DIR__ . '/autoload_static.php';
+
+ call_user_func(\Composer\Autoload\ComposerStaticInit19fc2ff1c0f9a92279c7979386bb2056::getInitializer($loader));
+ } else {
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
+
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
+
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
+ }
+ }
+
+ $loader->register(true);
+
+ if ($useStaticLoader) {
+ $includeFiles = Composer\Autoload\ComposerStaticInit19fc2ff1c0f9a92279c7979386bb2056::$files;
+ } else {
+ $includeFiles = require __DIR__ . '/autoload_files.php';
+ }
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequire19fc2ff1c0f9a92279c7979386bb2056($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
+
+function composerRequire19fc2ff1c0f9a92279c7979386bb2056($fileIdentifier, $file)
+{
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ require $file;
+
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+ }
+}
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
new file mode 100644
index 000000000..ac3554d3f
--- /dev/null
+++ b/vendor/composer/autoload_static.php
@@ -0,0 +1,168 @@
+ __DIR__ . '/..' . '/beberlei/assert/lib/Assert/functions.php',
+ '51fcf4e06c07cc00c920b44bcd900e7a' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/apc.php',
+ '47f619d9197b36cf5ab70738d7743fe2' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/libevent.php',
+ 'ea6bb8a12ef9b68f6ada99058e530760' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/mssql.php',
+ '9a29089eb3ce41a446744c68a00f118c' => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated/stats.php',
+ '72243e5536b63e298acb6476f01f1aff' => __DIR__ . '/..' . '/thecodingmachine/safe/lib/special_cases.php',
+ '3f648889e687f31c52f949ba8a9d0873' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/apache.php',
+ 'eeb4581d958421a4244aaa4167c6a575' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/apcu.php',
+ '04cb0b3c1dac5b5ddb23c14e3d66dbe9' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/array.php',
+ '450b332a74a9a21e043c5e953485a791' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/bzip2.php',
+ '6e9b7954ecfd7cbb9ca239319d1acdb6' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/calendar.php',
+ '2c6d7e8bd2de9a272a9d4d43b0a4304a' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/classobj.php',
+ '0b8231c1ad0865447c988a4c16b4001f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/com.php',
+ '7643a71fe1c3256058c8fee234cb86e5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/cubrid.php',
+ '68e1365710575942efc1d55000032cee' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/curl.php',
+ '02fd26bca803106c5b942a7197c3ad8b' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/datetime.php',
+ 'f4817dcbd956cd221b1c31f6fbd5749c' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/dir.php',
+ '51c3f2d10ca61a70dbcea0e38d8e902d' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/eio.php',
+ '1d34f34327ca3e81535963016e3be2c3' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/errorfunc.php',
+ '4fd0ba2d3717b0424d474bebfdafa2b4' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/exec.php',
+ '98f4dae054bc7fb19c13be14935cbdd3' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/fileinfo.php',
+ '5530ae063ba88323eaf0a07904efdf85' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/filesystem.php',
+ '633f4f134975d70e97bddad83348e91a' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/filter.php',
+ 'fbd163fc68c5faf73d5ed4002ffd836d' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/fpm.php',
+ '21b511999d61411fab0692ff8795bbed' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ftp.php',
+ '85fbd73fc92365cd90526b0ea03cae3a' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/funchand.php',
+ '51df9c146e0b7dcbdf358d8abd24dbdc' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/gmp.php',
+ '93bb7fe678d7dcfb1322f8e3475a48b0' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/gnupg.php',
+ 'c171ba99cf316379ff66468392bf4950' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/hash.php',
+ '5ab4aad4c28e468209fbfcceb2e5e6a5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ibase.php',
+ '4d57409c5e8e576b0c64c08d9d731cfb' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ibmDb2.php',
+ 'eeb246d5403972a9d62106e4a4883496' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/iconv.php',
+ 'c28a05f498c01b810a714f7214b7a8da' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/image.php',
+ '8063cd92acdf00fd978b5599eb7cc142' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/imap.php',
+ '8bd26dbe768e9c9599edad7b198e5446' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/info.php',
+ '0c577fe603b029d4b65c84376b15dbd5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ingres-ii.php',
+ 'd4362910bde43c0f956b52527effd7d4' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/inotify.php',
+ '696ba49197d9b55f0428a12bb5a818e1' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/json.php',
+ '9818aaa99c8647c63f8ef62b7a368160' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ldap.php',
+ 'bcf523ff2a195eb08e0fbb668ed784d0' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/libxml.php',
+ '68be68a9a8b95bb56cab6109ff03bc88' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/lzf.php',
+ 'bdca804bb0904ea9f53f328dfc0bb8a5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/mailparse.php',
+ 'b0a3fcac3eaf55445796d6af26b89366' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/mbstring.php',
+ '98de16b8db03eb0cb4d318b4402215a6' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/misc.php',
+ 'c112440003b56e243b192c11fa9d836e' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/msql.php',
+ '7cefd81607cd21b8b3a15656eb6465f5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/mysql.php',
+ 'aaf438b080089c6d0686679cd34aa72e' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/mysqli.php',
+ 'df0ef890e9afbf95f3924feb1c7a89f3' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/mysqlndMs.php',
+ 'db595fee5972867e45c5327010d78735' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/mysqlndQc.php',
+ 'cbac956836b72483dcff1ac39d5c0a0f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/network.php',
+ '6c8f89dfbdc117d7871f572269363f25' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/oci8.php',
+ '169a669966a45c06bf55ed029122729b' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/opcache.php',
+ 'def61bf4fecd4d4bca7354919cd69302' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/openssl.php',
+ '26bb010649a6d32d4120181458aa6ef2' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/outcontrol.php',
+ '1212c201fe43c7492a085b2c71505e0f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/password.php',
+ '002ebcb842e2c0d5b7f67fe64cc93158' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/pcntl.php',
+ '86df38612982dade72c7085ce7eca81f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/pcre.php',
+ '1cacc3e65f82a473fbd5507c7ce4385d' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/pdf.php',
+ '1fc22f445c69ea8706e82fce301c0831' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/pgsql.php',
+ 'c70b42561584f7144bff38cd63c4eef3' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/posix.php',
+ '9923214639c32ca5173db03a177d3b63' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ps.php',
+ '7e9c3f8eae2b5bf42205c4f1295cb7a7' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/pspell.php',
+ '91aa91f6245c349c2e2e88bd0025f199' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/readline.php',
+ 'd43773cacb9e5e8e897aa255e32007d1' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/rpminfo.php',
+ 'f053a3849e9e8383762b34b91db0320b' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/rrd.php',
+ '775b964f72f827a1bf87c65ab5b10800' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/sem.php',
+ '816428bd69c29ab5e1ed622af5dca0cd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/session.php',
+ '5093e233bedbefaef0df262bfbab0a5c' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/shmop.php',
+ '01352920b0151f17e671266e44b52536' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/simplexml.php',
+ 'b080617b1d949683c2e37f8f01dc0e15' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/sockets.php',
+ '2708aa182ddcfe6ce27c96acaaa40f69' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/sodium.php',
+ 'f1b96cb260a5baeea9a7285cda82a1ec' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/solr.php',
+ '3fd8853757d0fe3557c179efb807afeb' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/spl.php',
+ '9312ce96a51c846913fcda5f186d58dd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/sqlsrv.php',
+ 'd3eb383ad0b8b962b29dc4afd29d6715' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ssdeep.php',
+ '42a09bc448f441a0b9f9367ea975c0bf' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/ssh2.php',
+ 'ef711077d356d1b33ca0b10b67b0be8f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/stream.php',
+ '764b09f6df081cbb2807b97c6ace3866' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/strings.php',
+ 'ef241678769fee4a44aaa288f3b78aa1' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/swoole.php',
+ '0efc8f6778cba932b9e2a89e28de2452' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/uodbc.php',
+ 'd383d32907b98af53ee9208c62204fd0' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/uopz.php',
+ '2fd2e4060f7fe772660f002ce38f0b71' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/url.php',
+ '782249e03deebeaf57b9991ff5493aa0' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/var.php',
+ '344440cd1cd7200fdb4f12af0d3c587f' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/xdiff.php',
+ '3599f369219c658a5fb6c4fe66832f62' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/xml.php',
+ '7fcd313da9fae337051b091b3492c21b' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/xmlrpc.php',
+ 'd668c74cfa92d893b582356733d9a80e' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/yaml.php',
+ '4af1dca6db8c527c6eed27bff85ff0e5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/yaz.php',
+ 'fe43ca06499ac37bc2dedd823af71eb5' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zip.php',
+ '356736db98a6834f0a886b8d509b0ecd' => __DIR__ . '/..' . '/thecodingmachine/safe/generated/zlib.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 'c' =>
+ array (
+ 'chillerlan\\Settings\\' => 20,
+ 'chillerlan\\QRCode\\' => 18,
+ ),
+ 'S' =>
+ array (
+ 'Safe\\' => 5,
+ ),
+ 'P' =>
+ array (
+ 'ParagonIE\\ConstantTime\\' => 23,
+ ),
+ 'O' =>
+ array (
+ 'OTPHP\\' => 6,
+ ),
+ 'A' =>
+ array (
+ 'Assert\\' => 7,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'chillerlan\\Settings\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/chillerlan/php-settings-container/src',
+ ),
+ 'chillerlan\\QRCode\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/chillerlan/php-qrcode/src',
+ ),
+ 'Safe\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/thecodingmachine/safe/lib',
+ 1 => __DIR__ . '/..' . '/thecodingmachine/safe/deprecated',
+ 2 => __DIR__ . '/..' . '/thecodingmachine/safe/generated',
+ ),
+ 'ParagonIE\\ConstantTime\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src',
+ ),
+ 'OTPHP\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/spomky-labs/otphp/src',
+ ),
+ 'Assert\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/beberlei/assert/lib/Assert',
+ ),
+ );
+
+ public static $classMap = array (
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInit19fc2ff1c0f9a92279c7979386bb2056::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit19fc2ff1c0f9a92279c7979386bb2056::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInit19fc2ff1c0f9a92279c7979386bb2056::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
new file mode 100644
index 000000000..086e5d4a4
--- /dev/null
+++ b/vendor/composer/installed.json
@@ -0,0 +1,500 @@
+{
+ "packages": [
+ {
+ "name": "beberlei/assert",
+ "version": "v3.2.7",
+ "version_normalized": "3.2.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/beberlei/assert.git",
+ "reference": "d63a6943fc4fd1a2aedb65994e3548715105abcf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/beberlei/assert/zipball/d63a6943fc4fd1a2aedb65994e3548715105abcf",
+ "reference": "d63a6943fc4fd1a2aedb65994e3548715105abcf",
+ "shasum": ""
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "ext-simplexml": "*",
+ "php": "^7"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "*",
+ "phpstan/phpstan-shim": "*",
+ "phpunit/phpunit": ">=6.0.0 <8"
+ },
+ "suggest": {
+ "ext-intl": "Needed to allow Assertion::count(), Assertion::isCountable(), Assertion::minCount(), and Assertion::maxCount() to operate on ResourceBundles"
+ },
+ "time": "2019-12-19T17:51:41+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Assert\\": "lib/Assert"
+ },
+ "files": [
+ "lib/Assert/functions.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Richard Quadling",
+ "email": "rquadling@gmail.com",
+ "role": "Collaborator"
+ }
+ ],
+ "description": "Thin assertion library for input validation in business models.",
+ "keywords": [
+ "assert",
+ "assertion",
+ "validation"
+ ],
+ "support": {
+ "issues": "https://github.com/beberlei/assert/issues",
+ "source": "https://github.com/beberlei/assert/tree/v3"
+ },
+ "install-path": "../beberlei/assert"
+ },
+ {
+ "name": "chillerlan/php-qrcode",
+ "version": "3.4.0",
+ "version_normalized": "3.4.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/chillerlan/php-qrcode.git",
+ "reference": "d8bf297e6843a53aeaa8f3285ce04fc349d133d6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/d8bf297e6843a53aeaa8f3285ce04fc349d133d6",
+ "reference": "d8bf297e6843a53aeaa8f3285ce04fc349d133d6",
+ "shasum": ""
+ },
+ "require": {
+ "chillerlan/php-settings-container": "^1.2",
+ "ext-mbstring": "*",
+ "php": "^7.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.5",
+ "setasign/fpdf": "^1.8.2"
+ },
+ "suggest": {
+ "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.",
+ "setasign/fpdf": "Required to use the QR FPDF output."
+ },
+ "time": "2020-11-18T20:51:41+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "chillerlan\\QRCode\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kazuhiko Arase",
+ "homepage": "https://github.com/kazuhikoarase"
+ },
+ {
+ "name": "Smiley",
+ "email": "smiley@chillerlan.net",
+ "homepage": "https://github.com/codemasher"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors"
+ }
+ ],
+ "description": "A QR code generator. PHP 7.2+",
+ "homepage": "https://github.com/chillerlan/php-qrcode",
+ "keywords": [
+ "phpqrcode",
+ "qr",
+ "qr code",
+ "qrcode",
+ "qrcode-generator"
+ ],
+ "support": {
+ "issues": "https://github.com/chillerlan/php-qrcode/issues",
+ "source": "https://github.com/chillerlan/php-qrcode/tree/3.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4",
+ "type": "custom"
+ },
+ {
+ "url": "https://ko-fi.com/codemasher",
+ "type": "ko_fi"
+ }
+ ],
+ "install-path": "../chillerlan/php-qrcode"
+ },
+ {
+ "name": "chillerlan/php-settings-container",
+ "version": "1.2.1",
+ "version_normalized": "1.2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/chillerlan/php-settings-container.git",
+ "reference": "b9b0431dffd74102ee92348a63b4c33fc8ba639b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/b9b0431dffd74102ee92348a63b4c33fc8ba639b",
+ "reference": "b9b0431dffd74102ee92348a63b4c33fc8ba639b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "php": "^7.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.3"
+ },
+ "time": "2019-09-10T00:09:44+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "chillerlan\\Settings\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Smiley",
+ "email": "smiley@chillerlan.net",
+ "homepage": "https://github.com/codemasher"
+ }
+ ],
+ "description": "A container class for immutable settings objects. Not a DI container. PHP 7.2+",
+ "homepage": "https://github.com/chillerlan/php-settings-container",
+ "keywords": [
+ "PHP7",
+ "Settings",
+ "container",
+ "helper"
+ ],
+ "support": {
+ "issues": "https://github.com/chillerlan/php-settings-container/issues",
+ "source": "https://github.com/chillerlan/php-settings-container"
+ },
+ "install-path": "../chillerlan/php-settings-container"
+ },
+ {
+ "name": "paragonie/constant_time_encoding",
+ "version": "v2.4.0",
+ "version_normalized": "2.4.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/constant_time_encoding.git",
+ "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
+ "reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7|^8"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6|^7|^8|^9",
+ "vimeo/psalm": "^1|^2|^3|^4"
+ },
+ "time": "2020-12-06T15:14:20+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "ParagonIE\\ConstantTime\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Steve 'Sc00bz' Thomas",
+ "email": "steve@tobtu.com",
+ "homepage": "https://www.tobtu.com",
+ "role": "Original Developer"
+ }
+ ],
+ "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
+ "keywords": [
+ "base16",
+ "base32",
+ "base32_decode",
+ "base32_encode",
+ "base64",
+ "base64_decode",
+ "base64_encode",
+ "bin2hex",
+ "encoding",
+ "hex",
+ "hex2bin",
+ "rfc4648"
+ ],
+ "support": {
+ "email": "info@paragonie.com",
+ "issues": "https://github.com/paragonie/constant_time_encoding/issues",
+ "source": "https://github.com/paragonie/constant_time_encoding"
+ },
+ "install-path": "../paragonie/constant_time_encoding"
+ },
+ {
+ "name": "spomky-labs/otphp",
+ "version": "v10.0.1",
+ "version_normalized": "10.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Spomky-Labs/otphp.git",
+ "reference": "f44cce5a9db4b8da410215d992110482c931232f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/f44cce5a9db4b8da410215d992110482c931232f",
+ "reference": "f44cce5a9db4b8da410215d992110482c931232f",
+ "shasum": ""
+ },
+ "require": {
+ "beberlei/assert": "^3.0",
+ "ext-mbstring": "*",
+ "paragonie/constant_time_encoding": "^2.0",
+ "php": "^7.2|^8.0",
+ "thecodingmachine/safe": "^0.1.14|^1.0"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.0",
+ "phpstan/phpstan": "^0.12",
+ "phpstan/phpstan-beberlei-assert": "^0.12",
+ "phpstan/phpstan-deprecation-rules": "^0.12",
+ "phpstan/phpstan-phpunit": "^0.12",
+ "phpstan/phpstan-strict-rules": "^0.12",
+ "phpunit/phpunit": "^8.0",
+ "thecodingmachine/phpstan-safe-rule": "^1.0"
+ },
+ "time": "2020-01-28T09:24:19+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "v10.0": "10.0.x-dev",
+ "v9.0": "9.0.x-dev",
+ "v8.3": "8.3.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "OTPHP\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Florent Morselli",
+ "homepage": "https://github.com/Spomky"
+ },
+ {
+ "name": "All contributors",
+ "homepage": "https://github.com/Spomky-Labs/otphp/contributors"
+ }
+ ],
+ "description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator",
+ "homepage": "https://github.com/Spomky-Labs/otphp",
+ "keywords": [
+ "FreeOTP",
+ "RFC 4226",
+ "RFC 6238",
+ "google authenticator",
+ "hotp",
+ "otp",
+ "totp"
+ ],
+ "support": {
+ "issues": "https://github.com/Spomky-Labs/otphp/issues",
+ "source": "https://github.com/Spomky-Labs/otphp/tree/v10.0.1"
+ },
+ "install-path": "../spomky-labs/otphp"
+ },
+ {
+ "name": "thecodingmachine/safe",
+ "version": "v1.3.3",
+ "version_normalized": "1.3.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thecodingmachine/safe.git",
+ "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/a8ab0876305a4cdaef31b2350fcb9811b5608dbc",
+ "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^0.12",
+ "squizlabs/php_codesniffer": "^3.2",
+ "thecodingmachine/phpstan-strict-rules": "^0.12"
+ },
+ "time": "2020-10-28T17:51:34+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.1-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Safe\\": [
+ "lib/",
+ "deprecated/",
+ "generated/"
+ ]
+ },
+ "files": [
+ "deprecated/apc.php",
+ "deprecated/libevent.php",
+ "deprecated/mssql.php",
+ "deprecated/stats.php",
+ "lib/special_cases.php",
+ "generated/apache.php",
+ "generated/apcu.php",
+ "generated/array.php",
+ "generated/bzip2.php",
+ "generated/calendar.php",
+ "generated/classobj.php",
+ "generated/com.php",
+ "generated/cubrid.php",
+ "generated/curl.php",
+ "generated/datetime.php",
+ "generated/dir.php",
+ "generated/eio.php",
+ "generated/errorfunc.php",
+ "generated/exec.php",
+ "generated/fileinfo.php",
+ "generated/filesystem.php",
+ "generated/filter.php",
+ "generated/fpm.php",
+ "generated/ftp.php",
+ "generated/funchand.php",
+ "generated/gmp.php",
+ "generated/gnupg.php",
+ "generated/hash.php",
+ "generated/ibase.php",
+ "generated/ibmDb2.php",
+ "generated/iconv.php",
+ "generated/image.php",
+ "generated/imap.php",
+ "generated/info.php",
+ "generated/ingres-ii.php",
+ "generated/inotify.php",
+ "generated/json.php",
+ "generated/ldap.php",
+ "generated/libxml.php",
+ "generated/lzf.php",
+ "generated/mailparse.php",
+ "generated/mbstring.php",
+ "generated/misc.php",
+ "generated/msql.php",
+ "generated/mysql.php",
+ "generated/mysqli.php",
+ "generated/mysqlndMs.php",
+ "generated/mysqlndQc.php",
+ "generated/network.php",
+ "generated/oci8.php",
+ "generated/opcache.php",
+ "generated/openssl.php",
+ "generated/outcontrol.php",
+ "generated/password.php",
+ "generated/pcntl.php",
+ "generated/pcre.php",
+ "generated/pdf.php",
+ "generated/pgsql.php",
+ "generated/posix.php",
+ "generated/ps.php",
+ "generated/pspell.php",
+ "generated/readline.php",
+ "generated/rpminfo.php",
+ "generated/rrd.php",
+ "generated/sem.php",
+ "generated/session.php",
+ "generated/shmop.php",
+ "generated/simplexml.php",
+ "generated/sockets.php",
+ "generated/sodium.php",
+ "generated/solr.php",
+ "generated/spl.php",
+ "generated/sqlsrv.php",
+ "generated/ssdeep.php",
+ "generated/ssh2.php",
+ "generated/stream.php",
+ "generated/strings.php",
+ "generated/swoole.php",
+ "generated/uodbc.php",
+ "generated/uopz.php",
+ "generated/url.php",
+ "generated/var.php",
+ "generated/xdiff.php",
+ "generated/xml.php",
+ "generated/xmlrpc.php",
+ "generated/yaml.php",
+ "generated/yaz.php",
+ "generated/zip.php",
+ "generated/zlib.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHP core functions that throw exceptions instead of returning FALSE on error",
+ "support": {
+ "issues": "https://github.com/thecodingmachine/safe/issues",
+ "source": "https://github.com/thecodingmachine/safe/tree/v1.3.3"
+ },
+ "install-path": "../thecodingmachine/safe"
+ }
+ ],
+ "dev": true,
+ "dev-package-names": []
+}
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
new file mode 100644
index 000000000..ceaa850e9
--- /dev/null
+++ b/vendor/composer/installed.php
@@ -0,0 +1,78 @@
+
+ array (
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'bc4475b6698f5a74e475674aa7af43253c459892',
+ 'name' => '__root__',
+ ),
+ 'versions' =>
+ array (
+ '__root__' =>
+ array (
+ 'pretty_version' => 'dev-master',
+ 'version' => 'dev-master',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'bc4475b6698f5a74e475674aa7af43253c459892',
+ ),
+ 'beberlei/assert' =>
+ array (
+ 'pretty_version' => 'v3.2.7',
+ 'version' => '3.2.7.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'd63a6943fc4fd1a2aedb65994e3548715105abcf',
+ ),
+ 'chillerlan/php-qrcode' =>
+ array (
+ 'pretty_version' => '3.4.0',
+ 'version' => '3.4.0.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'd8bf297e6843a53aeaa8f3285ce04fc349d133d6',
+ ),
+ 'chillerlan/php-settings-container' =>
+ array (
+ 'pretty_version' => '1.2.1',
+ 'version' => '1.2.1.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'b9b0431dffd74102ee92348a63b4c33fc8ba639b',
+ ),
+ 'paragonie/constant_time_encoding' =>
+ array (
+ 'pretty_version' => 'v2.4.0',
+ 'version' => '2.4.0.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c',
+ ),
+ 'spomky-labs/otphp' =>
+ array (
+ 'pretty_version' => 'v10.0.1',
+ 'version' => '10.0.1.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'f44cce5a9db4b8da410215d992110482c931232f',
+ ),
+ 'thecodingmachine/safe' =>
+ array (
+ 'pretty_version' => 'v1.3.3',
+ 'version' => '1.3.3.0',
+ 'aliases' =>
+ array (
+ ),
+ 'reference' => 'a8ab0876305a4cdaef31b2350fcb9811b5608dbc',
+ ),
+ ),
+);
diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php
new file mode 100644
index 000000000..589e9e770
--- /dev/null
+++ b/vendor/composer/platform_check.php
@@ -0,0 +1,26 @@
+= 70200)) {
+ $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.';
+}
+
+if ($issues) {
+ if (!headers_sent()) {
+ header('HTTP/1.1 500 Internal Server Error');
+ }
+ if (!ini_get('display_errors')) {
+ if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+ fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
+ } elseif (!headers_sent()) {
+ echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
+ }
+ }
+ trigger_error(
+ 'Composer detected issues in your platform: ' . implode(' ', $issues),
+ E_USER_ERROR
+ );
+}
diff --git a/vendor/paragonie/constant_time_encoding/.gitignore b/vendor/paragonie/constant_time_encoding/.gitignore
new file mode 100644
index 000000000..e0caea8fc
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/.gitignore
@@ -0,0 +1,2 @@
+.idea/
+vendor/
\ No newline at end of file
diff --git a/vendor/paragonie/constant_time_encoding/.travis.yml b/vendor/paragonie/constant_time_encoding/.travis.yml
new file mode 100644
index 000000000..117c114a1
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/.travis.yml
@@ -0,0 +1,24 @@
+language: php
+sudo: false
+
+matrix:
+ fast_finish: true
+ include:
+ - php: "7.1"
+ - php: "7.2"
+ - php: "7.3"
+ - php: "7.4"
+ - php: "8.0"
+ - php: "nightly"
+ allow_failures:
+ - php: "nightly"
+ - php: "7.4"
+ - php: "8.0"
+
+install:
+ - composer self-update
+ - composer update
+
+script:
+ - vendor/bin/phpunit
+ - vendor/bin/psalm
diff --git a/vendor/paragonie/constant_time_encoding/LICENSE.txt b/vendor/paragonie/constant_time_encoding/LICENSE.txt
new file mode 100644
index 000000000..f424f5ecc
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/LICENSE.txt
@@ -0,0 +1,48 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 - 2020 Paragon Initiative Enterprises
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+------------------------------------------------------------------------------
+This library was based on the work of Steve "Sc00bz" Thomas.
+------------------------------------------------------------------------------
+
+The MIT License (MIT)
+
+Copyright (c) 2014 Steve Thomas
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/vendor/paragonie/constant_time_encoding/README.md b/vendor/paragonie/constant_time_encoding/README.md
new file mode 100644
index 000000000..d7db2a2d0
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/README.md
@@ -0,0 +1,84 @@
+# Constant-Time Encoding
+
+[![Build Status](https://travis-ci.org/paragonie/constant_time_encoding.svg?branch=master)](https://travis-ci.org/paragonie/constant_time_encoding)
+[![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding)
+[![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding)
+[![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding)
+[![Downloads](https://img.shields.io/packagist/dt/paragonie/constant_time_encoding.svg)](https://packagist.org/packages/paragonie/constant_time_encoding)
+
+Based on the [constant-time base64 implementation made by Steve "Sc00bz" Thomas](https://github.com/Sc00bz/ConstTimeEncoding),
+this library aims to offer character encoding functions that do not leak
+information about what you are encoding/decoding via processor cache
+misses. Further reading on [cache-timing attacks](http://blog.ircmaxell.com/2014/11/its-all-about-time.html).
+
+Our fork offers the following enchancements:
+
+* `mbstring.func_overload` resistance
+* Unit tests
+* Composer- and Packagist-ready
+* Base16 encoding
+* Base32 encoding
+* Uses `pack()` and `unpack()` instead of `chr()` and `ord()`
+
+## PHP Version Requirements
+
+Version 2 of this library should work on **PHP 7** or newer. For PHP 5
+support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x).
+
+If you are adding this as a dependency to a project intended to work on both PHP 5 and PHP 7, please set the required version to `^1|^2` instead of just `^1` or `^2`.
+
+## How to Install
+
+```sh
+composer require paragonie/constant_time_encoding
+```
+
+## How to Use
+
+```php
+use \ParagonIE\ConstantTime\Encoding;
+
+// possibly (if applicable):
+// require 'vendor/autoload.php';
+
+$data = random_bytes(32);
+echo Encoding::base64Encode($data), "\n";
+echo Encoding::base32EncodeUpper($data), "\n";
+echo Encoding::base32Encode($data), "\n";
+echo Encoding::hexEncode($data), "\n";
+echo Encoding::hexEncodeUpper($data), "\n";
+```
+
+Example output:
+
+```
+1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE=
+2VMKKPSHSWVCVZJ6E7SONRY3ZXCNG3GE6ZZFU7TGJSX7KUKFNLAQ====
+2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq====
+d558a53e4795aa2ae53e27e4e6c71bcdc4d36cc4f6725a7e664caff551456ac1
+D558A53E4795AA2AE53E27E4E6C71BDCC4D36CC4F6725A7E664CAFF551456AC1
+```
+
+If you only need a particular variant, you can just reference the
+required class like so:
+
+```php
+use \ParagonIE\ConstantTime\Base64;
+use \ParagonIE\ConstantTime\Base32;
+
+$data = random_bytes(32);
+echo Base64::encode($data), "\n";
+echo Base32::encode($data), "\n";
+```
+
+Example output:
+
+```
+1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE=
+2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq====
+```
+
+## Support Contracts
+
+If your company uses this library in their products or services, you may be
+interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise).
diff --git a/vendor/paragonie/constant_time_encoding/composer.json b/vendor/paragonie/constant_time_encoding/composer.json
new file mode 100644
index 000000000..583fe366f
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/composer.json
@@ -0,0 +1,51 @@
+{
+ "name": "paragonie/constant_time_encoding",
+ "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
+ "keywords": [
+ "base64",
+ "encoding",
+ "rfc4648",
+ "base32",
+ "base16",
+ "hex",
+ "bin2hex",
+ "hex2bin",
+ "base64_encode",
+ "base64_decode",
+ "base32_encode",
+ "base32_decode"
+ ],
+ "license": "MIT",
+ "type": "library",
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com",
+ "role": "Maintainer"
+ },
+ {
+ "name": "Steve 'Sc00bz' Thomas",
+ "email": "steve@tobtu.com",
+ "homepage": "https://www.tobtu.com",
+ "role": "Original Developer"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/paragonie/constant_time_encoding/issues",
+ "email": "info@paragonie.com",
+ "source": "https://github.com/paragonie/constant_time_encoding"
+ },
+ "require": {
+ "php": "^7|^8"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^6|^7|^8|^9",
+ "vimeo/psalm": "^1|^2|^3|^4"
+ },
+ "autoload": {
+ "psr-4": {
+ "ParagonIE\\ConstantTime\\": "src/"
+ }
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/phpunit.xml.dist b/vendor/paragonie/constant_time_encoding/phpunit.xml.dist
new file mode 100644
index 000000000..4d090343e
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/phpunit.xml.dist
@@ -0,0 +1,13 @@
+
+
+
+
+ ./src
+
+
+
+
+ ./tests
+
+
+
diff --git a/vendor/paragonie/constant_time_encoding/psalm.xml b/vendor/paragonie/constant_time_encoding/psalm.xml
new file mode 100644
index 000000000..0a17264b0
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/psalm.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/vendor/paragonie/constant_time_encoding/src/Base32.php b/vendor/paragonie/constant_time_encoding/src/Base32.php
new file mode 100644
index 000000000..7784bafbf
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/src/Base32.php
@@ -0,0 +1,471 @@
+ 96 && $src < 123) $ret += $src - 97 + 1; // -64
+ $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96);
+
+ // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23
+ $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23);
+
+ return $ret;
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 5-bit integers
+ * into 8-bit integers.
+ *
+ * Uppercase variant.
+ *
+ * @param int $src
+ * @return int
+ */
+ protected static function decode5BitsUpper(int $src): int
+ {
+ $ret = -1;
+
+ // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64
+ $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
+
+ // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23
+ $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23);
+
+ return $ret;
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 5-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode5Bits(int $src): string
+ {
+ $diff = 0x61;
+
+ // if ($src > 25) $ret -= 72;
+ $diff -= ((25 - $src) >> 8) & 73;
+
+ return \pack('C', $src + $diff);
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 5-bit integers.
+ *
+ * Uppercase variant.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode5BitsUpper(int $src): string
+ {
+ $diff = 0x41;
+
+ // if ($src > 25) $ret -= 40;
+ $diff -= ((25 - $src) >> 8) & 41;
+
+ return \pack('C', $src + $diff);
+ }
+
+
+ /**
+ * Base32 decoding
+ *
+ * @param string $src
+ * @param bool $upper
+ * @param bool $strictPadding
+ * @return string
+ * @throws \TypeError
+ * @psalm-suppress RedundantCondition
+ */
+ protected static function doDecode(string $src, bool $upper = false, bool $strictPadding = false): string
+ {
+ // We do this to reduce code duplication:
+ $method = $upper
+ ? 'decode5BitsUpper'
+ : 'decode5Bits';
+
+ // Remove padding
+ $srcLen = Binary::safeStrlen($src);
+ if ($srcLen === 0) {
+ return '';
+ }
+ if ($strictPadding) {
+ if (($srcLen & 7) === 0) {
+ for ($j = 0; $j < 7; ++$j) {
+ if ($src[$srcLen - 1] === '=') {
+ $srcLen--;
+ } else {
+ break;
+ }
+ }
+ }
+ if (($srcLen & 7) === 1) {
+ throw new \RangeException(
+ 'Incorrect padding'
+ );
+ }
+ } else {
+ $src = \rtrim($src, '=');
+ $srcLen = Binary::safeStrlen($src);
+ }
+
+ $err = 0;
+ $dest = '';
+ // Main loop (no padding):
+ for ($i = 0; $i + 8 <= $srcLen; $i += 8) {
+ /** @var array $chunk */
+ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8));
+ /** @var int $c0 */
+ $c0 = static::$method($chunk[1]);
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+ /** @var int $c4 */
+ $c4 = static::$method($chunk[5]);
+ /** @var int $c5 */
+ $c5 = static::$method($chunk[6]);
+ /** @var int $c6 */
+ $c6 = static::$method($chunk[7]);
+ /** @var int $c7 */
+ $c7 = static::$method($chunk[8]);
+
+ $dest .= \pack(
+ 'CCCCC',
+ (($c0 << 3) | ($c1 >> 2) ) & 0xff,
+ (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
+ (($c3 << 4) | ($c4 >> 1) ) & 0xff,
+ (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff,
+ (($c6 << 5) | ($c7 ) ) & 0xff
+ );
+ $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8;
+ }
+ // The last chunk, which may have padding:
+ if ($i < $srcLen) {
+ /** @var array $chunk */
+ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
+ /** @var int $c0 */
+ $c0 = static::$method($chunk[1]);
+
+ if ($i + 6 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+ /** @var int $c4 */
+ $c4 = static::$method($chunk[5]);
+ /** @var int $c5 */
+ $c5 = static::$method($chunk[6]);
+ /** @var int $c6 */
+ $c6 = static::$method($chunk[7]);
+
+ $dest .= \pack(
+ 'CCCC',
+ (($c0 << 3) | ($c1 >> 2) ) & 0xff,
+ (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
+ (($c3 << 4) | ($c4 >> 1) ) & 0xff,
+ (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff
+ );
+ $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8;
+ } elseif ($i + 5 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+ /** @var int $c4 */
+ $c4 = static::$method($chunk[5]);
+ /** @var int $c5 */
+ $c5 = static::$method($chunk[6]);
+
+ $dest .= \pack(
+ 'CCCC',
+ (($c0 << 3) | ($c1 >> 2) ) & 0xff,
+ (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
+ (($c3 << 4) | ($c4 >> 1) ) & 0xff,
+ (($c4 << 7) | ($c5 << 2) ) & 0xff
+ );
+ $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8;
+ } elseif ($i + 4 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+ /** @var int $c4 */
+ $c4 = static::$method($chunk[5]);
+
+ $dest .= \pack(
+ 'CCC',
+ (($c0 << 3) | ($c1 >> 2) ) & 0xff,
+ (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
+ (($c3 << 4) | ($c4 >> 1) ) & 0xff
+ );
+ $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8;
+ } elseif ($i + 3 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+ /** @var int $c3 */
+ $c3 = static::$method($chunk[4]);
+
+ $dest .= \pack(
+ 'CC',
+ (($c0 << 3) | ($c1 >> 2) ) & 0xff,
+ (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff
+ );
+ $err |= ($c0 | $c1 | $c2 | $c3) >> 8;
+ } elseif ($i + 2 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+ /** @var int $c2 */
+ $c2 = static::$method($chunk[3]);
+
+ $dest .= \pack(
+ 'CC',
+ (($c0 << 3) | ($c1 >> 2) ) & 0xff,
+ (($c1 << 6) | ($c2 << 1) ) & 0xff
+ );
+ $err |= ($c0 | $c1 | $c2) >> 8;
+ } elseif ($i + 1 < $srcLen) {
+ /** @var int $c1 */
+ $c1 = static::$method($chunk[2]);
+
+ $dest .= \pack(
+ 'C',
+ (($c0 << 3) | ($c1 >> 2) ) & 0xff
+ );
+ $err |= ($c0 | $c1) >> 8;
+ } else {
+ $dest .= \pack(
+ 'C',
+ (($c0 << 3) ) & 0xff
+ );
+ $err |= ($c0) >> 8;
+ }
+ }
+ /** @var bool $check */
+ $check = ($err === 0);
+ if (!$check) {
+ throw new \RangeException(
+ 'Base32::doDecode() only expects characters in the correct base32 alphabet'
+ );
+ }
+ return $dest;
+ }
+
+ /**
+ * Base32 Encoding
+ *
+ * @param string $src
+ * @param bool $upper
+ * @param bool $pad
+ * @return string
+ * @throws \TypeError
+ */
+ protected static function doEncode(string $src, bool $upper = false, $pad = true): string
+ {
+ // We do this to reduce code duplication:
+ $method = $upper
+ ? 'encode5BitsUpper'
+ : 'encode5Bits';
+
+ $dest = '';
+ $srcLen = Binary::safeStrlen($src);
+
+ // Main loop (no padding):
+ for ($i = 0; $i + 5 <= $srcLen; $i += 5) {
+ /** @var array $chunk */
+ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5));
+ $b0 = $chunk[1];
+ $b1 = $chunk[2];
+ $b2 = $chunk[3];
+ $b3 = $chunk[4];
+ $b4 = $chunk[5];
+ $dest .=
+ static::$method( ($b0 >> 3) & 31) .
+ static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
+ static::$method((($b1 >> 1) ) & 31) .
+ static::$method((($b1 << 4) | ($b2 >> 4)) & 31) .
+ static::$method((($b2 << 1) | ($b3 >> 7)) & 31) .
+ static::$method((($b3 >> 2) ) & 31) .
+ static::$method((($b3 << 3) | ($b4 >> 5)) & 31) .
+ static::$method( $b4 & 31);
+ }
+ // The last chunk, which may have padding:
+ if ($i < $srcLen) {
+ /** @var array $chunk */
+ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
+ $b0 = $chunk[1];
+ if ($i + 3 < $srcLen) {
+ $b1 = $chunk[2];
+ $b2 = $chunk[3];
+ $b3 = $chunk[4];
+ $dest .=
+ static::$method( ($b0 >> 3) & 31) .
+ static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
+ static::$method((($b1 >> 1) ) & 31) .
+ static::$method((($b1 << 4) | ($b2 >> 4)) & 31) .
+ static::$method((($b2 << 1) | ($b3 >> 7)) & 31) .
+ static::$method((($b3 >> 2) ) & 31) .
+ static::$method((($b3 << 3) ) & 31);
+ if ($pad) {
+ $dest .= '=';
+ }
+ } elseif ($i + 2 < $srcLen) {
+ $b1 = $chunk[2];
+ $b2 = $chunk[3];
+ $dest .=
+ static::$method( ($b0 >> 3) & 31) .
+ static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
+ static::$method((($b1 >> 1) ) & 31) .
+ static::$method((($b1 << 4) | ($b2 >> 4)) & 31) .
+ static::$method((($b2 << 1) ) & 31);
+ if ($pad) {
+ $dest .= '===';
+ }
+ } elseif ($i + 1 < $srcLen) {
+ $b1 = $chunk[2];
+ $dest .=
+ static::$method( ($b0 >> 3) & 31) .
+ static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
+ static::$method((($b1 >> 1) ) & 31) .
+ static::$method((($b1 << 4) ) & 31);
+ if ($pad) {
+ $dest .= '====';
+ }
+ } else {
+ $dest .=
+ static::$method( ($b0 >> 3) & 31) .
+ static::$method( ($b0 << 2) & 31);
+ if ($pad) {
+ $dest .= '======';
+ }
+ }
+ }
+ return $dest;
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/src/Base32Hex.php b/vendor/paragonie/constant_time_encoding/src/Base32Hex.php
new file mode 100644
index 000000000..68fdad52c
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/src/Base32Hex.php
@@ -0,0 +1,111 @@
+ 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47
+ $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47);
+
+ // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86
+ $ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86);
+
+ return $ret;
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 5-bit integers
+ * into 8-bit integers.
+ *
+ * @param int $src
+ * @return int
+ */
+ protected static function decode5BitsUpper(int $src): int
+ {
+ $ret = -1;
+
+ // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47
+ $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47);
+
+ // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54
+ $ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54);
+
+ return $ret;
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 5-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode5Bits(int $src): string
+ {
+ $src += 0x30;
+
+ // if ($src > 0x39) $src += 0x61 - 0x3a; // 39
+ $src += ((0x39 - $src) >> 8) & 39;
+
+ return \pack('C', $src);
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 5-bit integers.
+ *
+ * Uppercase variant.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode5BitsUpper(int $src): string
+ {
+ $src += 0x30;
+
+ // if ($src > 0x39) $src += 0x41 - 0x3a; // 7
+ $src += ((0x39 - $src) >> 8) & 7;
+
+ return \pack('C', $src);
+ }
+}
\ No newline at end of file
diff --git a/vendor/paragonie/constant_time_encoding/src/Base64.php b/vendor/paragonie/constant_time_encoding/src/Base64.php
new file mode 100644
index 000000000..4739e4895
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/src/Base64.php
@@ -0,0 +1,271 @@
+ $chunk */
+ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 3));
+ $b0 = $chunk[1];
+ $b1 = $chunk[2];
+ $b2 = $chunk[3];
+
+ $dest .=
+ static::encode6Bits( $b0 >> 2 ) .
+ static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
+ static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) .
+ static::encode6Bits( $b2 & 63);
+ }
+ // The last chunk, which may have padding:
+ if ($i < $srcLen) {
+ /** @var array $chunk */
+ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
+ $b0 = $chunk[1];
+ if ($i + 1 < $srcLen) {
+ $b1 = $chunk[2];
+ $dest .=
+ static::encode6Bits($b0 >> 2) .
+ static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
+ static::encode6Bits(($b1 << 2) & 63);
+ if ($pad) {
+ $dest .= '=';
+ }
+ } else {
+ $dest .=
+ static::encode6Bits( $b0 >> 2) .
+ static::encode6Bits(($b0 << 4) & 63);
+ if ($pad) {
+ $dest .= '==';
+ }
+ }
+ }
+ return $dest;
+ }
+
+ /**
+ * decode from base64 into binary
+ *
+ * Base64 character set "./[A-Z][a-z][0-9]"
+ *
+ * @param string $encodedString
+ * @param bool $strictPadding
+ * @return string
+ * @throws \RangeException
+ * @throws \TypeError
+ * @psalm-suppress RedundantCondition
+ */
+ public static function decode(string $encodedString, bool $strictPadding = false): string
+ {
+ // Remove padding
+ $srcLen = Binary::safeStrlen($encodedString);
+ if ($srcLen === 0) {
+ return '';
+ }
+
+ if ($strictPadding) {
+ if (($srcLen & 3) === 0) {
+ if ($encodedString[$srcLen - 1] === '=') {
+ $srcLen--;
+ if ($encodedString[$srcLen - 1] === '=') {
+ $srcLen--;
+ }
+ }
+ }
+ if (($srcLen & 3) === 1) {
+ throw new \RangeException(
+ 'Incorrect padding'
+ );
+ }
+ if ($encodedString[$srcLen - 1] === '=') {
+ throw new \RangeException(
+ 'Incorrect padding'
+ );
+ }
+ } else {
+ $encodedString = \rtrim($encodedString, '=');
+ $srcLen = Binary::safeStrlen($encodedString);
+ }
+
+ $err = 0;
+ $dest = '';
+ // Main loop (no padding):
+ for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
+ /** @var array $chunk */
+ $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, 4));
+ $c0 = static::decode6Bits($chunk[1]);
+ $c1 = static::decode6Bits($chunk[2]);
+ $c2 = static::decode6Bits($chunk[3]);
+ $c3 = static::decode6Bits($chunk[4]);
+
+ $dest .= \pack(
+ 'CCC',
+ ((($c0 << 2) | ($c1 >> 4)) & 0xff),
+ ((($c1 << 4) | ($c2 >> 2)) & 0xff),
+ ((($c2 << 6) | $c3 ) & 0xff)
+ );
+ $err |= ($c0 | $c1 | $c2 | $c3) >> 8;
+ }
+ // The last chunk, which may have padding:
+ if ($i < $srcLen) {
+ /** @var array $chunk */
+ $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, $srcLen - $i));
+ $c0 = static::decode6Bits($chunk[1]);
+
+ if ($i + 2 < $srcLen) {
+ $c1 = static::decode6Bits($chunk[2]);
+ $c2 = static::decode6Bits($chunk[3]);
+ $dest .= \pack(
+ 'CC',
+ ((($c0 << 2) | ($c1 >> 4)) & 0xff),
+ ((($c1 << 4) | ($c2 >> 2)) & 0xff)
+ );
+ $err |= ($c0 | $c1 | $c2) >> 8;
+ } elseif ($i + 1 < $srcLen) {
+ $c1 = static::decode6Bits($chunk[2]);
+ $dest .= \pack(
+ 'C',
+ ((($c0 << 2) | ($c1 >> 4)) & 0xff)
+ );
+ $err |= ($c0 | $c1) >> 8;
+ } elseif ($i < $srcLen && $strictPadding) {
+ $err |= 1;
+ }
+ }
+ /** @var bool $check */
+ $check = ($err === 0);
+ if (!$check) {
+ throw new \RangeException(
+ 'Base64::decode() only expects characters in the correct base64 alphabet'
+ );
+ }
+ return $dest;
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 6-bit integers
+ * into 8-bit integers.
+ *
+ * Base64 character set:
+ * [A-Z] [a-z] [0-9] + /
+ * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
+ *
+ * @param int $src
+ * @return int
+ */
+ protected static function decode6Bits(int $src): int
+ {
+ $ret = -1;
+
+ // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
+ $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
+
+ // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
+ $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
+
+ // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
+ $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
+
+ // if ($src == 0x2b) $ret += 62 + 1;
+ $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63;
+
+ // if ($src == 0x2f) ret += 63 + 1;
+ $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64;
+
+ return $ret;
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 6-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode6Bits(int $src): string
+ {
+ $diff = 0x41;
+
+ // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
+ $diff += ((25 - $src) >> 8) & 6;
+
+ // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
+ $diff -= ((51 - $src) >> 8) & 75;
+
+ // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15
+ $diff -= ((61 - $src) >> 8) & 15;
+
+ // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3
+ $diff += ((62 - $src) >> 8) & 3;
+
+ return \pack('C', $src + $diff);
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php b/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php
new file mode 100644
index 000000000..8ad2e2bf1
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php
@@ -0,0 +1,88 @@
+ 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45
+ $ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45);
+
+ // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62
+ $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62);
+
+ // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68
+ $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68);
+
+ // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7
+ $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7);
+
+ return $ret;
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 6-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode6Bits(int $src): string
+ {
+ $src += 0x2e;
+
+ // if ($src > 0x2f) $src += 0x41 - 0x30; // 17
+ $src += ((0x2f - $src) >> 8) & 17;
+
+ // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6
+ $src += ((0x5a - $src) >> 8) & 6;
+
+ // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75
+ $src -= ((0x7a - $src) >> 8) & 75;
+
+ return \pack('C', $src);
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php b/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php
new file mode 100644
index 000000000..dd1459e85
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php
@@ -0,0 +1,82 @@
+ 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45
+ $ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45);
+
+ // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52
+ $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52);
+
+ // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58
+ $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58);
+
+ return $ret;
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 6-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode6Bits(int $src): string
+ {
+ $src += 0x2e;
+
+ // if ($src > 0x39) $src += 0x41 - 0x3a; // 7
+ $src += ((0x39 - $src) >> 8) & 7;
+
+ // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6
+ $src += ((0x5a - $src) >> 8) & 6;
+
+ return \pack('C', $src);
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php b/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php
new file mode 100644
index 000000000..1a4107527
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php
@@ -0,0 +1,95 @@
+ 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
+ $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
+
+ // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
+ $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
+
+ // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
+ $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
+
+ // if ($src == 0x2c) $ret += 62 + 1;
+ $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63;
+
+ // if ($src == 0x5f) ret += 63 + 1;
+ $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64;
+
+ return $ret;
+ }
+
+ /**
+ * Uses bitwise operators instead of table-lookups to turn 8-bit integers
+ * into 6-bit integers.
+ *
+ * @param int $src
+ * @return string
+ */
+ protected static function encode6Bits(int $src): string
+ {
+ $diff = 0x41;
+
+ // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
+ $diff += ((25 - $src) >> 8) & 6;
+
+ // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
+ $diff -= ((51 - $src) >> 8) & 75;
+
+ // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13
+ $diff -= ((61 - $src) >> 8) & 13;
+
+ // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3
+ $diff += ((62 - $src) >> 8) & 49;
+
+ return \pack('C', $src + $diff);
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/src/Binary.php b/vendor/paragonie/constant_time_encoding/src/Binary.php
new file mode 100644
index 000000000..38dbc4e66
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/src/Binary.php
@@ -0,0 +1,85 @@
+ $chunk */
+ $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 1));
+ /** @var int $c */
+ $c = $chunk[1] & 0xf;
+ /** @var int $b */
+ $b = $chunk[1] >> 4;
+
+ $hex .= pack(
+ 'CC',
+ (87 + $b + ((($b - 10) >> 8) & ~38)),
+ (87 + $c + ((($c - 10) >> 8) & ~38))
+ );
+ }
+ return $hex;
+ }
+
+ /**
+ * Convert a binary string into a hexadecimal string without cache-timing
+ * leaks, returning uppercase letters (as per RFC 4648)
+ *
+ * @param string $binString (raw binary)
+ * @return string
+ * @throws \TypeError
+ */
+ public static function encodeUpper(string $binString): string
+ {
+ /** @var string $hex */
+ $hex = '';
+ /** @var int $len */
+ $len = Binary::safeStrlen($binString);
+
+ for ($i = 0; $i < $len; ++$i) {
+ /** @var array $chunk */
+ $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 2));
+ /** @var int $c */
+ $c = $chunk[1] & 0xf;
+ /** @var int $b */
+ $b = $chunk[1] >> 4;
+
+ $hex .= pack(
+ 'CC',
+ (55 + $b + ((($b - 10) >> 8) & ~6)),
+ (55 + $c + ((($c - 10) >> 8) & ~6))
+ );
+ }
+ return $hex;
+ }
+
+ /**
+ * Convert a hexadecimal string into a binary string without cache-timing
+ * leaks
+ *
+ * @param string $encodedString
+ * @param bool $strictPadding
+ * @return string (raw binary)
+ * @throws \RangeException
+ */
+ public static function decode(string $encodedString, bool $strictPadding = false): string
+ {
+ /** @var int $hex_pos */
+ $hex_pos = 0;
+ /** @var string $bin */
+ $bin = '';
+ /** @var int $c_acc */
+ $c_acc = 0;
+ /** @var int $hex_len */
+ $hex_len = Binary::safeStrlen($encodedString);
+ /** @var int $state */
+ $state = 0;
+ if (($hex_len & 1) !== 0) {
+ if ($strictPadding) {
+ throw new \RangeException(
+ 'Expected an even number of hexadecimal characters'
+ );
+ } else {
+ $encodedString = '0' . $encodedString;
+ ++$hex_len;
+ }
+ }
+
+ /** @var array $chunk */
+ $chunk = \unpack('C*', $encodedString);
+ while ($hex_pos < $hex_len) {
+ ++$hex_pos;
+ /** @var int $c */
+ $c = $chunk[$hex_pos];
+ /** @var int $c_num */
+ $c_num = $c ^ 48;
+ /** @var int $c_num0 */
+ $c_num0 = ($c_num - 10) >> 8;
+ /** @var int $c_alpha */
+ $c_alpha = ($c & ~32) - 55;
+ /** @var int $c_alpha0 */
+ $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8;
+
+ if (($c_num0 | $c_alpha0) === 0) {
+ throw new \RangeException(
+ 'Expected hexadecimal character'
+ );
+ }
+ /** @var int $c_val */
+ $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0);
+ if ($state === 0) {
+ $c_acc = $c_val * 16;
+ } else {
+ $bin .= \pack('C', $c_acc | $c_val);
+ }
+ $state ^= 1;
+ }
+ return $bin;
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/src/RFC4648.php b/vendor/paragonie/constant_time_encoding/src/RFC4648.php
new file mode 100644
index 000000000..492cad00e
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/src/RFC4648.php
@@ -0,0 +1,175 @@
+ "Zm9v"
+ *
+ * @param string $str
+ * @return string
+ * @throws \TypeError
+ */
+ public static function base64Encode(string $str): string
+ {
+ return Base64::encode($str);
+ }
+
+ /**
+ * RFC 4648 Base64 decoding
+ *
+ * "Zm9v" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ * @throws \TypeError
+ */
+ public static function base64Decode(string $str): string
+ {
+ return Base64::decode($str, true);
+ }
+
+ /**
+ * RFC 4648 Base64 (URL Safe) encoding
+ *
+ * "foo" -> "Zm9v"
+ *
+ * @param string $str
+ * @return string
+ * @throws \TypeError
+ */
+ public static function base64UrlSafeEncode(string $str): string
+ {
+ return Base64UrlSafe::encode($str);
+ }
+
+ /**
+ * RFC 4648 Base64 (URL Safe) decoding
+ *
+ * "Zm9v" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ * @throws \TypeError
+ */
+ public static function base64UrlSafeDecode(string $str): string
+ {
+ return Base64UrlSafe::decode($str, true);
+ }
+
+ /**
+ * RFC 4648 Base32 encoding
+ *
+ * "foo" -> "MZXW6==="
+ *
+ * @param string $str
+ * @return string
+ * @throws \TypeError
+ */
+ public static function base32Encode(string $str): string
+ {
+ return Base32::encodeUpper($str);
+ }
+
+ /**
+ * RFC 4648 Base32 encoding
+ *
+ * "MZXW6===" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ * @throws \TypeError
+ */
+ public static function base32Decode(string $str): string
+ {
+ return Base32::decodeUpper($str, true);
+ }
+
+ /**
+ * RFC 4648 Base32-Hex encoding
+ *
+ * "foo" -> "CPNMU==="
+ *
+ * @param string $str
+ * @return string
+ * @throws \TypeError
+ */
+ public static function base32HexEncode(string $str): string
+ {
+ return Base32::encodeUpper($str);
+ }
+
+ /**
+ * RFC 4648 Base32-Hex decoding
+ *
+ * "CPNMU===" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ * @throws \TypeError
+ */
+ public static function base32HexDecode(string $str): string
+ {
+ return Base32::decodeUpper($str, true);
+ }
+
+ /**
+ * RFC 4648 Base16 decoding
+ *
+ * "foo" -> "666F6F"
+ *
+ * @param string $str
+ * @return string
+ * @throws \TypeError
+ */
+ public static function base16Encode(string $str): string
+ {
+ return Hex::encodeUpper($str);
+ }
+
+ /**
+ * RFC 4648 Base16 decoding
+ *
+ * "666F6F" -> "foo"
+ *
+ * @param string $str
+ * @return string
+ */
+ public static function base16Decode(string $str): string
+ {
+ return Hex::decode($str, true);
+ }
+}
\ No newline at end of file
diff --git a/vendor/paragonie/constant_time_encoding/tests/Base32HexTest.php b/vendor/paragonie/constant_time_encoding/tests/Base32HexTest.php
new file mode 100644
index 000000000..ed19f336f
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/tests/Base32HexTest.php
@@ -0,0 +1,49 @@
+assertSame(
+ $random,
+ Base32Hex::decode($enc)
+ );
+ $unpadded = \rtrim($enc, '=');
+ $this->assertSame(
+ $unpadded,
+ Base32Hex::encodeUnpadded($random)
+ );
+ $this->assertSame(
+ $random,
+ Base32Hex::decode($unpadded)
+ );
+
+ $enc = Base32Hex::encodeUpper($random);
+ $this->assertSame(
+ $random,
+ Base32Hex::decodeUpper($enc)
+ ); $unpadded = \rtrim($enc, '=');
+ $this->assertSame(
+ $unpadded,
+ Base32Hex::encodeUpperUnpadded($random)
+ );
+ $this->assertSame(
+ $random,
+ Base32Hex::decodeUpper($unpadded)
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/tests/Base32Test.php b/vendor/paragonie/constant_time_encoding/tests/Base32Test.php
new file mode 100644
index 000000000..65e8e7c56
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/tests/Base32Test.php
@@ -0,0 +1,50 @@
+assertSame(
+ $random,
+ Base32::decode($enc)
+ );
+ $unpadded = \rtrim($enc, '=');
+ $this->assertSame(
+ $unpadded,
+ Base32::encodeUnpadded($random)
+ );
+ $this->assertSame(
+ $random,
+ Base32::decode($unpadded)
+ );
+
+ $enc = Base32::encodeUpper($random);
+ $this->assertSame(
+ $random,
+ Base32::decodeUpper($enc)
+ );
+ $unpadded = \rtrim($enc, '=');
+ $this->assertSame(
+ $unpadded,
+ Base32::encodeUpperUnpadded($random)
+ );
+ $this->assertSame(
+ $random,
+ Base32::decodeUpper($unpadded)
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/tests/Base64DotSlashOrderedTest.php b/vendor/paragonie/constant_time_encoding/tests/Base64DotSlashOrderedTest.php
new file mode 100644
index 000000000..f7dc828b1
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/tests/Base64DotSlashOrderedTest.php
@@ -0,0 +1,34 @@
+assertSame(
+ $random,
+ Base64DotSlashOrdered::decode($enc)
+ );
+
+ $unpadded = \rtrim($enc, '=');
+ $this->assertSame(
+ $random,
+ Base64DotSlashOrdered::decode($unpadded)
+ );
+ $this->assertSame(
+ $random,
+ Base64DotSlashOrdered::decode($unpadded)
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/tests/Base64DotSlashTest.php b/vendor/paragonie/constant_time_encoding/tests/Base64DotSlashTest.php
new file mode 100644
index 000000000..257a3d549
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/tests/Base64DotSlashTest.php
@@ -0,0 +1,34 @@
+assertSame(
+ $random,
+ Base64DotSlash::decode($enc)
+ );
+
+ $unpadded = \rtrim($enc, '=');
+ $this->assertSame(
+ $random,
+ Base64DotSlash::decode($unpadded)
+ );
+ $this->assertSame(
+ $random,
+ Base64DotSlash::decode($unpadded)
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/tests/Base64Test.php b/vendor/paragonie/constant_time_encoding/tests/Base64Test.php
new file mode 100644
index 000000000..16ab47da0
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/tests/Base64Test.php
@@ -0,0 +1,79 @@
+assertSame(
+ $random,
+ Base64::decode($enc)
+ );
+ $this->assertSame(
+ \base64_encode($random),
+ $enc
+ );
+
+ $unpadded = \rtrim($enc, '=');
+ $this->assertSame(
+ $random,
+ Base64::decode($unpadded)
+ );
+ $this->assertSame(
+ $random,
+ Base64::decode($unpadded)
+ );
+ }
+ }
+ $str = 'MIIFzzCCBLegAwIBAgIDAfdlMA0GCSqGSIb3DQEBBQUAMHMxCzAJBgNVBAYTAlBM' .
+ 'MSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQ' .
+ 'DDBtDT1BFIFNaQUZJUiAtIEt3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1Oi' .
+ 'A2MB4XDTExMTEwOTA2MDAwMFoXDTEzMTEwOTA2MDAwMFowgdkxCzAJBgNVBAYTAlBMM' .
+ 'RwwGgYDVQQKDBNVcnrEhWQgTWlhc3RhIEdkeW5pMRswGQYDVQQFExJQRVNFTDogNjEw' .
+ 'NjA2MDMxMTgxGTAXBgNVBAMMEEplcnp5IFByemV3b3Jza2kxTzBNBgNVBBAwRgwiQWw' .
+ 'uIE1hcnN6YcWCa2EgUGnFgnN1ZHNraWVnbyA1Mi81NAwNODEtMzgyIEdkeW5pYQwGUG' .
+ '9sc2thDAlwb21vcnNraWUxDjAMBgNVBCoMBUplcnp5MRMwEQYDVQQEDApQcnpld29yc' .
+ '2tpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMm5vjGqHPthJCMqKpqssSISRo' .
+ 's0PYDTcEQzyyurfX67EJWKtZj6HNwuDMEGJ02iBNZfjUl7r8dIi28bSKhNlsfycXZKY' .
+ 'RcIjp0+r5RqtR2auo9GQ6veKb61DEAGIqaR+uLLcJVTHCu0w9oXLGbRlGth5eNoj03C' .
+ 'xXVAH2IfhbNwIDAQABo4IChzCCAoMwDAYDVR0TAQH/BAIwADCCAUgGA1UdIAEB/wSCA' .
+ 'TwwggE4MIIBNAYJKoRoAYb3IwEBMIIBJTCB3QYIKwYBBQUHAgIwgdAMgc1EZWtsYXJh' .
+ 'Y2phIHRhIGplc3Qgb8Wbd2lhZGN6ZW5pZW0gd3lkYXdjeSwgxbxlIHRlbiBjZXJ0eWZ' .
+ 'pa2F0IHpvc3RhxYIgd3lkYW55IGpha28gY2VydHlmaWthdCBrd2FsaWZpa293YW55IH' .
+ 'pnb2RuaWUgeiB3eW1hZ2FuaWFtaSB1c3Rhd3kgbyBwb2RwaXNpZSBlbGVrdHJvbmlje' .
+ 'm55bSBvcmF6IHRvd2FyenlzesSFY3ltaSBqZWogcm96cG9yesSFZHplbmlhbWkuMEMG' .
+ 'CCsGAQUFBwIBFjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN' .
+ '6eS9wb2xpdHlrYS5odG1sMAkGA1UdCQQCMAAwIQYDVR0RBBowGIEWai5wcnpld29yc2' .
+ 'tpQGdkeW5pYS5wbDAOBgNVHQ8BAf8EBAMCBkAwgZ4GA1UdIwSBljCBk4AU3TGldJXip' .
+ 'N4oGS3ZYmnBDMFs8gKhd6R1MHMxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dh' .
+ 'IEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQDDBtDT1BFIFNaQUZJUiAtIEt' .
+ '3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1OiA2ggJb9jBIBgNVHR8EQTA/MD' .
+ '2gO6A5hjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6eS9DU' .
+ 'kxfT1pLMzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBYPIqnAreyeql7/opJjcar/qWZ' .
+ 'y9ruhB2q0lZFsJOhwgMnbQXzp/4vv93YJqcHGAXdHP6EO8FQX47mjo2ZKQmi+cIHJHL' .
+ 'ONdX/3Im+M17V0iNAh7Z1lOSfTRT+iiwe/F8phcEaD5q2RmvYusR7zXZq/cLL0If0hX' .
+ 'oPZ/EHQxjN8pxzxiUx6bJAgturnIMEfRNesxwghdr1dkUjOhGLf3kHVzgM6j3VAM7oF' .
+ 'mMUb5y5s96Bzl10DodWitjOEH0vvnIcsppSxH1C1dCAi0o9f/1y2XuLNhBNHMAyTqpY' .
+ 'PX8Yvav1c+Z50OMaSXHAnTa20zv8UtiHbaAhwlifCelUMj93S';
+
+ try {
+ Base64::decode($str, true);
+ $this->fail('Strict padding not enforced');
+ } catch (\Exception $ex) {
+
+ $this->assertSame(
+ Base64::decode($str),
+ \base64_decode($str)
+ );
+ }
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/tests/Base64UrlSafeTest.php b/vendor/paragonie/constant_time_encoding/tests/Base64UrlSafeTest.php
new file mode 100644
index 000000000..136ed611c
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/tests/Base64UrlSafeTest.php
@@ -0,0 +1,58 @@
+assertSame(
+ $random,
+ Base64UrlSafe::decode($enc)
+ );
+ $this->assertSame(
+ \strtr(\base64_encode($random), '+/', '-_'),
+ $enc
+ );
+
+ $unpadded = \rtrim($enc, '=');
+ $this->assertSame(
+ $unpadded,
+ Base64UrlSafe::encodeUnpadded($random)
+ );
+ $this->assertSame(
+ $random,
+ Base64UrlSafe::decode($unpadded)
+ );
+ }
+ }
+
+ $random = \random_bytes(1 << 20);
+ $enc = Base64UrlSafe::encode($random);
+ $this->assertTrue(Binary::safeStrlen($enc) > 65536);
+ $this->assertSame(
+ $random,
+ Base64UrlSafe::decode($enc)
+ );
+ $this->assertSame(
+ \strtr(\base64_encode($random), '+/', '-_'),
+ $enc
+ );
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/tests/EncodingTest.php b/vendor/paragonie/constant_time_encoding/tests/EncodingTest.php
new file mode 100644
index 000000000..6f774d8c0
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/tests/EncodingTest.php
@@ -0,0 +1,307 @@
+assertSame(
+ Encoding::base32Encode("\x00"),
+ 'aa======'
+ );
+ $this->assertSame(
+ Encoding::base32Encode("\x00\x00"),
+ 'aaaa===='
+ );
+ $this->assertSame(
+ Encoding::base32Encode("\x00\x00\x00"),
+ 'aaaaa==='
+ );
+ $this->assertSame(
+ Encoding::base32Encode("\x00\x00\x00\x00"),
+ 'aaaaaaa='
+ );
+ $this->assertSame(
+ Encoding::base32Encode("\x00\x00\x00\x00\x00"),
+ 'aaaaaaaa'
+ );
+ $this->assertSame(
+ Encoding::base32Encode("\x00\x00\x0F\xFF\xFF"),
+ 'aaaa7777'
+ );
+ $this->assertSame(
+ Encoding::base32Encode("\xFF\xFF\xF0\x00\x00"),
+ '7777aaaa'
+ );
+
+ $this->assertSame(
+ Encoding::base32Encode("\xce\x73\x9c\xe7\x39"),
+ 'zzzzzzzz'
+ );
+ $this->assertSame(
+ Encoding::base32Encode("\xd6\xb5\xad\x6b\x5a"),
+ '22222222'
+ );
+ $this->assertSame(
+ Base32::encodeUpper("\x00"),
+ 'AA======'
+ );
+ $this->assertSame(
+ Base32::encodeUpper("\x00\x00"),
+ 'AAAA===='
+ );
+ $this->assertSame(
+ Base32::encodeUpper("\x00\x00\x00"),
+ 'AAAAA==='
+ );
+ $this->assertSame(
+ Base32::encodeUpper("\x00\x00\x00\x00"),
+ 'AAAAAAA='
+ );
+ $this->assertSame(
+ Base32::encodeUpper("\x00\x00\x00\x00\x00"),
+ 'AAAAAAAA'
+ );
+ $this->assertSame(
+ Base32::encodeUpper("\x00\x00\x0F\xFF\xFF"),
+ 'AAAA7777'
+ );
+ $this->assertSame(
+ Base32::encodeUpper("\xFF\xFF\xF0\x00\x00"),
+ '7777AAAA'
+ );
+
+ $this->assertSame(
+ Base32::encodeUpper("\xce\x73\x9c\xe7\x39"),
+ 'ZZZZZZZZ'
+ );
+ $this->assertSame(
+ Base32::encodeUpper("\xd6\xb5\xad\x6b\x5a"),
+ '22222222'
+ );
+ }
+
+ public function testBase32Hex()
+ {
+ $this->assertSame(
+ Base32Hex::encode("\x00"),
+ '00======'
+ );
+ $this->assertSame(
+ Base32Hex::encode("\x00\x00"),
+ '0000===='
+ );
+ $this->assertSame(
+ Base32Hex::encode("\x00\x00\x00"),
+ '00000==='
+ );
+ $this->assertSame(
+ Base32Hex::encode("\x00\x00\x00\x00"),
+ '0000000='
+ );
+ $this->assertSame(
+ Base32Hex::encode("\x00\x00\x00\x00\x00"),
+ '00000000'
+ );
+ $this->assertSame(
+ Base32Hex::encode("\x00\x00\x0F\xFF\xFF"),
+ '0000vvvv'
+ );
+ $this->assertSame(
+ Base32Hex::encode("\xFF\xFF\xF0\x00\x00"),
+ 'vvvv0000'
+ );
+
+
+ }
+
+ /**
+ * Based on test vectors from RFC 4648
+ */
+ public function testBase32Decode()
+ {
+ $this->assertSame(
+ "\x00\x00\x00\x00\x00\x00",
+ Encoding::base32Decode('aaaaaaaaaa======')
+ );
+ $this->assertSame(
+ "\x00\x00\x00\x00\x00\x00\x00",
+ Encoding::base32Decode('aaaaaaaaaaaa====')
+ );
+ $this->assertSame(
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ Encoding::base32Decode('aaaaaaaaaaaaa===')
+ );
+ $this->assertSame(
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ Encoding::base32Decode('aaaaaaaaaaaaaaa=')
+ );
+ $this->assertSame(
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ Encoding::base32Decode('aaaaaaaaaaaaaaaa')
+ );
+ $this->assertSame(
+ "\x00",
+ Encoding::base32Decode('aa======')
+ );
+ $this->assertSame(
+ "\x00\x00",
+ Encoding::base32Decode('aaaa====')
+ );
+ $this->assertSame(
+ "\x00\x00\x00",
+ Encoding::base32Decode('aaaaa===')
+ );
+ $this->assertSame(
+ "\x00\x00\x00\x00",
+ Encoding::base32Decode('aaaaaaa=')
+ );
+ $this->assertSame(
+ "\x00\x00\x00\x00\x00",
+ Encoding::base32Decode('aaaaaaaa')
+ );
+ $this->assertSame(
+ "\x00\x00\x0F\xFF\xFF",
+ Encoding::base32Decode('aaaa7777')
+ );
+ $this->assertSame(
+ "\xFF\xFF\xF0\x00\x00",
+ Encoding::base32Decode('7777aaaa')
+ );
+ $this->assertSame(
+ "\xce\x73\x9c\xe7\x39",
+ Encoding::base32Decode('zzzzzzzz')
+ );
+ $this->assertSame(
+ "\xd6\xb5\xad\x6b\x5a",
+ Encoding::base32Decode('22222222')
+ );
+ $this->assertSame(
+ 'foobar',
+ Encoding::base32Decode('mzxw6ytboi======')
+ );
+
+ $rand = random_bytes(9);
+ $enc = Encoding::base32Encode($rand);
+
+ $this->assertSame(
+ Encoding::base32Encode($rand),
+ Encoding::base32Encode(Encoding::base32Decode($enc))
+ );
+ $this->assertSame(
+ $rand,
+ Encoding::base32Decode($enc)
+ );
+ }
+
+ /**
+ * @covers Encoding::hexDecode()
+ * @covers Encoding::hexEncode()
+ * @covers Encoding::base32Decode()
+ * @covers Encoding::base32Encode()
+ * @covers Encoding::base64Decode()
+ * @covers Encoding::base64Encode()
+ * @covers Encoding::base64DotSlashDecode()
+ * @covers Encoding::base64DotSlashEncode()
+ * @covers Encoding::base64DotSlashOrderedDecode()
+ * @covers Encoding::base64DotSlashOrderedEncode()
+ */
+ public function testBasicEncoding()
+ {
+ // Re-run the test at least 3 times for each length
+ for ($j = 0; $j < 3; ++$j) {
+ for ($i = 1; $i < 84; ++$i) {
+ $rand = random_bytes($i);
+ $enc = Encoding::hexEncode($rand);
+ $this->assertSame(
+ \bin2hex($rand),
+ $enc,
+ "Hex Encoding - Length: " . $i
+ );
+ $this->assertSame(
+ $rand,
+ Encoding::hexDecode($enc),
+ "Hex Encoding - Length: " . $i
+ );
+
+ // Uppercase variant:
+ $enc = Hex::encodeUpper($rand);
+ $this->assertSame(
+ \strtoupper(\bin2hex($rand)),
+ $enc,
+ "Hex Encoding - Length: " . $i
+ );
+ $this->assertSame(
+ $rand,
+ Hex::decode($enc),
+ "HexUpper Encoding - Length: " . $i
+ );
+
+ $enc = Encoding::base32Encode($rand);
+ $this->assertSame(
+ $rand,
+ Encoding::base32Decode($enc),
+ "Base32 Encoding - Length: " . $i
+ );
+
+ $enc = Encoding::base32EncodeUpper($rand);
+ $this->assertSame(
+ $rand,
+ Encoding::base32DecodeUpper($enc),
+ "Base32Upper Encoding - Length: " . $i
+ );
+
+ $enc = Encoding::base32HexEncode($rand);
+ $this->assertSame(
+ bin2hex($rand),
+ bin2hex(Encoding::base32HexDecode($enc)),
+ "Base32Hex Encoding - Length: " . $i
+ );
+
+ $enc = Encoding::base32HexEncodeUpper($rand);
+ $this->assertSame(
+ bin2hex($rand),
+ bin2hex(Encoding::base32HexDecodeUpper($enc)),
+ "Base32HexUpper Encoding - Length: " . $i
+ );
+
+ $enc = Encoding::base64Encode($rand);
+ $this->assertSame(
+ $rand,
+ Encoding::base64Decode($enc),
+ "Base64 Encoding - Length: " . $i
+ );
+
+ $enc = Encoding::base64EncodeDotSlash($rand);
+ $this->assertSame(
+ $rand,
+ Encoding::base64DecodeDotSlash($enc),
+ "Base64 DotSlash Encoding - Length: " . $i
+ );
+ $enc = Encoding::base64EncodeDotSlashOrdered($rand);
+ $this->assertSame(
+ $rand,
+ Encoding::base64DecodeDotSlashOrdered($enc),
+ "Base64 Ordered DotSlash Encoding - Length: " . $i
+ );
+
+ $enc = Base64UrlSafe::encode($rand);
+ $this->assertSame(
+ \strtr(\base64_encode($rand), '+/', '-_'),
+ $enc
+ );
+ $this->assertSame(
+ $rand,
+ Base64UrlSafe::decode($enc)
+ );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/vendor/paragonie/constant_time_encoding/tests/HexTest.php b/vendor/paragonie/constant_time_encoding/tests/HexTest.php
new file mode 100644
index 000000000..5c31f6d15
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/tests/HexTest.php
@@ -0,0 +1,39 @@
+assertSame(
+ $random,
+ Hex::decode($enc)
+ );
+ $this->assertSame(
+ \bin2hex($random),
+ $enc
+ );
+
+ $enc = Hex::encodeUpper($random);
+ $this->assertSame(
+ $random,
+ Hex::decode($enc)
+ );
+ $this->assertSame(
+ \strtoupper(\bin2hex($random)),
+ $enc
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/paragonie/constant_time_encoding/tests/RFC4648Test.php b/vendor/paragonie/constant_time_encoding/tests/RFC4648Test.php
new file mode 100644
index 000000000..a6653de88
--- /dev/null
+++ b/vendor/paragonie/constant_time_encoding/tests/RFC4648Test.php
@@ -0,0 +1,84 @@
+assertSame(Base64::encode(''), '');
+ $this->assertSame(Base64::encode('f'), 'Zg==');
+ $this->assertSame(Base64::encode('fo'), 'Zm8=');
+ $this->assertSame(Base64::encode('foo'), 'Zm9v');
+ $this->assertSame(Base64::encode('foob'), 'Zm9vYg==');
+ $this->assertSame(Base64::encode('fooba'), 'Zm9vYmE=');
+ $this->assertSame(Base64::encode('foobar'), 'Zm9vYmFy');
+ }
+
+ public function testVectorBase32()
+ {
+ $this->assertSame(Base32::encode(''), '');
+ $this->assertSame(Base32::encode('f'), 'my======');
+ $this->assertSame(Base32::encode('fo'), 'mzxq====');
+ $this->assertSame(Base32::encode('foo'), 'mzxw6===');
+ $this->assertSame(Base32::encode('foob'), 'mzxw6yq=');
+ $this->assertSame(Base32::encode('fooba'), 'mzxw6ytb');
+ $this->assertSame(Base32::encode('foobar'), 'mzxw6ytboi======');
+
+ $this->assertSame(Base32::encodeUpper(''), '');
+ $this->assertSame(Base32::encodeUpper('f'), 'MY======');
+ $this->assertSame(Base32::encodeUpper('fo'), 'MZXQ====');
+ $this->assertSame(Base32::encodeUpper('foo'), 'MZXW6===');
+ $this->assertSame(Base32::encodeUpper('foob'), 'MZXW6YQ=');
+ $this->assertSame(Base32::encodeUpper('fooba'), 'MZXW6YTB');
+ $this->assertSame(Base32::encodeUpper('foobar'), 'MZXW6YTBOI======');
+ }
+
+ public function testVectorBase32Hex()
+ {
+ $this->assertSame(Base32Hex::encode(''), '');
+ $this->assertSame(Base32Hex::encode('f'), 'co======');
+ $this->assertSame(Base32Hex::encode('fo'), 'cpng====');
+ $this->assertSame(Base32Hex::encode('foo'), 'cpnmu===');
+ $this->assertSame(Base32Hex::encode('foob'), 'cpnmuog=');
+ $this->assertSame(Base32Hex::encode('fooba'), 'cpnmuoj1');
+ $this->assertSame(Base32Hex::encode('foobar'), 'cpnmuoj1e8======');
+
+ $this->assertSame(Base32Hex::encodeUpper(''), '');
+ $this->assertSame(Base32Hex::encodeUpper('f'), 'CO======');
+ $this->assertSame(Base32Hex::encodeUpper('fo'), 'CPNG====');
+ $this->assertSame(Base32Hex::encodeUpper('foo'), 'CPNMU===');
+ $this->assertSame(Base32Hex::encodeUpper('foob'), 'CPNMUOG=');
+ $this->assertSame(Base32Hex::encodeUpper('fooba'), 'CPNMUOJ1');
+ $this->assertSame(Base32Hex::encodeUpper('foobar'), 'CPNMUOJ1E8======');
+ }
+
+ public function testVectorBase16()
+ {
+ $this->assertSame(Hex::encode(''), '');
+ $this->assertSame(Hex::encode('f'), '66');
+ $this->assertSame(Hex::encode('fo'), '666f');
+ $this->assertSame(Hex::encode('foo'), '666f6f');
+ $this->assertSame(Hex::encode('foob'), '666f6f62');
+ $this->assertSame(Hex::encode('fooba'), '666f6f6261');
+ $this->assertSame(Hex::encode('foobar'), '666f6f626172');
+
+ $this->assertSame(Hex::encodeUpper(''), '');
+ $this->assertSame(Hex::encodeUpper('f'), '66');
+ $this->assertSame(Hex::encodeUpper('fo'), '666F');
+ $this->assertSame(Hex::encodeUpper('foo'), '666F6F');
+ $this->assertSame(Hex::encodeUpper('foob'), '666F6F62');
+ $this->assertSame(Hex::encodeUpper('fooba'), '666F6F6261');
+ $this->assertSame(Hex::encodeUpper('foobar'), '666F6F626172');
+ }
+}
diff --git a/vendor/spomky-labs/otphp/.github/CONTRIBUTING.md b/vendor/spomky-labs/otphp/.github/CONTRIBUTING.md
new file mode 100644
index 000000000..871735ad1
--- /dev/null
+++ b/vendor/spomky-labs/otphp/.github/CONTRIBUTING.md
@@ -0,0 +1,25 @@
+# Contributing
+
+First of all, **thank you** for contributing.
+
+Bugs or feature requests can be posted online on the GitHub issues section of the project.
+
+Few rules to ease code reviews and merges:
+
+- You MUST follow the [PSR-1](http://www.php-fig.org/psr/psr-1/), [PSR-2](http://www.php-fig.org/psr/psr-2/) and [PSR-4](http://www.php-fig.org/psr/psr-4/) coding standards.
+- You MUST run the test suite.
+- You MUST write (or update) unit tests when bugs are fixed or features are added.
+- You SHOULD write documentation.
+
+We use [Git-Flow](http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/) to automate our git branching workflow.
+
+To contribute use [Pull Requests](https://help.github.com/articles/using-pull-requests), please, write commit messages that make sense, and rebase your branch before submitting your PR.
+
+May be asked to squash your commits too. This is used to "clean" your Pull Request before merging it, avoiding commits such as fix tests, fix 2, fix 3, etc.
+
+Run test suite
+------------
+
+* install composer: `curl -s http://getcomposer.org/installer | php`
+* install dependencies: `php composer.phar install`
+* run tests: `vendor/bin/phpunit`
diff --git a/vendor/spomky-labs/otphp/.github/ISSUE_TEMPLATE.md b/vendor/spomky-labs/otphp/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..2ceb8da6a
--- /dev/null
+++ b/vendor/spomky-labs/otphp/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,16 @@
+| Q | A
+| -------------------- | -----
+| Bug report? | yes/no
+| Feature request? | yes/no
+| BC Break report? | yes/no
+| RFC? / Specification | yes/no
+| Library version | x.y(.z)
+
+
diff --git a/vendor/spomky-labs/otphp/.github/PULL_REQUEST_TEMPLATE.md b/vendor/spomky-labs/otphp/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..acd0be9fc
--- /dev/null
+++ b/vendor/spomky-labs/otphp/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,21 @@
+| Q | A
+| ------------- | ---
+| Branch? | master
+| Bug fix? | yes/no
+| New feature? | yes/no
+| BC breaks? | yes/no
+| Deprecations? | yes/no
+| Tests pass? | yes/no
+| Fixed tickets | #...
+| License | MIT
+| Tests added |
+| Doc PR |
+
+
diff --git a/vendor/spomky-labs/otphp/.github/stale.yml b/vendor/spomky-labs/otphp/.github/stale.yml
new file mode 100644
index 000000000..dc90e5a1c
--- /dev/null
+++ b/vendor/spomky-labs/otphp/.github/stale.yml
@@ -0,0 +1,17 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 60
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 7
+# Issues with these labels will never be considered stale
+exemptLabels:
+ - pinned
+ - security
+# Label to use when marking an issue as stale
+staleLabel: wontfix
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ This issue has been automatically marked as stale because it has not had
+ recent activity. It will be closed if no further activity occurs. Thank you
+ for your contributions.
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: false
diff --git a/vendor/spomky-labs/otphp/.php_cs.dist b/vendor/spomky-labs/otphp/.php_cs.dist
new file mode 100644
index 000000000..7410dff65
--- /dev/null
+++ b/vendor/spomky-labs/otphp/.php_cs.dist
@@ -0,0 +1,61 @@
+in(__DIR__.'/src')
+ ->in(__DIR__.'/tests')
+;
+
+return PhpCsFixer\Config::create()
+ ->setRules([
+ '@PSR1' => true,
+ '@PSR2' => true,
+ '@Symfony' => true,
+ '@DoctrineAnnotation' => true,
+ '@PHP70Migration' => true,
+ '@PHP71Migration' => true,
+ 'strict_param' => true,
+ 'strict_comparison' => true,
+ 'array_syntax' => ['syntax' => 'short'],
+ 'array_indentation' => true,
+ 'ordered_imports' => true,
+ 'protected_to_private' => true,
+ 'declare_strict_types' => true,
+ 'native_function_invocation' => [
+ 'include' => ['@compiler_optimized'],
+ 'scope' => 'namespaced',
+ ],
+ 'mb_str_functions' => true,
+ 'method_chaining_indentation' => true,
+ 'linebreak_after_opening_tag' => true,
+ 'combine_consecutive_issets' => true,
+ 'combine_consecutive_unsets' => true,
+ 'compact_nullable_typehint' => true,
+ 'no_superfluous_phpdoc_tags' => true,
+ 'no_superfluous_elseif' => true,
+ 'phpdoc_trim_consecutive_blank_line_separation' => true,
+ 'phpdoc_order' => true,
+ 'pow_to_exponentiation' => true,
+ 'simplified_null_return' => true,
+ 'header_comment' => [
+ 'header' => $header,
+ ],
+ 'align_multiline_comment' => [
+ 'comment_type' => 'all_multiline',
+ ],
+ 'php_unit_test_annotation' => [
+ 'case' => 'snake',
+ 'style' => 'annotation',
+ ],
+ 'php_unit_test_case_static_method_calls' => true,
+ ])
+ ->setRiskyAllowed(true)
+ ->setUsingCache(true)
+ ->setFinder($finder)
+ ;
diff --git a/vendor/spomky-labs/otphp/CODE_OF_CONDUCT.md b/vendor/spomky-labs/otphp/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..4ec12c72b
--- /dev/null
+++ b/vendor/spomky-labs/otphp/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@spomky-labs.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/vendor/spomky-labs/otphp/LICENSE b/vendor/spomky-labs/otphp/LICENSE
new file mode 100644
index 000000000..e6a673e34
--- /dev/null
+++ b/vendor/spomky-labs/otphp/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2014-2016 Florent Morselli
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/spomky-labs/otphp/composer.json b/vendor/spomky-labs/otphp/composer.json
new file mode 100644
index 000000000..8979e8f06
--- /dev/null
+++ b/vendor/spomky-labs/otphp/composer.json
@@ -0,0 +1,50 @@
+{
+ "name": "spomky-labs/otphp",
+ "type": "library",
+ "description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator",
+ "license": "MIT",
+ "keywords": ["otp", "hotp", "totp", "RFC 4226", "RFC 6238", "Google Authenticator", "FreeOTP"],
+ "homepage": "https://github.com/Spomky-Labs/otphp",
+ "authors": [
+ {
+ "name": "Florent Morselli",
+ "homepage": "https://github.com/Spomky"
+ },
+ {
+ "name": "All contributors",
+ "homepage": "https://github.com/Spomky-Labs/otphp/contributors"
+ }
+ ],
+ "require": {
+ "php": "^7.2|^8.0",
+ "ext-mbstring": "*",
+ "paragonie/constant_time_encoding": "^2.0",
+ "beberlei/assert": "^3.0",
+ "thecodingmachine/safe": "^0.1.14|^1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^8.0",
+ "php-coveralls/php-coveralls": "^2.0",
+ "phpstan/phpstan": "^0.12",
+ "phpstan/phpstan-beberlei-assert": "^0.12",
+ "phpstan/phpstan-deprecation-rules": "^0.12",
+ "phpstan/phpstan-phpunit": "^0.12",
+ "phpstan/phpstan-strict-rules": "^0.12",
+ "thecodingmachine/phpstan-safe-rule": "^1.0"
+ },
+ "suggest": {
+ },
+ "autoload": {
+ "psr-4": { "OTPHP\\": "src/" }
+ },
+ "autoload-dev": {
+ "psr-4": { "OTPHP\\Test\\": "tests/" }
+ },
+ "extra": {
+ "branch-alias": {
+ "v10.0": "10.0.x-dev",
+ "v9.0": "9.0.x-dev",
+ "v8.3": "8.3.x-dev"
+ }
+ }
+}
diff --git a/vendor/spomky-labs/otphp/phpstan.neon b/vendor/spomky-labs/otphp/phpstan.neon
new file mode 100644
index 000000000..c9be89623
--- /dev/null
+++ b/vendor/spomky-labs/otphp/phpstan.neon
@@ -0,0 +1,13 @@
+parameters:
+ level: 7
+ paths:
+ - src
+ - tests
+ ignoreErrors:
+ - '#Variable property access on \$this\(OTPHP\\OTP\)\.#'
+includes:
+ - vendor/phpstan/phpstan-strict-rules/rules.neon
+ - vendor/phpstan/phpstan-phpunit/extension.neon
+ - vendor/phpstan/phpstan-deprecation-rules/rules.neon
+ - vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon
+ - vendor/phpstan/phpstan-beberlei-assert/extension.neon
diff --git a/vendor/spomky-labs/otphp/src/Factory.php b/vendor/spomky-labs/otphp/src/Factory.php
new file mode 100644
index 000000000..70df63945
--- /dev/null
+++ b/vendor/spomky-labs/otphp/src/Factory.php
@@ -0,0 +1,115 @@
+getCode(), $throwable);
+ }
+ Assertion::isArray($parsed_url, 'Not a valid OTP provisioning URI');
+ self::checkData($parsed_url);
+
+ $otp = self::createOTP($parsed_url);
+
+ self::populateOTP($otp, $parsed_url);
+
+ return $otp;
+ }
+
+ /**
+ * @param array $data
+ */
+ private static function populateParameters(OTPInterface &$otp, array $data): void
+ {
+ foreach ($data['query'] as $key => $value) {
+ $otp->setParameter($key, $value);
+ }
+ }
+
+ /**
+ * @param array $data
+ */
+ private static function populateOTP(OTPInterface &$otp, array $data): void
+ {
+ self::populateParameters($otp, $data);
+ $result = explode(':', rawurldecode(mb_substr($data['path'], 1)));
+
+ if (2 > \count($result)) {
+ $otp->setIssuerIncludedAsParameter(false);
+
+ return;
+ }
+
+ if (null !== $otp->getIssuer()) {
+ Assertion::eq($result[0], $otp->getIssuer(), 'Invalid OTP: invalid issuer in parameter');
+ $otp->setIssuerIncludedAsParameter(true);
+ }
+ $otp->setIssuer($result[0]);
+ }
+
+ /**
+ * @param array $data
+ */
+ private static function checkData(array &$data): void
+ {
+ foreach (['scheme', 'host', 'path', 'query'] as $key) {
+ Assertion::keyExists($data, $key, 'Not a valid OTP provisioning URI');
+ }
+ Assertion::eq('otpauth', $data['scheme'], 'Not a valid OTP provisioning URI');
+ parse_str($data['query'], $data['query']);
+ Assertion::keyExists($data['query'], 'secret', 'Not a valid OTP provisioning URI');
+ }
+
+ /**
+ * @param array $parsed_url
+ */
+ private static function createOTP(array $parsed_url): OTPInterface
+ {
+ switch ($parsed_url['host']) {
+ case 'totp':
+ $totp = TOTP::create($parsed_url['query']['secret']);
+ $totp->setLabel(self::getLabel($parsed_url['path']));
+
+ return $totp;
+ case 'hotp':
+ $hotp = HOTP::create($parsed_url['query']['secret']);
+ $hotp->setLabel(self::getLabel($parsed_url['path']));
+
+ return $hotp;
+ default:
+ throw new InvalidArgumentException(sprintf('Unsupported "%s" OTP type', $parsed_url['host']));
+ }
+ }
+
+ private static function getLabel(string $data): string
+ {
+ $result = explode(':', rawurldecode(mb_substr($data, 1)));
+
+ return 2 === \count($result) ? $result[1] : $result[0];
+ }
+}
diff --git a/vendor/spomky-labs/otphp/src/FactoryInterface.php b/vendor/spomky-labs/otphp/src/FactoryInterface.php
new file mode 100644
index 000000000..00acc2d04
--- /dev/null
+++ b/vendor/spomky-labs/otphp/src/FactoryInterface.php
@@ -0,0 +1,23 @@
+setCounter($counter);
+ }
+
+ public static function create(?string $secret = null, int $counter = 0, string $digest = 'sha1', int $digits = 6): HOTPInterface
+ {
+ return new self($secret, $counter, $digest, $digits);
+ }
+
+ protected function setCounter(int $counter): void
+ {
+ $this->setParameter('counter', $counter);
+ }
+
+ public function getCounter(): int
+ {
+ return $this->getParameter('counter');
+ }
+
+ private function updateCounter(int $counter): void
+ {
+ $this->setCounter($counter);
+ }
+
+ public function getProvisioningUri(): string
+ {
+ return $this->generateURI('hotp', ['counter' => $this->getCounter()]);
+ }
+
+ /**
+ * If the counter is not provided, the OTP is verified at the actual counter.
+ */
+ public function verify(string $otp, ?int $counter = null, ?int $window = null): bool
+ {
+ Assertion::greaterOrEqualThan($counter, 0, 'The counter must be at least 0.');
+
+ if (null === $counter) {
+ $counter = $this->getCounter();
+ } elseif ($counter < $this->getCounter()) {
+ return false;
+ }
+
+ return $this->verifyOtpWithWindow($otp, $counter, $window);
+ }
+
+ private function getWindow(?int $window): int
+ {
+ return abs($window ?? 0);
+ }
+
+ private function verifyOtpWithWindow(string $otp, int $counter, ?int $window): bool
+ {
+ $window = $this->getWindow($window);
+
+ for ($i = $counter; $i <= $counter + $window; ++$i) {
+ if ($this->compareOTP($this->at($i), $otp)) {
+ $this->updateCounter($i + 1);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @return array
+ */
+ protected function getParameterMap(): array
+ {
+ $v = array_merge(
+ parent::getParameterMap(),
+ ['counter' => function ($value): int {
+ Assertion::greaterOrEqualThan((int) $value, 0, 'Counter must be at least 0.');
+
+ return (int) $value;
+ }]
+ );
+
+ return $v;
+ }
+}
diff --git a/vendor/spomky-labs/otphp/src/HOTPInterface.php b/vendor/spomky-labs/otphp/src/HOTPInterface.php
new file mode 100644
index 000000000..336ce1055
--- /dev/null
+++ b/vendor/spomky-labs/otphp/src/HOTPInterface.php
@@ -0,0 +1,29 @@
+setSecret($secret);
+ $this->setDigest($digest);
+ $this->setDigits($digits);
+ }
+
+ public function getQrCodeUri(string $uri, string $placeholder): string
+ {
+ $provisioning_uri = urlencode($this->getProvisioningUri());
+
+ return str_replace($placeholder, $provisioning_uri, $uri);
+ }
+
+ /**
+ * The OTP at the specified input.
+ */
+ protected function generateOTP(int $input): string
+ {
+ $hash = hash_hmac($this->getDigest(), $this->intToByteString($input), $this->getDecodedSecret(), true);
+
+ $hmac = array_values(unpack('C*', $hash));
+
+ $offset = ($hmac[\count($hmac) - 1] & 0xF);
+ $code = ($hmac[$offset + 0] & 0x7F) << 24 | ($hmac[$offset + 1] & 0xFF) << 16 | ($hmac[$offset + 2] & 0xFF) << 8 | ($hmac[$offset + 3] & 0xFF);
+ $otp = $code % (10 ** $this->getDigits());
+
+ return str_pad((string) $otp, $this->getDigits(), '0', STR_PAD_LEFT);
+ }
+
+ public function at(int $timestamp): string
+ {
+ return $this->generateOTP($timestamp);
+ }
+
+ /**
+ * @param array $options
+ */
+ protected function filterOptions(array &$options): void
+ {
+ foreach (['algorithm' => 'sha1', 'period' => 30, 'digits' => 6] as $key => $default) {
+ if (isset($options[$key]) && $default === $options[$key]) {
+ unset($options[$key]);
+ }
+ }
+
+ ksort($options);
+ }
+
+ /**
+ * @param array $options
+ */
+ protected function generateURI(string $type, array $options): string
+ {
+ $label = $this->getLabel();
+ Assertion::string($label, 'The label is not set.');
+ Assertion::false($this->hasColon($label), 'Label must not contain a colon.');
+ $options = array_merge($options, $this->getParameters());
+ $this->filterOptions($options);
+ $params = str_replace(['+', '%7E'], ['%20', '~'], http_build_query($options));
+
+ return sprintf('otpauth://%s/%s?%s', $type, rawurlencode((null !== $this->getIssuer() ? $this->getIssuer().':' : '').$label), $params);
+ }
+
+ private function getDecodedSecret(): string
+ {
+ try {
+ return Base32::decodeUpper($this->getSecret());
+ } catch (\Exception $e) {
+ throw new RuntimeException('Unable to decode the secret. Is it correctly base32 encoded?');
+ }
+ }
+
+ private function intToByteString(int $int): string
+ {
+ $result = [];
+ while (0 !== $int) {
+ $result[] = \chr($int & 0xFF);
+ $int >>= 8;
+ }
+
+ return str_pad(implode(array_reverse($result)), 8, "\000", STR_PAD_LEFT);
+ }
+
+ protected function compareOTP(string $safe, string $user): bool
+ {
+ return hash_equals($safe, $user);
+ }
+}
diff --git a/vendor/spomky-labs/otphp/src/OTPInterface.php b/vendor/spomky-labs/otphp/src/OTPInterface.php
new file mode 100644
index 000000000..66e163d5d
--- /dev/null
+++ b/vendor/spomky-labs/otphp/src/OTPInterface.php
@@ -0,0 +1,97 @@
+
+ */
+ public function getParameters(): array;
+
+ /**
+ * @param mixed|null $value
+ */
+ public function setParameter(string $parameter, $value): void;
+
+ /**
+ * Get the provisioning URI.
+ */
+ public function getProvisioningUri(): string;
+
+ /**
+ * Get the provisioning URI.
+ *
+ * @param string $uri The Uri of the QRCode generator with all parameters. This Uri MUST contain a placeholder that will be replaced by the method.
+ * @param string $placeholder the placeholder to be replaced in the QR Code generator URI
+ */
+ public function getQrCodeUri(string $uri, string $placeholder): string;
+}
diff --git a/vendor/spomky-labs/otphp/src/ParameterTrait.php b/vendor/spomky-labs/otphp/src/ParameterTrait.php
new file mode 100644
index 000000000..69fa774db
--- /dev/null
+++ b/vendor/spomky-labs/otphp/src/ParameterTrait.php
@@ -0,0 +1,196 @@
+
+ */
+ private $parameters = [];
+
+ /**
+ * @var string|null
+ */
+ private $issuer;
+
+ /**
+ * @var string|null
+ */
+ private $label;
+
+ /**
+ * @var bool
+ */
+ private $issuer_included_as_parameter = true;
+
+ /**
+ * @return array
+ */
+ public function getParameters(): array
+ {
+ $parameters = $this->parameters;
+
+ if (null !== $this->getIssuer() && true === $this->isIssuerIncludedAsParameter()) {
+ $parameters['issuer'] = $this->getIssuer();
+ }
+
+ return $parameters;
+ }
+
+ public function getSecret(): string
+ {
+ return $this->getParameter('secret');
+ }
+
+ private function setSecret(?string $secret): void
+ {
+ $this->setParameter('secret', $secret);
+ }
+
+ public function getLabel(): ?string
+ {
+ return $this->label;
+ }
+
+ public function setLabel(string $label): void
+ {
+ $this->setParameter('label', $label);
+ }
+
+ public function getIssuer(): ?string
+ {
+ return $this->issuer;
+ }
+
+ public function setIssuer(string $issuer): void
+ {
+ $this->setParameter('issuer', $issuer);
+ }
+
+ public function isIssuerIncludedAsParameter(): bool
+ {
+ return $this->issuer_included_as_parameter;
+ }
+
+ public function setIssuerIncludedAsParameter(bool $issuer_included_as_parameter): void
+ {
+ $this->issuer_included_as_parameter = $issuer_included_as_parameter;
+ }
+
+ public function getDigits(): int
+ {
+ return $this->getParameter('digits');
+ }
+
+ private function setDigits(int $digits): void
+ {
+ $this->setParameter('digits', $digits);
+ }
+
+ public function getDigest(): string
+ {
+ return $this->getParameter('algorithm');
+ }
+
+ private function setDigest(string $digest): void
+ {
+ $this->setParameter('algorithm', $digest);
+ }
+
+ public function hasParameter(string $parameter): bool
+ {
+ return \array_key_exists($parameter, $this->parameters);
+ }
+
+ public function getParameter(string $parameter)
+ {
+ if ($this->hasParameter($parameter)) {
+ return $this->getParameters()[$parameter];
+ }
+
+ throw new InvalidArgumentException(sprintf('Parameter "%s" does not exist', $parameter));
+ }
+
+ public function setParameter(string $parameter, $value): void
+ {
+ $map = $this->getParameterMap();
+
+ if (true === \array_key_exists($parameter, $map)) {
+ $callback = $map[$parameter];
+ $value = $callback($value);
+ }
+
+ if (property_exists($this, $parameter)) {
+ $this->$parameter = $value;
+ } else {
+ $this->parameters[$parameter] = $value;
+ }
+ }
+
+ /**
+ * @return array
+ */
+ protected function getParameterMap(): array
+ {
+ return [
+ 'label' => function ($value) {
+ Assertion::false($this->hasColon($value), 'Label must not contain a colon.');
+
+ return $value;
+ },
+ 'secret' => function ($value): string {
+ if (null === $value) {
+ $value = Base32::encodeUpper(random_bytes(64));
+ }
+ $value = trim(mb_strtoupper($value), '=');
+
+ return $value;
+ },
+ 'algorithm' => function ($value): string {
+ $value = mb_strtolower($value);
+ Assertion::inArray($value, hash_algos(), sprintf('The "%s" digest is not supported.', $value));
+
+ return $value;
+ },
+ 'digits' => function ($value): int {
+ Assertion::greaterThan($value, 0, 'Digits must be at least 1.');
+
+ return (int) $value;
+ },
+ 'issuer' => function ($value) {
+ Assertion::false($this->hasColon($value), 'Issuer must not contain a colon.');
+
+ return $value;
+ },
+ ];
+ }
+
+ private function hasColon(string $value): bool
+ {
+ $colons = [':', '%3A', '%3a'];
+ foreach ($colons as $colon) {
+ if (false !== mb_strpos($value, $colon)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/spomky-labs/otphp/src/TOTP.php b/vendor/spomky-labs/otphp/src/TOTP.php
new file mode 100644
index 000000000..588b37f17
--- /dev/null
+++ b/vendor/spomky-labs/otphp/src/TOTP.php
@@ -0,0 +1,159 @@
+setPeriod($period);
+ $this->setEpoch($epoch);
+ }
+
+ public static function create(?string $secret = null, int $period = 30, string $digest = 'sha1', int $digits = 6, int $epoch = 0): TOTPInterface
+ {
+ return new self($secret, $period, $digest, $digits, $epoch);
+ }
+
+ protected function setPeriod(int $period): void
+ {
+ $this->setParameter('period', $period);
+ }
+
+ public function getPeriod(): int
+ {
+ return $this->getParameter('period');
+ }
+
+ private function setEpoch(int $epoch): void
+ {
+ $this->setParameter('epoch', $epoch);
+ }
+
+ public function getEpoch(): int
+ {
+ return $this->getParameter('epoch');
+ }
+
+ public function at(int $timestamp): string
+ {
+ return $this->generateOTP($this->timecode($timestamp));
+ }
+
+ public function now(): string
+ {
+ return $this->at(time());
+ }
+
+ /**
+ * If no timestamp is provided, the OTP is verified at the actual timestamp.
+ */
+ public function verify(string $otp, ?int $timestamp = null, ?int $window = null): bool
+ {
+ $timestamp = $this->getTimestamp($timestamp);
+
+ if (null === $window) {
+ return $this->compareOTP($this->at($timestamp), $otp);
+ }
+
+ return $this->verifyOtpWithWindow($otp, $timestamp, $window);
+ }
+
+ private function verifyOtpWithWindow(string $otp, int $timestamp, int $window): bool
+ {
+ $window = abs($window);
+
+ for ($i = 0; $i <= $window; ++$i) {
+ $next = $i * $this->getPeriod() + $timestamp;
+ $previous = -$i * $this->getPeriod() + $timestamp;
+ $valid = $this->compareOTP($this->at($next), $otp) ||
+ $this->compareOTP($this->at($previous), $otp);
+
+ if ($valid) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private function getTimestamp(?int $timestamp): int
+ {
+ $timestamp = $timestamp ?? time();
+ Assertion::greaterOrEqualThan($timestamp, 0, 'Timestamp must be at least 0.');
+
+ return $timestamp;
+ }
+
+ public function getProvisioningUri(): string
+ {
+ $params = [];
+ if (30 !== $this->getPeriod()) {
+ $params['period'] = $this->getPeriod();
+ }
+
+ if (0 !== $this->getEpoch()) {
+ $params['epoch'] = $this->getEpoch();
+ }
+
+ return $this->generateURI('totp', $params);
+ }
+
+ private function timecode(int $timestamp): int
+ {
+ return (int) floor(($timestamp - $this->getEpoch()) / $this->getPeriod());
+ }
+
+ /**
+ * @return array
+ */
+ protected function getParameterMap(): array
+ {
+ $v = array_merge(
+ parent::getParameterMap(),
+ [
+ 'period' => function ($value): int {
+ Assertion::greaterThan((int) $value, 0, 'Period must be at least 1.');
+
+ return (int) $value;
+ },
+ 'epoch' => function ($value): int {
+ Assertion::greaterOrEqualThan((int) $value, 0, 'Epoch must be greater than or equal to 0.');
+
+ return (int) $value;
+ },
+ ]
+ );
+
+ return $v;
+ }
+
+ /**
+ * @param array $options
+ */
+ protected function filterOptions(array &$options): void
+ {
+ parent::filterOptions($options);
+
+ if (isset($options['epoch']) && 0 === $options['epoch']) {
+ unset($options['epoch']);
+ }
+
+ ksort($options);
+ }
+}
diff --git a/vendor/spomky-labs/otphp/src/TOTPInterface.php b/vendor/spomky-labs/otphp/src/TOTPInterface.php
new file mode 100644
index 000000000..a19fe7c0b
--- /dev/null
+++ b/vendor/spomky-labs/otphp/src/TOTPInterface.php
@@ -0,0 +1,36 @@
+ Yeah... but I must explicitly think about importing the "safe" variant of the function, for each and every file of my application.
+> I'm sure I will forget some "use function" statements!
+
+Fear not! thecodingmachine/safe comes with a PHPStan rule.
+
+Never heard of [PHPStan](https://github.com/phpstan/phpstan) before?
+Check it out, it's an amazing code analyzer for PHP.
+
+Simply install the Safe rule in your PHPStan setup (explained in the "Installation" section) and PHPStan will let you know each time you are using an "unsafe" function.
+
+The code below will trigger this warning:
+
+```php
+$content = file_get_contents('foobar.json');
+```
+
+> Function file_get_contents is unsafe to use. It can return FALSE instead of throwing an exception. Please add 'use function Safe\\file_get_contents;' at the beginning of the file to use the variant provided by the 'thecodingmachine/safe' library.
+
+## Installation
+
+Use composer to install Safe-PHP:
+
+```bash
+$ composer require thecodingmachine/safe
+```
+
+*Highly recommended*: install PHPStan and PHPStan extension:
+
+```bash
+$ composer require --dev thecodingmachine/phpstan-safe-rule
+```
+
+Now, edit your `phpstan.neon` file and add these rules:
+
+```yml
+includes:
+ - vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon
+```
+
+## Automated refactoring
+
+You have a large legacy codebase and want to use "Safe-PHP" functions throughout your project? PHPStan will help you
+find these functions but changing the namespace of the functions one function at a time might be a tedious task.
+
+Fortunately, Safe comes bundled with a "Rector" configuration file. [Rector](https://github.com/rectorphp/rector) is a command-line
+tool that performs instant refactoring of your application.
+
+Run
+
+```bash
+$ composer require --dev rector/rector:^0.7
+```
+
+to install `rector/rector`.
+
+Run
+
+```bash
+vendor/bin/rector process src/ --config vendor/thecodingmachine/safe/rector-migrate-0.7.php
+```
+
+to run `rector/rector`.
+
+*Note:* do not forget to replace "src/" with the path to your source directory.
+
+**Important:** the refactoring only performs a "dumb" replacement of functions. It will not modify the way
+"false" return values are handled. So if your code was already performing error handling, you will have to deal
+with it manually.
+
+Especially, you should look for error handling that was already performed, like:
+
+```php
+if (!mkdir($dirPath)) {
+ // Do something on error
+}
+```
+
+This code will be refactored by Rector to:
+
+```php
+if (!\Safe\mkdir($dirPath)) {
+ // Do something on error
+}
+```
+
+You should then (manually) refactor it to:
+
+```php
+try {
+ \Safe\mkdir($dirPath));
+} catch (\Safe\FilesystemException $e) {
+ // Do something on error
+}
+```
+
+## Performance impact
+
+Safe is loading 1000+ functions from ~85 files on each request. Yet, the performance impact of this loading is quite low.
+
+In case you worry, using Safe will "cost" you ~700µs on each request. The [performance section](performance/README.md)
+contains more information regarding the way we tested the performance impact of Safe.
+
+## Learn more
+
+Read [the release article on TheCodingMachine's blog](https://thecodingmachine.io/introducing-safe-php) if you want to
+learn more about what triggered the development of Safe-PHP.
+
+## Contributing
+
+The files that contain all the functions are auto-generated from the PHP doc.
+Read the [CONTRIBUTING.md](CONTRIBUTING.md) file to learn how to regenerate these files and to contribute to this library.
diff --git a/vendor/thecodingmachine/safe/composer.json b/vendor/thecodingmachine/safe/composer.json
new file mode 100644
index 000000000..2cd03fcc8
--- /dev/null
+++ b/vendor/thecodingmachine/safe/composer.json
@@ -0,0 +1,123 @@
+{
+ "name": "thecodingmachine/safe",
+ "description": "PHP core functions that throw exceptions instead of returning FALSE on error",
+ "license": "MIT",
+ "autoload": {
+ "psr-4": {
+ "Safe\\": [
+ "lib/",
+ "deprecated/",
+ "generated/"
+ ]
+ },
+ "files": [
+ "deprecated/apc.php",
+ "deprecated/libevent.php",
+ "deprecated/mssql.php",
+ "deprecated/stats.php",
+ "lib/special_cases.php",
+ "generated/apache.php",
+ "generated/apcu.php",
+ "generated/array.php",
+ "generated/bzip2.php",
+ "generated/calendar.php",
+ "generated/classobj.php",
+ "generated/com.php",
+ "generated/cubrid.php",
+ "generated/curl.php",
+ "generated/datetime.php",
+ "generated/dir.php",
+ "generated/eio.php",
+ "generated/errorfunc.php",
+ "generated/exec.php",
+ "generated/fileinfo.php",
+ "generated/filesystem.php",
+ "generated/filter.php",
+ "generated/fpm.php",
+ "generated/ftp.php",
+ "generated/funchand.php",
+ "generated/gmp.php",
+ "generated/gnupg.php",
+ "generated/hash.php",
+ "generated/ibase.php",
+ "generated/ibmDb2.php",
+ "generated/iconv.php",
+ "generated/image.php",
+ "generated/imap.php",
+ "generated/info.php",
+ "generated/ingres-ii.php",
+ "generated/inotify.php",
+ "generated/json.php",
+ "generated/ldap.php",
+ "generated/libxml.php",
+ "generated/lzf.php",
+ "generated/mailparse.php",
+ "generated/mbstring.php",
+ "generated/misc.php",
+ "generated/msql.php",
+ "generated/mysql.php",
+ "generated/mysqli.php",
+ "generated/mysqlndMs.php",
+ "generated/mysqlndQc.php",
+ "generated/network.php",
+ "generated/oci8.php",
+ "generated/opcache.php",
+ "generated/openssl.php",
+ "generated/outcontrol.php",
+ "generated/password.php",
+ "generated/pcntl.php",
+ "generated/pcre.php",
+ "generated/pdf.php",
+ "generated/pgsql.php",
+ "generated/posix.php",
+ "generated/ps.php",
+ "generated/pspell.php",
+ "generated/readline.php",
+ "generated/rpminfo.php",
+ "generated/rrd.php",
+ "generated/sem.php",
+ "generated/session.php",
+ "generated/shmop.php",
+ "generated/simplexml.php",
+ "generated/sockets.php",
+ "generated/sodium.php",
+ "generated/solr.php",
+ "generated/spl.php",
+ "generated/sqlsrv.php",
+ "generated/ssdeep.php",
+ "generated/ssh2.php",
+ "generated/stream.php",
+ "generated/strings.php",
+ "generated/swoole.php",
+ "generated/uodbc.php",
+ "generated/uopz.php",
+ "generated/url.php",
+ "generated/var.php",
+ "generated/xdiff.php",
+ "generated/xml.php",
+ "generated/xmlrpc.php",
+ "generated/yaml.php",
+ "generated/yaz.php",
+ "generated/zip.php",
+ "generated/zlib.php"
+ ]
+ },
+ "require": {
+ "php": ">=7.2"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^0.12",
+ "thecodingmachine/phpstan-strict-rules": "^0.12",
+ "squizlabs/php_codesniffer": "^3.2"
+ },
+ "scripts": {
+ "phpstan": "phpstan analyse lib -c phpstan.neon --level=max --no-progress -vvv",
+ "cs-fix": "phpcbf",
+ "cs-check": "phpcs"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.1-dev"
+ }
+ }
+}
\ No newline at end of file
diff --git a/vendor/thecodingmachine/safe/deprecated/Exceptions/ApcException.php b/vendor/thecodingmachine/safe/deprecated/Exceptions/ApcException.php
new file mode 100644
index 000000000..f344490d8
--- /dev/null
+++ b/vendor/thecodingmachine/safe/deprecated/Exceptions/ApcException.php
@@ -0,0 +1,11 @@
+
+ *
+ *
+ *
+ * The mode parameter consists of three octal
+ * number components specifying access restrictions for the owner,
+ * the user group in which the owner is in, and to everybody else in
+ * this order. One component can be computed by adding up the needed
+ * permissions for that target user base. Number 1 means that you
+ * grant execute rights, number 2 means that you make the file
+ * writeable, number 4 means that you make the file readable. Add
+ * up these numbers to specify needed rights. You can also read more
+ * about modes on Unix systems with 'man 1 chmod'
+ * and 'man 2 chmod'.
+ *
+ *
+ *
+ *
+ */
+function chmod(string $filename, int $mode): void
+{
+ error_clear_last();
+ $result = \chmod($filename, $mode);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Attempts to change the owner of the file filename
+ * to user user. Only the superuser may change the
+ * owner of a file.
+ *
+ * @param string $filename Path to the file.
+ * @param string|int $user A user name or number.
+ * @throws FilesystemException
+ *
+ */
+function chown(string $filename, $user): void
+{
+ error_clear_last();
+ $result = \chown($filename, $user);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Makes a copy of the file source to
+ * dest.
+ *
+ * If you wish to move a file, use the rename function.
+ *
+ * @param string $source Path to the source file.
+ * @param string $dest The destination path. If dest is a URL, the
+ * copy operation may fail if the wrapper does not support overwriting of
+ * existing files.
+ *
+ * If the destination file already exists, it will be overwritten.
+ * @param resource $context A valid context resource created with
+ * stream_context_create.
+ * @throws FilesystemException
+ *
+ */
+function copy(string $source, string $dest, $context = null): void
+{
+ error_clear_last();
+ if ($context !== null) {
+ $result = \copy($source, $dest, $context);
+ } else {
+ $result = \copy($source, $dest);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Given a string containing a directory, this function will return the
+ * number of bytes available on the corresponding filesystem or disk
+ * partition.
+ *
+ * @param string $directory A directory of the filesystem or disk partition.
+ *
+ * Given a file name instead of a directory, the behaviour of the
+ * function is unspecified and may differ between operating systems and
+ * PHP versions.
+ * @return float Returns the number of available bytes as a float.
+ * @throws FilesystemException
+ *
+ */
+function disk_free_space(string $directory): float
+{
+ error_clear_last();
+ $result = \disk_free_space($directory);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Given a string containing a directory, this function will return the total
+ * number of bytes on the corresponding filesystem or disk partition.
+ *
+ * @param string $directory A directory of the filesystem or disk partition.
+ * @return float Returns the total number of bytes as a float.
+ * @throws FilesystemException
+ *
+ */
+function disk_total_space(string $directory): float
+{
+ error_clear_last();
+ $result = \disk_total_space($directory);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * The file pointed to by handle is closed.
+ *
+ * @param resource $handle The file pointer must be valid, and must point to a file successfully
+ * opened by fopen or fsockopen.
+ * @throws FilesystemException
+ *
+ */
+function fclose($handle): void
+{
+ error_clear_last();
+ $result = \fclose($handle);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * This function forces a write of all buffered output to the resource
+ * pointed to by the file handle.
+ *
+ * @param resource $handle The file pointer must be valid, and must point to
+ * a file successfully opened by fopen or
+ * fsockopen (and not yet closed by
+ * fclose).
+ * @throws FilesystemException
+ *
+ */
+function fflush($handle): void
+{
+ error_clear_last();
+ $result = \fflush($handle);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * This function is similar to file, except that
+ * file_get_contents returns the file in a
+ * string, starting at the specified offset
+ * up to maxlen bytes. On failure,
+ * file_get_contents will return FALSE.
+ *
+ * file_get_contents is the preferred way to read the
+ * contents of a file into a string. It will use memory mapping techniques if
+ * supported by your OS to enhance performance.
+ *
+ * @param string $filename Name of the file to read.
+ * @param bool $use_include_path The FILE_USE_INCLUDE_PATH constant can be used
+ * to trigger include path
+ * search.
+ * This is not possible if strict typing
+ * is enabled, since FILE_USE_INCLUDE_PATH is an
+ * int. Use TRUE instead.
+ * @param resource|null $context A valid context resource created with
+ * stream_context_create. If you don't need to use a
+ * custom context, you can skip this parameter by NULL.
+ * @param int $offset The offset where the reading starts on the original stream.
+ * Negative offsets count from the end of the stream.
+ *
+ * Seeking (offset) is not supported with remote files.
+ * Attempting to seek on non-local files may work with small offsets, but this
+ * is unpredictable because it works on the buffered stream.
+ * @param int $maxlen Maximum length of data read. The default is to read until end
+ * of file is reached. Note that this parameter is applied to the
+ * stream processed by the filters.
+ * @return string The function returns the read data.
+ * @throws FilesystemException
+ *
+ */
+function file_get_contents(string $filename, bool $use_include_path = false, $context = null, int $offset = 0, int $maxlen = null): string
+{
+ error_clear_last();
+ if ($maxlen !== null) {
+ $result = \file_get_contents($filename, $use_include_path, $context, $offset, $maxlen);
+ } elseif ($offset !== 0) {
+ $result = \file_get_contents($filename, $use_include_path, $context, $offset);
+ } elseif ($context !== null) {
+ $result = \file_get_contents($filename, $use_include_path, $context);
+ } else {
+ $result = \file_get_contents($filename, $use_include_path);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * This function is identical to calling fopen,
+ * fwrite and fclose successively
+ * to write data to a file.
+ *
+ * If filename does not exist, the file is created.
+ * Otherwise, the existing file is overwritten, unless the
+ * FILE_APPEND flag is set.
+ *
+ * @param string $filename Path to the file where to write the data.
+ * @param mixed $data The data to write. Can be either a string, an
+ * array or a stream resource.
+ *
+ * If data is a stream resource, the
+ * remaining buffer of that stream will be copied to the specified file.
+ * This is similar with using stream_copy_to_stream.
+ *
+ * You can also specify the data parameter as a single
+ * dimension array. This is equivalent to
+ * file_put_contents($filename, implode('', $array)).
+ * @param int $flags The value of flags can be any combination of
+ * the following flags, joined with the binary OR (|)
+ * operator.
+ *
+ *
+ * Available flags
+ *
+ *
+ *
+ * Flag
+ * Description
+ *
+ *
+ *
+ *
+ *
+ * FILE_USE_INCLUDE_PATH
+ *
+ *
+ * Search for filename in the include directory.
+ * See include_path for more
+ * information.
+ *
+ *
+ *
+ *
+ * FILE_APPEND
+ *
+ *
+ * If file filename already exists, append
+ * the data to the file instead of overwriting it.
+ *
+ *
+ *
+ *
+ * LOCK_EX
+ *
+ *
+ * Acquire an exclusive lock on the file while proceeding to the
+ * writing. In other words, a flock call happens
+ * between the fopen call and the
+ * fwrite call. This is not identical to an
+ * fopen call with mode "x".
+ *
+ *
+ *
+ *
+ *
+ * @param resource $context A valid context resource created with
+ * stream_context_create.
+ * @return int This function returns the number of bytes that were written to the file.
+ * @throws FilesystemException
+ *
+ */
+function file_put_contents(string $filename, $data, int $flags = 0, $context = null): int
+{
+ error_clear_last();
+ if ($context !== null) {
+ $result = \file_put_contents($filename, $data, $flags, $context);
+ } else {
+ $result = \file_put_contents($filename, $data, $flags);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Reads an entire file into an array.
+ *
+ * @param string $filename Path to the file.
+ * @param int $flags The optional parameter flags can be one, or
+ * more, of the following constants:
+ *
+ *
+ *
+ * FILE_USE_INCLUDE_PATH
+ *
+ *
+ *
+ * Search for the file in the include_path.
+ *
+ *
+ *
+ *
+ *
+ * FILE_IGNORE_NEW_LINES
+ *
+ *
+ *
+ * Omit newline at the end of each array element
+ *
+ *
+ *
+ *
+ *
+ * FILE_SKIP_EMPTY_LINES
+ *
+ *
+ *
+ * Skip empty lines
+ *
+ *
+ *
+ *
+ * @param resource $context
+ * @return array Returns the file in an array. Each element of the array corresponds to a
+ * line in the file, with the newline still attached. Upon failure,
+ * file returns FALSE.
+ * @throws FilesystemException
+ *
+ */
+function file(string $filename, int $flags = 0, $context = null): array
+{
+ error_clear_last();
+ if ($context !== null) {
+ $result = \file($filename, $flags, $context);
+ } else {
+ $result = \file($filename, $flags);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ *
+ *
+ * @param string $filename Path to the file.
+ * @return int Returns the time the file was last accessed.
+ * The time is returned as a Unix timestamp.
+ * @throws FilesystemException
+ *
+ */
+function fileatime(string $filename): int
+{
+ error_clear_last();
+ $result = \fileatime($filename);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Gets the inode change time of a file.
+ *
+ * @param string $filename Path to the file.
+ * @return int Returns the time the file was last changed.
+ * The time is returned as a Unix timestamp.
+ * @throws FilesystemException
+ *
+ */
+function filectime(string $filename): int
+{
+ error_clear_last();
+ $result = \filectime($filename);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Gets the file inode.
+ *
+ * @param string $filename Path to the file.
+ * @return int Returns the inode number of the file.
+ * @throws FilesystemException
+ *
+ */
+function fileinode(string $filename): int
+{
+ error_clear_last();
+ $result = \fileinode($filename);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * This function returns the time when the data blocks of a file were being
+ * written to, that is, the time when the content of the file was changed.
+ *
+ * @param string $filename Path to the file.
+ * @return int Returns the time the file was last modified.
+ * The time is returned as a Unix timestamp, which is
+ * suitable for the date function.
+ * @throws FilesystemException
+ *
+ */
+function filemtime(string $filename): int
+{
+ error_clear_last();
+ $result = \filemtime($filename);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Gets the file owner.
+ *
+ * @param string $filename Path to the file.
+ * @return int Returns the user ID of the owner of the file.
+ * The user ID is returned in numerical format, use
+ * posix_getpwuid to resolve it to a username.
+ * @throws FilesystemException
+ *
+ */
+function fileowner(string $filename): int
+{
+ error_clear_last();
+ $result = \fileowner($filename);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Gets the size for the given file.
+ *
+ * @param string $filename Path to the file.
+ * @return int Returns the size of the file in bytes, or FALSE (and generates an error
+ * of level E_WARNING) in case of an error.
+ * @throws FilesystemException
+ *
+ */
+function filesize(string $filename): int
+{
+ error_clear_last();
+ $result = \filesize($filename);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * flock allows you to perform a simple reader/writer
+ * model which can be used on virtually every platform (including most Unix
+ * derivatives and even Windows).
+ *
+ * On versions of PHP before 5.3.2, the lock is released also by
+ * fclose (which is also called automatically when script
+ * finished).
+ *
+ * PHP supports a portable way of locking complete files in an advisory way
+ * (which means all accessing programs have to use the same way of locking
+ * or it will not work). By default, this function will block until the
+ * requested lock is acquired; this may be controlled with the LOCK_NB option documented below.
+ *
+ * @param resource $handle A file system pointer resource
+ * that is typically created using fopen.
+ * @param int $operation operation is one of the following:
+ *
+ *
+ *
+ * LOCK_SH to acquire a shared lock (reader).
+ *
+ *
+ *
+ *
+ * LOCK_EX to acquire an exclusive lock (writer).
+ *
+ *
+ *
+ *
+ * LOCK_UN to release a lock (shared or exclusive).
+ *
+ *
+ *
+ *
+ * It is also possible to add LOCK_NB as a bitmask to one
+ * of the above operations, if flock should not
+ * block during the locking attempt.
+ * @param int|null $wouldblock The optional third argument is set to 1 if the lock would block
+ * (EWOULDBLOCK errno condition).
+ * @throws FilesystemException
+ *
+ */
+function flock($handle, int $operation, ?int &$wouldblock = null): void
+{
+ error_clear_last();
+ $result = \flock($handle, $operation, $wouldblock);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * fopen binds a named resource, specified by
+ * filename, to a stream.
+ *
+ * @param string $filename If filename is of the form "scheme://...", it
+ * is assumed to be a URL and PHP will search for a protocol handler
+ * (also known as a wrapper) for that scheme. If no wrappers for that
+ * protocol are registered, PHP will emit a notice to help you track
+ * potential problems in your script and then continue as though
+ * filename specifies a regular file.
+ *
+ * If PHP has decided that filename specifies
+ * a local file, then it will try to open a stream on that file.
+ * The file must be accessible to PHP, so you need to ensure that
+ * the file access permissions allow this access.
+ * If you have enabled
+ * open_basedir further
+ * restrictions may apply.
+ *
+ * If PHP has decided that filename specifies
+ * a registered protocol, and that protocol is registered as a
+ * network URL, PHP will check to make sure that
+ * allow_url_fopen is
+ * enabled. If it is switched off, PHP will emit a warning and
+ * the fopen call will fail.
+ *
+ * The list of supported protocols can be found in . Some protocols (also referred to as
+ * wrappers) support context
+ * and/or php.ini options. Refer to the specific page for the
+ * protocol in use for a list of options which can be set. (e.g.
+ * php.ini value user_agent used by the
+ * http wrapper).
+ *
+ * On the Windows platform, be careful to escape any backslashes
+ * used in the path to the file, or use forward slashes.
+ *
+ *
+ *
+ * ]]>
+ *
+ *
+ * @param string $mode The mode parameter specifies the type of access
+ * you require to the stream. It may be any of the following:
+ *
+ *
+ * A list of possible modes for fopen
+ * using mode
+ *
+ *
+ *
+ *
+ * mode
+ * Description
+ *
+ *
+ *
+ *
+ * 'r'
+ *
+ * Open for reading only; place the file pointer at the
+ * beginning of the file.
+ *
+ *
+ *
+ * 'r+'
+ *
+ * Open for reading and writing; place the file pointer at
+ * the beginning of the file.
+ *
+ *
+ *
+ * 'w'
+ *
+ * Open for writing only; place the file pointer at the
+ * beginning of the file and truncate the file to zero length.
+ * If the file does not exist, attempt to create it.
+ *
+ *
+ *
+ * 'w+'
+ *
+ * Open for reading and writing; place the file pointer at
+ * the beginning of the file and truncate the file to zero
+ * length. If the file does not exist, attempt to create it.
+ *
+ *
+ *
+ * 'a'
+ *
+ * Open for writing only; place the file pointer at the end of
+ * the file. If the file does not exist, attempt to create it.
+ * In this mode, fseek has no effect, writes are always appended.
+ *
+ *
+ *
+ * 'a+'
+ *
+ * Open for reading and writing; place the file pointer at
+ * the end of the file. If the file does not exist, attempt to
+ * create it. In this mode, fseek only affects
+ * the reading position, writes are always appended.
+ *
+ *
+ *
+ * 'x'
+ *
+ * Create and open for writing only; place the file pointer at the
+ * beginning of the file. If the file already exists, the
+ * fopen call will fail by returning FALSE and
+ * generating an error of level E_WARNING. If
+ * the file does not exist, attempt to create it. This is equivalent
+ * to specifying O_EXCL|O_CREAT flags for the
+ * underlying open(2) system call.
+ *
+ *
+ *
+ * 'x+'
+ *
+ * Create and open for reading and writing; otherwise it has the
+ * same behavior as 'x'.
+ *
+ *
+ *
+ * 'c'
+ *
+ * Open the file for writing only. If the file does not exist, it is
+ * created. If it exists, it is neither truncated (as opposed to
+ * 'w'), nor the call to this function fails (as is
+ * the case with 'x'). The file pointer is
+ * positioned on the beginning of the file. This may be useful if it's
+ * desired to get an advisory lock (see flock)
+ * before attempting to modify the file, as using
+ * 'w' could truncate the file before the lock
+ * was obtained (if truncation is desired,
+ * ftruncate can be used after the lock is
+ * requested).
+ *
+ *
+ *
+ * 'c+'
+ *
+ * Open the file for reading and writing; otherwise it has the same
+ * behavior as 'c'.
+ *
+ *
+ *
+ * 'e'
+ *
+ * Set close-on-exec flag on the opened file descriptor. Only
+ * available in PHP compiled on POSIX.1-2008 conform systems.
+ *
+ *
+ *
+ *
+ *
+ *
+ * Different operating system families have different line-ending
+ * conventions. When you write a text file and want to insert a line
+ * break, you need to use the correct line-ending character(s) for your
+ * operating system. Unix based systems use \n as the
+ * line ending character, Windows based systems use \r\n
+ * as the line ending characters and Macintosh based systems (Mac OS Classic) used
+ * \r as the line ending character.
+ *
+ * If you use the wrong line ending characters when writing your files, you
+ * might find that other applications that open those files will "look
+ * funny".
+ *
+ * Windows offers a text-mode translation flag ('t')
+ * which will transparently translate \n to
+ * \r\n when working with the file. In contrast, you
+ * can also use 'b' to force binary mode, which will not
+ * translate your data. To use these flags, specify either
+ * 'b' or 't' as the last character
+ * of the mode parameter.
+ *
+ * The default translation mode is 'b'.
+ * You can use the 't'
+ * mode if you are working with plain-text files and you use
+ * \n to delimit your line endings in your script, but
+ * expect your files to be readable with applications such as old versions of notepad. You
+ * should use the 'b' in all other cases.
+ *
+ * If you specify the 't' flag when working with binary files, you
+ * may experience strange problems with your data, including broken image
+ * files and strange problems with \r\n characters.
+ *
+ * For portability, it is also strongly recommended that
+ * you re-write code that uses or relies upon the 't'
+ * mode so that it uses the correct line endings and
+ * 'b' mode instead.
+ * @param bool $use_include_path The optional third use_include_path parameter
+ * can be set to '1' or TRUE if you want to search for the file in the
+ * include_path, too.
+ * @param resource $context
+ * @return resource Returns a file pointer resource on success
+ * @throws FilesystemException
+ *
+ */
+function fopen(string $filename, string $mode, bool $use_include_path = false, $context = null)
+{
+ error_clear_last();
+ if ($context !== null) {
+ $result = \fopen($filename, $mode, $use_include_path, $context);
+ } else {
+ $result = \fopen($filename, $mode, $use_include_path);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * fputcsv formats a line (passed as a
+ * fields array) as CSV and writes it (terminated by a
+ * newline) to the specified file handle.
+ *
+ * @param resource $handle The file pointer must be valid, and must point to
+ * a file successfully opened by fopen or
+ * fsockopen (and not yet closed by
+ * fclose).
+ * @param array $fields An array of strings.
+ * @param string $delimiter The optional delimiter parameter sets the field
+ * delimiter (one character only).
+ * @param string $enclosure The optional enclosure parameter sets the field
+ * enclosure (one character only).
+ * @param string $escape_char The optional escape_char parameter sets the
+ * escape character (at most one character).
+ * An empty string ("") disables the proprietary escape mechanism.
+ * @return int Returns the length of the written string.
+ * @throws FilesystemException
+ *
+ */
+function fputcsv($handle, array $fields, string $delimiter = ",", string $enclosure = '"', string $escape_char = "\\"): int
+{
+ error_clear_last();
+ $result = \fputcsv($handle, $fields, $delimiter, $enclosure, $escape_char);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * fread reads up to
+ * length bytes from the file pointer
+ * referenced by handle. Reading stops as soon as one
+ * of the following conditions is met:
+ *
+ *
+ *
+ * length bytes have been read
+ *
+ *
+ *
+ *
+ * EOF (end of file) is reached
+ *
+ *
+ *
+ *
+ * a packet becomes available or the
+ * socket timeout occurs (for network streams)
+ *
+ *
+ *
+ *
+ * if the stream is read buffered and it does not represent a plain file, at
+ * most one read of up to a number of bytes equal to the chunk size (usually
+ * 8192) is made; depending on the previously buffered data, the size of the
+ * returned data may be larger than the chunk size.
+ *
+ *
+ *
+ *
+ * @param resource $handle A file system pointer resource
+ * that is typically created using fopen.
+ * @param int $length Up to length number of bytes read.
+ * @return string Returns the read string.
+ * @throws FilesystemException
+ *
+ */
+function fread($handle, int $length): string
+{
+ error_clear_last();
+ $result = \fread($handle, $length);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Takes the filepointer, handle, and truncates the file to
+ * length, size.
+ *
+ * @param resource $handle The file pointer.
+ *
+ * The handle must be open for writing.
+ * @param int $size The size to truncate to.
+ *
+ * If size is larger than the file then the file
+ * is extended with null bytes.
+ *
+ * If size is smaller than the file then the file
+ * is truncated to that size.
+ * @throws FilesystemException
+ *
+ */
+function ftruncate($handle, int $size): void
+{
+ error_clear_last();
+ $result = \ftruncate($handle, $size);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ *
+ *
+ * @param resource $handle A file system pointer resource
+ * that is typically created using fopen.
+ * @param string $string The string that is to be written.
+ * @param int $length If the length argument is given, writing will
+ * stop after length bytes have been written or
+ * the end of string is reached, whichever comes
+ * first.
+ *
+ * Note that if the length argument is given,
+ * then the magic_quotes_runtime
+ * configuration option will be ignored and no slashes will be
+ * stripped from string.
+ * @return int
+ * @throws FilesystemException
+ *
+ */
+function fwrite($handle, string $string, int $length = null): int
+{
+ error_clear_last();
+ if ($length !== null) {
+ $result = \fwrite($handle, $string, $length);
+ } else {
+ $result = \fwrite($handle, $string);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * The glob function searches for all the pathnames
+ * matching pattern according to the rules used by
+ * the libc glob() function, which is similar to the rules used by common
+ * shells.
+ *
+ * @param string $pattern The pattern. No tilde expansion or parameter substitution is done.
+ *
+ * Special characters:
+ *
+ *
+ *
+ * * - Matches zero or more characters.
+ *
+ *
+ *
+ *
+ * ? - Matches exactly one character (any character).
+ *
+ *
+ *
+ *
+ * [...] - Matches one character from a group of
+ * characters. If the first character is !,
+ * matches any character not in the group.
+ *
+ *
+ *
+ *
+ * \ - Escapes the following character,
+ * except when the GLOB_NOESCAPE flag is used.
+ *
+ *
+ *
+ * @param int $flags Valid flags:
+ *
+ *
+ *
+ * GLOB_MARK - Adds a slash (a backslash on Windows) to each directory returned
+ *
+ *
+ *
+ *
+ * GLOB_NOSORT - Return files as they appear in the
+ * directory (no sorting). When this flag is not used, the pathnames are
+ * sorted alphabetically
+ *
+ *
+ *
+ *
+ * GLOB_NOCHECK - Return the search pattern if no
+ * files matching it were found
+ *
+ *
+ *
+ *
+ * GLOB_NOESCAPE - Backslashes do not quote
+ * metacharacters
+ *
+ *
+ *
+ *
+ * GLOB_BRACE - Expands {a,b,c} to match 'a', 'b',
+ * or 'c'
+ *
+ *
+ *
+ *
+ * GLOB_ONLYDIR - Return only directory entries
+ * which match the pattern
+ *
+ *
+ *
+ *
+ * GLOB_ERR - Stop on read errors (like unreadable
+ * directories), by default errors are ignored.
+ *
+ *
+ *
+ * @return array Returns an array containing the matched files/directories, an empty array
+ * if no file matched.
+ * @throws FilesystemException
+ *
+ */
+function glob(string $pattern, int $flags = 0): array
+{
+ error_clear_last();
+ $result = \glob($pattern, $flags);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Attempts to change the group of the symlink filename
+ * to group.
+ *
+ * Only the superuser may change the group of a symlink arbitrarily; other
+ * users may change the group of a symlink to any group of which that user is
+ * a member.
+ *
+ * @param string $filename Path to the symlink.
+ * @param string|int $group The group specified by name or number.
+ * @throws FilesystemException
+ *
+ */
+function lchgrp(string $filename, $group): void
+{
+ error_clear_last();
+ $result = \lchgrp($filename, $group);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Attempts to change the owner of the symlink filename
+ * to user user.
+ *
+ * Only the superuser may change the owner of a symlink.
+ *
+ * @param string $filename Path to the file.
+ * @param string|int $user User name or number.
+ * @throws FilesystemException
+ *
+ */
+function lchown(string $filename, $user): void
+{
+ error_clear_last();
+ $result = \lchown($filename, $user);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * link creates a hard link.
+ *
+ * @param string $target Target of the link.
+ * @param string $link The link name.
+ * @throws FilesystemException
+ *
+ */
+function link(string $target, string $link): void
+{
+ error_clear_last();
+ $result = \link($target, $link);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Attempts to create the directory specified by pathname.
+ *
+ * @param string $pathname The directory path.
+ * @param int $mode The mode is 0777 by default, which means the widest possible
+ * access. For more information on modes, read the details
+ * on the chmod page.
+ *
+ * mode is ignored on Windows.
+ *
+ * Note that you probably want to specify the mode as an octal number,
+ * which means it should have a leading zero. The mode is also modified
+ * by the current umask, which you can change using
+ * umask.
+ * @param bool $recursive Allows the creation of nested directories specified in the
+ * pathname.
+ * @param resource $context
+ * @throws FilesystemException
+ *
+ */
+function mkdir(string $pathname, int $mode = 0777, bool $recursive = false, $context = null): void
+{
+ error_clear_last();
+ if ($context !== null) {
+ $result = \mkdir($pathname, $mode, $recursive, $context);
+ } else {
+ $result = \mkdir($pathname, $mode, $recursive);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * parse_ini_file loads in the
+ * ini file specified in filename,
+ * and returns the settings in it in an associative array.
+ *
+ * The structure of the ini file is the same as the php.ini's.
+ *
+ * @param string $filename The filename of the ini file being parsed. If a relative path is used,
+ * it is evaluated relative to the current working directory, then the
+ * include_path.
+ * @param bool $process_sections By setting the process_sections
+ * parameter to TRUE, you get a multidimensional array, with
+ * the section names and settings included. The default
+ * for process_sections is FALSE
+ * @param int $scanner_mode Can either be INI_SCANNER_NORMAL (default) or
+ * INI_SCANNER_RAW. If INI_SCANNER_RAW
+ * is supplied, then option values will not be parsed.
+ *
+ *
+ * As of PHP 5.6.1 can also be specified as INI_SCANNER_TYPED.
+ * In this mode boolean, null and integer types are preserved when possible.
+ * String values "true", "on" and "yes"
+ * are converted to TRUE. "false", "off", "no"
+ * and "none" are considered FALSE. "null" is converted to NULL
+ * in typed mode. Also, all numeric strings are converted to integer type if it is possible.
+ * @return array The settings are returned as an associative array on success.
+ * @throws FilesystemException
+ *
+ */
+function parse_ini_file(string $filename, bool $process_sections = false, int $scanner_mode = INI_SCANNER_NORMAL): array
+{
+ error_clear_last();
+ $result = \parse_ini_file($filename, $process_sections, $scanner_mode);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * parse_ini_string returns the settings in string
+ * ini in an associative array.
+ *
+ * The structure of the ini string is the same as the php.ini's.
+ *
+ * @param string $ini The contents of the ini file being parsed.
+ * @param bool $process_sections By setting the process_sections
+ * parameter to TRUE, you get a multidimensional array, with
+ * the section names and settings included. The default
+ * for process_sections is FALSE
+ * @param int $scanner_mode Can either be INI_SCANNER_NORMAL (default) or
+ * INI_SCANNER_RAW. If INI_SCANNER_RAW
+ * is supplied, then option values will not be parsed.
+ *
+ *
+ * As of PHP 5.6.1 can also be specified as INI_SCANNER_TYPED.
+ * In this mode boolean, null and integer types are preserved when possible.
+ * String values "true", "on" and "yes"
+ * are converted to TRUE. "false", "off", "no"
+ * and "none" are considered FALSE. "null" is converted to NULL
+ * in typed mode. Also, all numeric strings are converted to integer type if it is possible.
+ * @return array The settings are returned as an associative array on success.
+ * @throws FilesystemException
+ *
+ */
+function parse_ini_string(string $ini, bool $process_sections = false, int $scanner_mode = INI_SCANNER_NORMAL): array
+{
+ error_clear_last();
+ $result = \parse_ini_string($ini, $process_sections, $scanner_mode);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Reads a file and writes it to the output buffer.
+ *
+ * @param string $filename The filename being read.
+ * @param bool $use_include_path You can use the optional second parameter and set it to TRUE, if
+ * you want to search for the file in the include_path, too.
+ * @param resource $context A context stream resource.
+ * @return int Returns the number of bytes read from the file on success
+ * @throws FilesystemException
+ *
+ */
+function readfile(string $filename, bool $use_include_path = false, $context = null): int
+{
+ error_clear_last();
+ if ($context !== null) {
+ $result = \readfile($filename, $use_include_path, $context);
+ } else {
+ $result = \readfile($filename, $use_include_path);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * readlink does the same as the readlink C function.
+ *
+ * @param string $path The symbolic link path.
+ * @return string Returns the contents of the symbolic link path.
+ * @throws FilesystemException
+ *
+ */
+function readlink(string $path): string
+{
+ error_clear_last();
+ $result = \readlink($path);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * realpath expands all symbolic links and
+ * resolves references to /./, /../ and extra / characters in
+ * the input path and returns the canonicalized
+ * absolute pathname.
+ *
+ * @param string $path The path being checked.
+ *
+ *
+ * Whilst a path must be supplied, the value can be an empty string.
+ * In this case, the value is interpreted as the current directory.
+ *
+ *
+ *
+ * Whilst a path must be supplied, the value can be an empty string.
+ * In this case, the value is interpreted as the current directory.
+ * @return string Returns the canonicalized absolute pathname on success. The resulting path
+ * will have no symbolic link, /./ or /../ components. Trailing delimiters,
+ * such as \ and /, are also removed.
+ *
+ * realpath returns FALSE on failure, e.g. if
+ * the file does not exist.
+ * @throws FilesystemException
+ *
+ */
+function realpath(string $path): string
+{
+ error_clear_last();
+ $result = \realpath($path);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Attempts to rename oldname to
+ * newname, moving it between directories if necessary.
+ * If renaming a file and newname exists,
+ * it will be overwritten. If renaming a directory and
+ * newname exists,
+ * this function will emit a warning.
+ *
+ * @param string $oldname The old name.
+ *
+ * The wrapper used in oldname
+ * must match the wrapper used in
+ * newname.
+ * @param string $newname The new name.
+ * @param resource $context
+ * @throws FilesystemException
+ *
+ */
+function rename(string $oldname, string $newname, $context = null): void
+{
+ error_clear_last();
+ if ($context !== null) {
+ $result = \rename($oldname, $newname, $context);
+ } else {
+ $result = \rename($oldname, $newname);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Sets the file position indicator for handle
+ * to the beginning of the file stream.
+ *
+ * @param resource $handle The file pointer must be valid, and must point to a file
+ * successfully opened by fopen.
+ * @throws FilesystemException
+ *
+ */
+function rewind($handle): void
+{
+ error_clear_last();
+ $result = \rewind($handle);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Attempts to remove the directory named by dirname.
+ * The directory must be empty, and the relevant permissions must permit this.
+ * A E_WARNING level error will be generated on failure.
+ *
+ * @param string $dirname Path to the directory.
+ * @param resource $context
+ * @throws FilesystemException
+ *
+ */
+function rmdir(string $dirname, $context = null): void
+{
+ error_clear_last();
+ if ($context !== null) {
+ $result = \rmdir($dirname, $context);
+ } else {
+ $result = \rmdir($dirname);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * symlink creates a symbolic link to the existing
+ * target with the specified name
+ * link.
+ *
+ * @param string $target Target of the link.
+ * @param string $link The link name.
+ * @throws FilesystemException
+ *
+ */
+function symlink(string $target, string $link): void
+{
+ error_clear_last();
+ $result = \symlink($target, $link);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Creates a file with a unique filename, with access permission set to 0600, in the specified directory.
+ * If the directory does not exist or is not writable, tempnam may
+ * generate a file in the system's temporary directory, and return
+ * the full path to that file, including its name.
+ *
+ * @param string $dir The directory where the temporary filename will be created.
+ * @param string $prefix The prefix of the generated temporary filename.
+ * @return string Returns the new temporary filename (with path).
+ * @throws FilesystemException
+ *
+ */
+function tempnam(string $dir, string $prefix): string
+{
+ error_clear_last();
+ $result = \tempnam($dir, $prefix);
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Creates a temporary file with a unique name in read-write (w+) mode and
+ * returns a file handle.
+ *
+ * The file is automatically removed when closed (for example, by calling
+ * fclose, or when there are no remaining references to
+ * the file handle returned by tmpfile), or when the
+ * script ends.
+ *
+ * @return resource Returns a file handle, similar to the one returned by
+ * fopen, for the new file.
+ * @throws FilesystemException
+ *
+ */
+function tmpfile()
+{
+ error_clear_last();
+ $result = \tmpfile();
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Attempts to set the access and modification times of the file named in the
+ * filename parameter to the value given in
+ * time.
+ * Note that the access time is always modified, regardless of the number
+ * of parameters.
+ *
+ * If the file does not exist, it will be created.
+ *
+ * @param string $filename The name of the file being touched.
+ * @param int $time The touch time. If time is not supplied,
+ * the current system time is used.
+ * @param int $atime If present, the access time of the given filename is set to
+ * the value of atime. Otherwise, it is set to
+ * the value passed to the time parameter.
+ * If neither are present, the current system time is used.
+ * @throws FilesystemException
+ *
+ */
+function touch(string $filename, int $time = null, int $atime = null): void
+{
+ error_clear_last();
+ if ($atime !== null) {
+ $result = \touch($filename, $time, $atime);
+ } elseif ($time !== null) {
+ $result = \touch($filename, $time);
+ } else {
+ $result = \touch($filename);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Deletes filename. Similar to the Unix C unlink()
+ * function. An E_WARNING level error will be generated on
+ * failure.
+ *
+ * @param string $filename Path to the file.
+ * @param resource $context
+ * @throws FilesystemException
+ *
+ */
+function unlink(string $filename, $context = null): void
+{
+ error_clear_last();
+ if ($context !== null) {
+ $result = \unlink($filename, $context);
+ } else {
+ $result = \unlink($filename);
+ }
+ if ($result === false) {
+ throw FilesystemException::createFromPhpError();
+ }
+}
diff --git a/vendor/thecodingmachine/safe/generated/filter.php b/vendor/thecodingmachine/safe/generated/filter.php
new file mode 100644
index 000000000..2d836c6c9
--- /dev/null
+++ b/vendor/thecodingmachine/safe/generated/filter.php
@@ -0,0 +1,93 @@
+
+ *
+ *
+ *
+ * channels will be 3 for RGB pictures and 4 for CMYK
+ * pictures.
+ *
+ * bits is the number of bits for each color.
+ *
+ * For some image types, the presence of channels and
+ * bits values can be a bit
+ * confusing. As an example, GIF always uses 3 channels
+ * per pixel, but the number of bits per pixel cannot be calculated for an
+ * animated GIF with a global color table.
+ *
+ * On failure, FALSE is returned.
+ * @throws ImageException
+ *
+ */
+function getimagesize(string $filename, array &$imageinfo = null): array
+{
+ error_clear_last();
+ $result = \getimagesize($filename, $imageinfo);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * image2wbmp outputs or save a WBMP
+ * version of the given image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param string|null $filename Path to the saved file. If not given, the raw image stream will be
+ * output directly.
+ * @param int $foreground You can set the foreground color with this parameter by setting an
+ * identifier obtained from imagecolorallocate.
+ * The default foreground color is black.
+ * @throws ImageException
+ *
+ */
+function image2wbmp($image, ?string $filename = null, int $foreground = null): void
+{
+ error_clear_last();
+ if ($foreground !== null) {
+ $result = \image2wbmp($image, $filename, $foreground);
+ } elseif ($filename !== null) {
+ $result = \image2wbmp($image, $filename);
+ } else {
+ $result = \image2wbmp($image);
+ }
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ *
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param array $affine Array with keys 0 to 5.
+ * @param array $clip Array with keys "x", "y", "width" and "height".
+ * @return resource Return affined image resource on success.
+ * @throws ImageException
+ *
+ */
+function imageaffine($image, array $affine, array $clip = null)
+{
+ error_clear_last();
+ if ($clip !== null) {
+ $result = \imageaffine($image, $affine, $clip);
+ } else {
+ $result = \imageaffine($image, $affine);
+ }
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Returns the concatenation of two affine transformation matrices,
+ * what is useful if multiple transformations should be applied to the same
+ * image in one go.
+ *
+ * @param array $m1 An affine transformation matrix (an array with keys
+ * 0 to 5 and float values).
+ * @param array $m2 An affine transformation matrix (an array with keys
+ * 0 to 5 and float values).
+ * @return array{0:float,1:float,2:float,3:float,4:float,5:float} An affine transformation matrix (an array with keys
+ * 0 to 5 and float values).
+ * @throws ImageException
+ *
+ */
+function imageaffinematrixconcat(array $m1, array $m2): array
+{
+ error_clear_last();
+ $result = \imageaffinematrixconcat($m1, $m2);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Returns an affine transformation matrix.
+ *
+ * @param int $type One of the IMG_AFFINE_* constants.
+ * @param array|float $options If type is IMG_AFFINE_TRANSLATE
+ * or IMG_AFFINE_SCALE,
+ * options has to be an array with keys x
+ * and y, both having float values.
+ *
+ * If type is IMG_AFFINE_ROTATE,
+ * IMG_AFFINE_SHEAR_HORIZONTAL or IMG_AFFINE_SHEAR_VERTICAL,
+ * options has to be a float specifying the angle.
+ * @return array{0:float,1:float,2:float,3:float,4:float,5:float} An affine transformation matrix (an array with keys
+ * 0 to 5 and float values).
+ * @throws ImageException
+ *
+ */
+function imageaffinematrixget(int $type, $options = null): array
+{
+ error_clear_last();
+ if ($options !== null) {
+ $result = \imageaffinematrixget($type, $options);
+ } else {
+ $result = \imageaffinematrixget($type);
+ }
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagealphablending allows for two different
+ * modes of drawing on truecolor images. In blending mode, the
+ * alpha channel component of the color supplied to all drawing function,
+ * such as imagesetpixel determines how much of the
+ * underlying color should be allowed to shine through. As a result, gd
+ * automatically blends the existing color at that point with the drawing color,
+ * and stores the result in the image. The resulting pixel is opaque. In
+ * non-blending mode, the drawing color is copied literally with its alpha channel
+ * information, replacing the destination pixel. Blending mode is not available
+ * when drawing on palette images.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param bool $blendmode Whether to enable the blending mode or not. On true color images
+ * the default value is TRUE otherwise the default value is FALSE
+ * @throws ImageException
+ *
+ */
+function imagealphablending($image, bool $blendmode): void
+{
+ error_clear_last();
+ $result = \imagealphablending($image, $blendmode);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Activate the fast drawing antialiased methods for lines and wired polygons.
+ * It does not support alpha components. It works using a direct blend
+ * operation. It works only with truecolor images.
+ *
+ * Thickness and styled are not supported.
+ *
+ * Using antialiased primitives with transparent background color can end with
+ * some unexpected results. The blend method uses the background color as any
+ * other colors. The lack of alpha component support does not allow an alpha
+ * based antialiasing method.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param bool $enabled Whether to enable antialiasing or not.
+ * @throws ImageException
+ *
+ */
+function imageantialias($image, bool $enabled): void
+{
+ error_clear_last();
+ $result = \imageantialias($image, $enabled);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagearc draws an arc of circle centered at the given
+ * coordinates.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $cx x-coordinate of the center.
+ * @param int $cy y-coordinate of the center.
+ * @param int $width The arc width.
+ * @param int $height The arc height.
+ * @param int $start The arc start angle, in degrees.
+ * @param int $end The arc end angle, in degrees.
+ * 0° is located at the three-o'clock position, and the arc is drawn
+ * clockwise.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagearc($image, int $cx, int $cy, int $width, int $height, int $start, int $end, int $color): void
+{
+ error_clear_last();
+ $result = \imagearc($image, $cx, $cy, $width, $height, $start, $end, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Outputs or saves a BMP version of the given image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param mixed $to The path or an open stream resource (which is automatically being closed after this function returns) to save the file to. If not set or NULL, the raw image stream will be outputted directly.
+ *
+ * NULL is invalid if the compressed arguments is
+ * not used.
+ * @param bool $compressed Whether the BMP should be compressed with run-length encoding (RLE), or not.
+ * @throws ImageException
+ *
+ */
+function imagebmp($image, $to = null, bool $compressed = true): void
+{
+ error_clear_last();
+ $result = \imagebmp($image, $to, $compressed);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagechar draws the first character of
+ * c in the image identified by
+ * image with its upper-left at
+ * x,y (top left is 0,
+ * 0) with the color color.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $font Can be 1, 2, 3, 4, 5 for built-in
+ * fonts in latin2 encoding (where higher numbers corresponding to larger fonts) or any of your
+ * own font identifiers registered with imageloadfont.
+ * @param int $x x-coordinate of the start.
+ * @param int $y y-coordinate of the start.
+ * @param string $c The character to draw.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagechar($image, int $font, int $x, int $y, string $c, int $color): void
+{
+ error_clear_last();
+ $result = \imagechar($image, $font, $x, $y, $c, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Draws the character c vertically at the specified
+ * coordinate on the given image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $font Can be 1, 2, 3, 4, 5 for built-in
+ * fonts in latin2 encoding (where higher numbers corresponding to larger fonts) or any of your
+ * own font identifiers registered with imageloadfont.
+ * @param int $x x-coordinate of the start.
+ * @param int $y y-coordinate of the start.
+ * @param string $c The character to draw.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagecharup($image, int $font, int $x, int $y, string $c, int $color): void
+{
+ error_clear_last();
+ $result = \imagecharup($image, $font, $x, $y, $c, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Returns the index of the color of the pixel at the
+ * specified location in the image specified by image.
+ *
+ * If the image is a
+ * truecolor image, this function returns the RGB value of that pixel as
+ * integer. Use bitshifting and masking to access the distinct red, green and blue
+ * component values:
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $x x-coordinate of the point.
+ * @param int $y y-coordinate of the point.
+ * @return int Returns the index of the color.
+ * @throws ImageException
+ *
+ */
+function imagecolorat($image, int $x, int $y): int
+{
+ error_clear_last();
+ $result = \imagecolorat($image, $x, $y);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * De-allocates a color previously allocated with
+ * imagecolorallocate or
+ * imagecolorallocatealpha.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $color The color identifier.
+ * @throws ImageException
+ *
+ */
+function imagecolordeallocate($image, int $color): void
+{
+ error_clear_last();
+ $result = \imagecolordeallocate($image, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Makes the colors of the palette version of an image more closely match the true color version.
+ *
+ * @param resource $image1 A truecolor image resource.
+ * @param resource $image2 A palette image resource pointing to an image that has the same
+ * size as image1.
+ * @throws ImageException
+ *
+ */
+function imagecolormatch($image1, $image2): void
+{
+ error_clear_last();
+ $result = \imagecolormatch($image1, $image2);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Applies a convolution matrix on the image, using the given coefficient and
+ * offset.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param array $matrix A 3x3 matrix: an array of three arrays of three floats.
+ * @param float $div The divisor of the result of the convolution, used for normalization.
+ * @param float $offset Color offset.
+ * @throws ImageException
+ *
+ */
+function imageconvolution($image, array $matrix, float $div, float $offset): void
+{
+ error_clear_last();
+ $result = \imageconvolution($image, $matrix, $div, $offset);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Copy a part of src_im onto
+ * dst_im starting at the x,y coordinates
+ * src_x, src_y with
+ * a width of src_w and a height of
+ * src_h. The portion defined will be copied
+ * onto the x,y coordinates, dst_x and
+ * dst_y.
+ *
+ * @param resource $dst_im Destination image resource.
+ * @param resource $src_im Source image resource.
+ * @param int $dst_x x-coordinate of destination point.
+ * @param int $dst_y y-coordinate of destination point.
+ * @param int $src_x x-coordinate of source point.
+ * @param int $src_y y-coordinate of source point.
+ * @param int $src_w Source width.
+ * @param int $src_h Source height.
+ * @throws ImageException
+ *
+ */
+function imagecopy($dst_im, $src_im, int $dst_x, int $dst_y, int $src_x, int $src_y, int $src_w, int $src_h): void
+{
+ error_clear_last();
+ $result = \imagecopy($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Copy a part of src_im onto
+ * dst_im starting at the x,y coordinates
+ * src_x, src_y with
+ * a width of src_w and a height of
+ * src_h. The portion defined will be copied
+ * onto the x,y coordinates, dst_x and
+ * dst_y.
+ *
+ * @param resource $dst_im Destination image resource.
+ * @param resource $src_im Source image resource.
+ * @param int $dst_x x-coordinate of destination point.
+ * @param int $dst_y y-coordinate of destination point.
+ * @param int $src_x x-coordinate of source point.
+ * @param int $src_y y-coordinate of source point.
+ * @param int $src_w Source width.
+ * @param int $src_h Source height.
+ * @param int $pct The two images will be merged according to pct
+ * which can range from 0 to 100. When pct = 0,
+ * no action is taken, when 100 this function behaves identically
+ * to imagecopy for pallete images, except for
+ * ignoring alpha components, while it implements alpha transparency
+ * for true colour images.
+ * @throws ImageException
+ *
+ */
+function imagecopymerge($dst_im, $src_im, int $dst_x, int $dst_y, int $src_x, int $src_y, int $src_w, int $src_h, int $pct): void
+{
+ error_clear_last();
+ $result = \imagecopymerge($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagecopymergegray copy a part of src_im onto
+ * dst_im starting at the x,y coordinates
+ * src_x, src_y with
+ * a width of src_w and a height of
+ * src_h. The portion defined will be copied
+ * onto the x,y coordinates, dst_x and
+ * dst_y.
+ *
+ * This function is identical to imagecopymerge except
+ * that when merging it preserves the hue of the source by converting
+ * the destination pixels to gray scale before the copy operation.
+ *
+ * @param resource $dst_im Destination image resource.
+ * @param resource $src_im Source image resource.
+ * @param int $dst_x x-coordinate of destination point.
+ * @param int $dst_y y-coordinate of destination point.
+ * @param int $src_x x-coordinate of source point.
+ * @param int $src_y y-coordinate of source point.
+ * @param int $src_w Source width.
+ * @param int $src_h Source height.
+ * @param int $pct The src_im will be changed to grayscale according
+ * to pct where 0 is fully grayscale and 100 is
+ * unchanged. When pct = 100 this function behaves
+ * identically to imagecopy for pallete images, except for
+ * ignoring alpha components, while
+ * it implements alpha transparency for true colour images.
+ * @throws ImageException
+ *
+ */
+function imagecopymergegray($dst_im, $src_im, int $dst_x, int $dst_y, int $src_x, int $src_y, int $src_w, int $src_h, int $pct): void
+{
+ error_clear_last();
+ $result = \imagecopymergegray($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagecopyresampled copies a rectangular
+ * portion of one image to another image, smoothly interpolating pixel
+ * values so that, in particular, reducing the size of an image still
+ * retains a great deal of clarity.
+ *
+ * In other words, imagecopyresampled will take a
+ * rectangular area from src_image of width
+ * src_w and height src_h at
+ * position (src_x,src_y)
+ * and place it in a rectangular area of dst_image
+ * of width dst_w and height dst_h
+ * at position (dst_x,dst_y).
+ *
+ * If the source and destination coordinates and width and heights
+ * differ, appropriate stretching or shrinking of the image fragment
+ * will be performed. The coordinates refer to the upper left
+ * corner. This function can be used to copy regions within the
+ * same image (if dst_image is the same as
+ * src_image) but if the regions overlap the
+ * results will be unpredictable.
+ *
+ * @param resource $dst_image Destination image resource.
+ * @param resource $src_image Source image resource.
+ * @param int $dst_x x-coordinate of destination point.
+ * @param int $dst_y y-coordinate of destination point.
+ * @param int $src_x x-coordinate of source point.
+ * @param int $src_y y-coordinate of source point.
+ * @param int $dst_w Destination width.
+ * @param int $dst_h Destination height.
+ * @param int $src_w Source width.
+ * @param int $src_h Source height.
+ * @throws ImageException
+ *
+ */
+function imagecopyresampled($dst_image, $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $dst_w, int $dst_h, int $src_w, int $src_h): void
+{
+ error_clear_last();
+ $result = \imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagecopyresized copies a rectangular
+ * portion of one image to another image.
+ * dst_image is the destination image,
+ * src_image is the source image identifier.
+ *
+ * In other words, imagecopyresized will take a
+ * rectangular area from src_image of width
+ * src_w and height src_h at
+ * position (src_x,src_y)
+ * and place it in a rectangular area of dst_image
+ * of width dst_w and height dst_h
+ * at position (dst_x,dst_y).
+ *
+ * If the source and destination coordinates and width and heights
+ * differ, appropriate stretching or shrinking of the image fragment
+ * will be performed. The coordinates refer to the upper left
+ * corner. This function can be used to copy regions within the
+ * same image (if dst_image is the same as
+ * src_image) but if the regions overlap the
+ * results will be unpredictable.
+ *
+ * @param resource $dst_image Destination image resource.
+ * @param resource $src_image Source image resource.
+ * @param int $dst_x x-coordinate of destination point.
+ * @param int $dst_y y-coordinate of destination point.
+ * @param int $src_x x-coordinate of source point.
+ * @param int $src_y y-coordinate of source point.
+ * @param int $dst_w Destination width.
+ * @param int $dst_h Destination height.
+ * @param int $src_w Source width.
+ * @param int $src_h Source height.
+ * @throws ImageException
+ *
+ */
+function imagecopyresized($dst_image, $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $dst_w, int $dst_h, int $src_w, int $src_h): void
+{
+ error_clear_last();
+ $result = \imagecopyresized($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagecreate returns an image identifier
+ * representing a blank image of specified size.
+ *
+ * In general, we recommend the use of
+ * imagecreatetruecolor instead of
+ * imagecreate so that image processing occurs on the
+ * highest quality image possible. If you want to output a palette image, then
+ * imagetruecolortopalette should be called immediately
+ * before saving the image with imagepng or
+ * imagegif.
+ *
+ * @param int $width The image width.
+ * @param int $height The image height.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreate(int $width, int $height)
+{
+ error_clear_last();
+ $result = \imagecreate($width, $height);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagecreatefrombmp returns an image identifier
+ * representing the image obtained from the given filename.
+ *
+ * @param string $filename Path to the BMP image.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefrombmp(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefrombmp($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Create a new image from GD file or URL.
+ *
+ * @param string $filename Path to the GD file.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefromgd(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefromgd($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Create a new image from GD2 file or URL.
+ *
+ * @param string $filename Path to the GD2 image.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefromgd2(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefromgd2($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Create a new image from a given part of GD2 file or URL.
+ *
+ * @param string $filename Path to the GD2 image.
+ * @param int $srcX x-coordinate of source point.
+ * @param int $srcY y-coordinate of source point.
+ * @param int $width Source width.
+ * @param int $height Source height.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefromgd2part(string $filename, int $srcX, int $srcY, int $width, int $height)
+{
+ error_clear_last();
+ $result = \imagecreatefromgd2part($filename, $srcX, $srcY, $width, $height);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagecreatefromgif returns an image identifier
+ * representing the image obtained from the given filename.
+ *
+ * @param string $filename Path to the GIF image.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefromgif(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefromgif($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagecreatefromjpeg returns an image identifier
+ * representing the image obtained from the given filename.
+ *
+ * @param string $filename Path to the JPEG image.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefromjpeg(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefromjpeg($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagecreatefrompng returns an image identifier
+ * representing the image obtained from the given filename.
+ *
+ * @param string $filename Path to the PNG image.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefrompng(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefrompng($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagecreatefromwbmp returns an image identifier
+ * representing the image obtained from the given filename.
+ *
+ * @param string $filename Path to the WBMP image.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefromwbmp(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefromwbmp($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagecreatefromwebp returns an image identifier
+ * representing the image obtained from the given filename.
+ *
+ * @param string $filename Path to the WebP image.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefromwebp(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefromwebp($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagecreatefromxbm returns an image identifier
+ * representing the image obtained from the given filename.
+ *
+ * @param string $filename Path to the XBM image.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefromxbm(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefromxbm($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagecreatefromxpm returns an image identifier
+ * representing the image obtained from the given filename.
+ *
+ * @param string $filename Path to the XPM image.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatefromxpm(string $filename)
+{
+ error_clear_last();
+ $result = \imagecreatefromxpm($filename);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagecreatetruecolor returns an image identifier
+ * representing a black image of the specified size.
+ *
+ * @param int $width Image width.
+ * @param int $height Image height.
+ * @return resource Returns an image resource identifier on success, FALSE on errors.
+ * @throws ImageException
+ *
+ */
+function imagecreatetruecolor(int $width, int $height)
+{
+ error_clear_last();
+ $result = \imagecreatetruecolor($width, $height);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Crops an image to the given rectangular area and returns the resulting image.
+ * The given image is not modified.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param array $rect The cropping rectangle as array with keys
+ * x, y, width and
+ * height.
+ * @return resource Return cropped image resource on success.
+ * @throws ImageException
+ *
+ */
+function imagecrop($image, array $rect)
+{
+ error_clear_last();
+ $result = \imagecrop($image, $rect);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Automatically crops an image according to the given
+ * mode.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $mode One of the following constants:
+ * @param float $threshold
+ * @param int $color
+ * @return resource Returns a cropped image resource on success.
+ * If the complete image was cropped, imagecrop returns FALSE.
+ * @throws ImageException
+ *
+ */
+function imagecropauto($image, int $mode = IMG_CROP_DEFAULT, float $threshold = .5, int $color = -1)
+{
+ error_clear_last();
+ $result = \imagecropauto($image, $mode, $threshold, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * This function is deprecated. Use combination of
+ * imagesetstyle and imageline
+ * instead.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $x1 Upper left x coordinate.
+ * @param int $y1 Upper left y coordinate 0, 0 is the top left corner of the image.
+ * @param int $x2 Bottom right x coordinate.
+ * @param int $y2 Bottom right y coordinate.
+ * @param int $color The fill color. A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagedashedline($image, int $x1, int $y1, int $x2, int $y2, int $color): void
+{
+ error_clear_last();
+ $result = \imagedashedline($image, $x1, $y1, $x2, $y2, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagedestroy frees any memory associated
+ * with image image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @throws ImageException
+ *
+ */
+function imagedestroy($image): void
+{
+ error_clear_last();
+ $result = \imagedestroy($image);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Draws an ellipse centered at the specified coordinates.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $cx x-coordinate of the center.
+ * @param int $cy y-coordinate of the center.
+ * @param int $width The ellipse width.
+ * @param int $height The ellipse height.
+ * @param int $color The color of the ellipse. A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imageellipse($image, int $cx, int $cy, int $width, int $height, int $color): void
+{
+ error_clear_last();
+ $result = \imageellipse($image, $cx, $cy, $width, $height, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Performs a flood fill starting at the given coordinate (top left is 0, 0)
+ * with the given color in the
+ * image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $x x-coordinate of start point.
+ * @param int $y y-coordinate of start point.
+ * @param int $color The fill color. A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagefill($image, int $x, int $y, int $color): void
+{
+ error_clear_last();
+ $result = \imagefill($image, $x, $y, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Draws a partial arc centered at the specified coordinate in the
+ * given image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $cx x-coordinate of the center.
+ * @param int $cy y-coordinate of the center.
+ * @param int $width The arc width.
+ * @param int $height The arc height.
+ * @param int $start The arc start angle, in degrees.
+ * @param int $end The arc end angle, in degrees.
+ * 0° is located at the three-o'clock position, and the arc is drawn
+ * clockwise.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @param int $style A bitwise OR of the following possibilities:
+ *
+ * IMG_ARC_PIE
+ * IMG_ARC_CHORD
+ * IMG_ARC_NOFILL
+ * IMG_ARC_EDGED
+ *
+ * IMG_ARC_PIE and IMG_ARC_CHORD are
+ * mutually exclusive; IMG_ARC_CHORD just
+ * connects the starting and ending angles with a straight line, while
+ * IMG_ARC_PIE produces a rounded edge.
+ * IMG_ARC_NOFILL indicates that the arc
+ * or chord should be outlined, not filled. IMG_ARC_EDGED,
+ * used together with IMG_ARC_NOFILL, indicates that the
+ * beginning and ending angles should be connected to the center - this is a
+ * good way to outline (rather than fill) a 'pie slice'.
+ * @throws ImageException
+ *
+ */
+function imagefilledarc($image, int $cx, int $cy, int $width, int $height, int $start, int $end, int $color, int $style): void
+{
+ error_clear_last();
+ $result = \imagefilledarc($image, $cx, $cy, $width, $height, $start, $end, $color, $style);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Draws an ellipse centered at the specified coordinate on the given
+ * image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $cx x-coordinate of the center.
+ * @param int $cy y-coordinate of the center.
+ * @param int $width The ellipse width.
+ * @param int $height The ellipse height.
+ * @param int $color The fill color. A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagefilledellipse($image, int $cx, int $cy, int $width, int $height, int $color): void
+{
+ error_clear_last();
+ $result = \imagefilledellipse($image, $cx, $cy, $width, $height, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagefilledpolygon creates a filled polygon
+ * in the given image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param array $points An array containing the x and y
+ * coordinates of the polygons vertices consecutively.
+ * @param int $num_points Total number of points (vertices), which must be at least 3.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagefilledpolygon($image, array $points, int $num_points, int $color): void
+{
+ error_clear_last();
+ $result = \imagefilledpolygon($image, $points, $num_points, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Creates a rectangle filled with color in the given
+ * image starting at point 1 and ending at point 2.
+ * 0, 0 is the top left corner of the image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $x1 x-coordinate for point 1.
+ * @param int $y1 y-coordinate for point 1.
+ * @param int $x2 x-coordinate for point 2.
+ * @param int $y2 y-coordinate for point 2.
+ * @param int $color The fill color. A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagefilledrectangle($image, int $x1, int $y1, int $x2, int $y2, int $color): void
+{
+ error_clear_last();
+ $result = \imagefilledrectangle($image, $x1, $y1, $x2, $y2, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagefilltoborder performs a flood fill
+ * whose border color is defined by border.
+ * The starting point for the fill is x,
+ * y (top left is 0, 0) and the region is
+ * filled with color color.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $x x-coordinate of start.
+ * @param int $y y-coordinate of start.
+ * @param int $border The border color. A color identifier created with imagecolorallocate.
+ * @param int $color The fill color. A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagefilltoborder($image, int $x, int $y, int $border, int $color): void
+{
+ error_clear_last();
+ $result = \imagefilltoborder($image, $x, $y, $border, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagefilter applies the given filter
+ * filtertype on the image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $filtertype filtertype can be one of the following:
+ *
+ *
+ *
+ * IMG_FILTER_NEGATE: Reverses all colors of
+ * the image.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_GRAYSCALE: Converts the image into
+ * grayscale by changing the red, green and blue components to their
+ * weighted sum using the same coefficients as the REC.601 luma (Y')
+ * calculation. The alpha components are retained. For palette images the
+ * result may differ due to palette limitations.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_BRIGHTNESS: Changes the brightness
+ * of the image. Use arg1 to set the level of
+ * brightness. The range for the brightness is -255 to 255.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_CONTRAST: Changes the contrast of
+ * the image. Use arg1 to set the level of
+ * contrast.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_COLORIZE: Like
+ * IMG_FILTER_GRAYSCALE, except you can specify the
+ * color. Use arg1, arg2 and
+ * arg3 in the form of
+ * red, green,
+ * blue and arg4 for the
+ * alpha channel. The range for each color is 0 to 255.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_EDGEDETECT: Uses edge detection to
+ * highlight the edges in the image.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_EMBOSS: Embosses the image.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_GAUSSIAN_BLUR: Blurs the image using
+ * the Gaussian method.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_SELECTIVE_BLUR: Blurs the image.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_MEAN_REMOVAL: Uses mean removal to
+ * achieve a "sketchy" effect.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_SMOOTH: Makes the image smoother.
+ * Use arg1 to set the level of smoothness.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_PIXELATE: Applies pixelation effect
+ * to the image, use arg1 to set the block size
+ * and arg2 to set the pixelation effect mode.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_SCATTER: Applies scatter effect
+ * to the image, use arg1 and
+ * arg2 to define the effect strength and
+ * additionally arg3 to only apply the
+ * on select pixel colors.
+ *
+ *
+ *
+ * @param int $arg1
+ *
+ *
+ * IMG_FILTER_BRIGHTNESS: Brightness level.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_CONTRAST: Contrast level.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_COLORIZE: Value of red component.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_SMOOTH: Smoothness level.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_PIXELATE: Block size in pixels.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_SCATTER: Effect substraction level.
+ * This must not be higher or equal to the addition level set with
+ * arg2.
+ *
+ *
+ *
+ * @param int $arg2
+ *
+ *
+ * IMG_FILTER_COLORIZE: Value of green component.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_PIXELATE: Whether to use advanced pixelation
+ * effect or not (defaults to FALSE).
+ *
+ *
+ *
+ *
+ * IMG_FILTER_SCATTER: Effect addition level.
+ *
+ *
+ *
+ * @param int $arg3
+ *
+ *
+ * IMG_FILTER_COLORIZE: Value of blue component.
+ *
+ *
+ *
+ *
+ * IMG_FILTER_SCATTER: Optional array indexed color values
+ * to apply effect at.
+ *
+ *
+ *
+ * @param int $arg4
+ *
+ *
+ * IMG_FILTER_COLORIZE: Alpha channel, A value
+ * between 0 and 127. 0 indicates completely opaque while 127 indicates
+ * completely transparent.
+ *
+ *
+ *
+ * @throws ImageException
+ *
+ */
+function imagefilter($image, int $filtertype, int $arg1 = null, int $arg2 = null, int $arg3 = null, int $arg4 = null): void
+{
+ error_clear_last();
+ if ($arg4 !== null) {
+ $result = \imagefilter($image, $filtertype, $arg1, $arg2, $arg3, $arg4);
+ } elseif ($arg3 !== null) {
+ $result = \imagefilter($image, $filtertype, $arg1, $arg2, $arg3);
+ } elseif ($arg2 !== null) {
+ $result = \imagefilter($image, $filtertype, $arg1, $arg2);
+ } elseif ($arg1 !== null) {
+ $result = \imagefilter($image, $filtertype, $arg1);
+ } else {
+ $result = \imagefilter($image, $filtertype);
+ }
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Flips the image image using the given
+ * mode.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $mode Flip mode, this can be one of the IMG_FLIP_* constants:
+ *
+ *
+ *
+ *
+ *
+ * Constant
+ * Meaning
+ *
+ *
+ *
+ *
+ * IMG_FLIP_HORIZONTAL
+ *
+ * Flips the image horizontally.
+ *
+ *
+ *
+ * IMG_FLIP_VERTICAL
+ *
+ * Flips the image vertically.
+ *
+ *
+ *
+ * IMG_FLIP_BOTH
+ *
+ * Flips the image both horizontally and vertically.
+ *
+ *
+ *
+ *
+ *
+ * @throws ImageException
+ *
+ */
+function imageflip($image, int $mode): void
+{
+ error_clear_last();
+ $result = \imageflip($image, $mode);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Applies gamma correction to the given gd image
+ * given an input and an output gamma.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param float $inputgamma The input gamma.
+ * @param float $outputgamma The output gamma.
+ * @throws ImageException
+ *
+ */
+function imagegammacorrect($image, float $inputgamma, float $outputgamma): void
+{
+ error_clear_last();
+ $result = \imagegammacorrect($image, $inputgamma, $outputgamma);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Outputs a GD image to the given to.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param mixed $to The path or an open stream resource (which is automatically being closed after this function returns) to save the file to. If not set or NULL, the raw image stream will be outputted directly.
+ * @throws ImageException
+ *
+ */
+function imagegd($image, $to = null): void
+{
+ error_clear_last();
+ $result = \imagegd($image, $to);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Outputs a GD2 image to the given to.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param mixed $to The path or an open stream resource (which is automatically being closed after this function returns) to save the file to. If not set or NULL, the raw image stream will be outputted directly.
+ * @param int $chunk_size Chunk size.
+ * @param int $type Either IMG_GD2_RAW or
+ * IMG_GD2_COMPRESSED. Default is
+ * IMG_GD2_RAW.
+ * @throws ImageException
+ *
+ */
+function imagegd2($image, $to = null, int $chunk_size = 128, int $type = IMG_GD2_RAW): void
+{
+ error_clear_last();
+ $result = \imagegd2($image, $to, $chunk_size, $type);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagegif creates the GIF
+ * file in to from the image image. The
+ * image argument is the return from the
+ * imagecreate or imagecreatefrom*
+ * function.
+ *
+ * The image format will be GIF87a unless the
+ * image has been made transparent with
+ * imagecolortransparent, in which case the
+ * image format will be GIF89a.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param mixed $to The path or an open stream resource (which is automatically being closed after this function returns) to save the file to. If not set or NULL, the raw image stream will be outputted directly.
+ * @throws ImageException
+ *
+ */
+function imagegif($image, $to = null): void
+{
+ error_clear_last();
+ $result = \imagegif($image, $to);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Grabs a screenshot of the whole screen.
+ *
+ * @return resource Returns an image resource identifier on success, FALSE on failure.
+ * @throws ImageException
+ *
+ */
+function imagegrabscreen()
+{
+ error_clear_last();
+ $result = \imagegrabscreen();
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Grabs a window or its client area using a windows handle (HWND property in COM instance)
+ *
+ * @param int $window_handle The HWND window ID.
+ * @param int $client_area Include the client area of the application window.
+ * @return resource Returns an image resource identifier on success, FALSE on failure.
+ * @throws ImageException
+ *
+ */
+function imagegrabwindow(int $window_handle, int $client_area = 0)
+{
+ error_clear_last();
+ $result = \imagegrabwindow($window_handle, $client_area);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagejpeg creates a JPEG file from
+ * the given image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param mixed $to The path or an open stream resource (which is automatically being closed after this function returns) to save the file to. If not set or NULL, the raw image stream will be outputted directly.
+ * @param int $quality quality is optional, and ranges from 0 (worst
+ * quality, smaller file) to 100 (best quality, biggest file). The
+ * default (-1) uses the default IJG quality value (about 75).
+ * @throws ImageException
+ *
+ */
+function imagejpeg($image, $to = null, int $quality = -1): void
+{
+ error_clear_last();
+ $result = \imagejpeg($image, $to, $quality);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Set the alpha blending flag to use layering effects.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $effect One of the following constants:
+ *
+ *
+ * IMG_EFFECT_REPLACE
+ *
+ *
+ * Use pixel replacement (equivalent of passing TRUE to
+ * imagealphablending)
+ *
+ *
+ *
+ *
+ * IMG_EFFECT_ALPHABLEND
+ *
+ *
+ * Use normal pixel blending (equivalent of passing FALSE to
+ * imagealphablending)
+ *
+ *
+ *
+ *
+ * IMG_EFFECT_NORMAL
+ *
+ *
+ * Same as IMG_EFFECT_ALPHABLEND.
+ *
+ *
+ *
+ *
+ * IMG_EFFECT_OVERLAY
+ *
+ *
+ * Overlay has the effect that black background pixels will remain
+ * black, white background pixels will remain white, but grey
+ * background pixels will take the colour of the foreground pixel.
+ *
+ *
+ *
+ *
+ * IMG_EFFECT_MULTIPLY
+ *
+ *
+ * Overlays with a multiply effect.
+ *
+ *
+ *
+ *
+ * @throws ImageException
+ *
+ */
+function imagelayereffect($image, int $effect): void
+{
+ error_clear_last();
+ $result = \imagelayereffect($image, $effect);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Draws a line between the two given points.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $x1 x-coordinate for first point.
+ * @param int $y1 y-coordinate for first point.
+ * @param int $x2 x-coordinate for second point.
+ * @param int $y2 y-coordinate for second point.
+ * @param int $color The line color. A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imageline($image, int $x1, int $y1, int $x2, int $y2, int $color): void
+{
+ error_clear_last();
+ $result = \imageline($image, $x1, $y1, $x2, $y2, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imageloadfont loads a user-defined bitmap and returns
+ * its identifier.
+ *
+ * @param string $file The font file format is currently binary and architecture
+ * dependent. This means you should generate the font files on the
+ * same type of CPU as the machine you are running PHP on.
+ *
+ *
+ * Font file format
+ *
+ *
+ *
+ * byte position
+ * C data type
+ * description
+ *
+ *
+ *
+ *
+ * byte 0-3
+ * int
+ * number of characters in the font
+ *
+ *
+ * byte 4-7
+ * int
+ *
+ * value of first character in the font (often 32 for space)
+ *
+ *
+ *
+ * byte 8-11
+ * int
+ * pixel width of each character
+ *
+ *
+ * byte 12-15
+ * int
+ * pixel height of each character
+ *
+ *
+ * byte 16-
+ * char
+ *
+ * array with character data, one byte per pixel in each
+ * character, for a total of (nchars*width*height) bytes.
+ *
+ *
+ *
+ *
+ *
+ * @return int The font identifier which is always bigger than 5 to avoid conflicts with
+ * built-in fontss.
+ * @throws ImageException
+ *
+ */
+function imageloadfont(string $file): int
+{
+ error_clear_last();
+ $result = \imageloadfont($file);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imageopenpolygon draws an open polygon on the given
+ * image. Contrary to imagepolygon,
+ * no line is drawn between the last and the first point.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param array $points An array containing the polygon's vertices, e.g.:
+ *
+ *
+ *
+ *
+ * points[0]
+ * = x0
+ *
+ *
+ * points[1]
+ * = y0
+ *
+ *
+ * points[2]
+ * = x1
+ *
+ *
+ * points[3]
+ * = y1
+ *
+ *
+ *
+ *
+ * @param int $num_points Total number of points (vertices), which must be at least 3.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imageopenpolygon($image, array $points, int $num_points, int $color): void
+{
+ error_clear_last();
+ $result = \imageopenpolygon($image, $points, $num_points, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Outputs or saves a PNG image from the given
+ * image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param mixed $to The path or an open stream resource (which is automatically being closed after this function returns) to save the file to. If not set or NULL, the raw image stream will be outputted directly.
+ *
+ * NULL is invalid if the quality and
+ * filters arguments are not used.
+ * @param int $quality Compression level: from 0 (no compression) to 9.
+ * The default (-1) uses the zlib compression default.
+ * For more information see the zlib manual.
+ * @param int $filters Allows reducing the PNG file size. It is a bitmask field which may be
+ * set to any combination of the PNG_FILTER_XXX
+ * constants. PNG_NO_FILTER or
+ * PNG_ALL_FILTERS may also be used to respectively
+ * disable or activate all filters.
+ * The default value (-1) disables filtering.
+ * @throws ImageException
+ *
+ */
+function imagepng($image, $to = null, int $quality = -1, int $filters = -1): void
+{
+ error_clear_last();
+ $result = \imagepng($image, $to, $quality, $filters);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagepolygon creates a polygon in the given
+ * image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param array $points An array containing the polygon's vertices, e.g.:
+ *
+ *
+ *
+ *
+ * points[0]
+ * = x0
+ *
+ *
+ * points[1]
+ * = y0
+ *
+ *
+ * points[2]
+ * = x1
+ *
+ *
+ * points[3]
+ * = y1
+ *
+ *
+ *
+ *
+ * @param int $num_points Total number of points (vertices), which must be at least 3.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagepolygon($image, array $points, int $num_points, int $color): void
+{
+ error_clear_last();
+ $result = \imagepolygon($image, $points, $num_points, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagerectangle creates a rectangle starting at
+ * the specified coordinates.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $x1 Upper left x coordinate.
+ * @param int $y1 Upper left y coordinate
+ * 0, 0 is the top left corner of the image.
+ * @param int $x2 Bottom right x coordinate.
+ * @param int $y2 Bottom right y coordinate.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagerectangle($image, int $x1, int $y1, int $x2, int $y2, int $color): void
+{
+ error_clear_last();
+ $result = \imagerectangle($image, $x1, $y1, $x2, $y2, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Rotates the image image using the given
+ * angle in degrees.
+ *
+ * The center of rotation is the center of the image, and the rotated
+ * image may have different dimensions than the original image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param float $angle Rotation angle, in degrees. The rotation angle is interpreted as the
+ * number of degrees to rotate the image anticlockwise.
+ * @param int $bgd_color Specifies the color of the uncovered zone after the rotation
+ * @param int $dummy This parameter is unused.
+ * @return resource Returns an image resource for the rotated image.
+ * @throws ImageException
+ *
+ */
+function imagerotate($image, float $angle, int $bgd_color, int $dummy = 0)
+{
+ error_clear_last();
+ $result = \imagerotate($image, $angle, $bgd_color, $dummy);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagesavealpha sets the flag which determines whether to retain
+ * full alpha channel information (as opposed to single-color transparency)
+ * when saving PNG images.
+ *
+ * Alphablending has to be disabled (imagealphablending($im, false))
+ * to retain the alpha-channel in the first place.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param bool $saveflag Whether to save the alpha channel or not. Defaults to FALSE.
+ * @throws ImageException
+ *
+ */
+function imagesavealpha($image, bool $saveflag): void
+{
+ error_clear_last();
+ $result = \imagesavealpha($image, $saveflag);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagescale scales an image using the given
+ * interpolation algorithm.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $new_width The width to scale the image to.
+ * @param int $new_height The height to scale the image to. If omitted or negative, the aspect
+ * ratio will be preserved.
+ * @param int $mode One of IMG_NEAREST_NEIGHBOUR,
+ * IMG_BILINEAR_FIXED,
+ * IMG_BICUBIC,
+ * IMG_BICUBIC_FIXED or anything else (will use two
+ * pass).
+ *
+ *
+ * IMG_WEIGHTED4 is not yet supported.
+ *
+ *
+ * @return resource Return the scaled image resource on success.
+ * @throws ImageException
+ *
+ */
+function imagescale($image, int $new_width, int $new_height = -1, int $mode = IMG_BILINEAR_FIXED)
+{
+ error_clear_last();
+ $result = \imagescale($image, $new_width, $new_height, $mode);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagesetbrush sets the brush image to be
+ * used by all line drawing functions (such as imageline
+ * and imagepolygon) when drawing with the special
+ * colors IMG_COLOR_BRUSHED or
+ * IMG_COLOR_STYLEDBRUSHED.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param resource $brush An image resource.
+ * @throws ImageException
+ *
+ */
+function imagesetbrush($image, $brush): void
+{
+ error_clear_last();
+ $result = \imagesetbrush($image, $brush);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagesetclip sets the current clipping rectangle, i.e.
+ * the area beyond which no pixels will be drawn.
+ *
+ * @param resource $im An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $x1 The x-coordinate of the upper left corner.
+ * @param int $y1 The y-coordinate of the upper left corner.
+ * @param int $x2 The x-coordinate of the lower right corner.
+ * @param int $y2 The y-coordinate of the lower right corner.
+ * @throws ImageException
+ *
+ */
+function imagesetclip($im, int $x1, int $y1, int $x2, int $y2): void
+{
+ error_clear_last();
+ $result = \imagesetclip($im, $x1, $y1, $x2, $y2);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Sets the interpolation method, setting an interpolation method affects the rendering
+ * of various functions in GD, such as the imagerotate function.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $method The interpolation method, which can be one of the following:
+ *
+ *
+ *
+ * IMG_BELL: Bell filter.
+ *
+ *
+ *
+ *
+ * IMG_BESSEL: Bessel filter.
+ *
+ *
+ *
+ *
+ * IMG_BICUBIC: Bicubic interpolation.
+ *
+ *
+ *
+ *
+ * IMG_BICUBIC_FIXED: Fixed point implementation of the bicubic interpolation.
+ *
+ *
+ *
+ *
+ * IMG_BILINEAR_FIXED: Fixed point implementation of the bilinear interpolation (default (also on image creation)).
+ *
+ *
+ *
+ *
+ * IMG_BLACKMAN: Blackman window function.
+ *
+ *
+ *
+ *
+ * IMG_BOX: Box blur filter.
+ *
+ *
+ *
+ *
+ * IMG_BSPLINE: Spline interpolation.
+ *
+ *
+ *
+ *
+ * IMG_CATMULLROM: Cubic Hermite spline interpolation.
+ *
+ *
+ *
+ *
+ * IMG_GAUSSIAN: Gaussian function.
+ *
+ *
+ *
+ *
+ * IMG_GENERALIZED_CUBIC: Generalized cubic spline fractal interpolation.
+ *
+ *
+ *
+ *
+ * IMG_HERMITE: Hermite interpolation.
+ *
+ *
+ *
+ *
+ * IMG_HAMMING: Hamming filter.
+ *
+ *
+ *
+ *
+ * IMG_HANNING: Hanning filter.
+ *
+ *
+ *
+ *
+ * IMG_MITCHELL: Mitchell filter.
+ *
+ *
+ *
+ *
+ * IMG_POWER: Power interpolation.
+ *
+ *
+ *
+ *
+ * IMG_QUADRATIC: Inverse quadratic interpolation.
+ *
+ *
+ *
+ *
+ * IMG_SINC: Sinc function.
+ *
+ *
+ *
+ *
+ * IMG_NEAREST_NEIGHBOUR: Nearest neighbour interpolation.
+ *
+ *
+ *
+ *
+ * IMG_WEIGHTED4: Weighting filter.
+ *
+ *
+ *
+ *
+ * IMG_TRIANGLE: Triangle interpolation.
+ *
+ *
+ *
+ * @throws ImageException
+ *
+ */
+function imagesetinterpolation($image, int $method = IMG_BILINEAR_FIXED): void
+{
+ error_clear_last();
+ $result = \imagesetinterpolation($image, $method);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagesetpixel draws a pixel at the specified
+ * coordinate.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $x x-coordinate.
+ * @param int $y y-coordinate.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagesetpixel($image, int $x, int $y, int $color): void
+{
+ error_clear_last();
+ $result = \imagesetpixel($image, $x, $y, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagesetstyle sets the style to be used by all
+ * line drawing functions (such as imageline
+ * and imagepolygon) when drawing with the special
+ * color IMG_COLOR_STYLED or lines of images with color
+ * IMG_COLOR_STYLEDBRUSHED.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param array $style An array of pixel colors. You can use the
+ * IMG_COLOR_TRANSPARENT constant to add a
+ * transparent pixel.
+ * Note that style must not be an empty array.
+ * @throws ImageException
+ *
+ */
+function imagesetstyle($image, array $style): void
+{
+ error_clear_last();
+ $result = \imagesetstyle($image, $style);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagesetthickness sets the thickness of the lines
+ * drawn when drawing rectangles, polygons, arcs etc. to
+ * thickness pixels.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $thickness Thickness, in pixels.
+ * @throws ImageException
+ *
+ */
+function imagesetthickness($image, int $thickness): void
+{
+ error_clear_last();
+ $result = \imagesetthickness($image, $thickness);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * imagesettile sets the tile image to be
+ * used by all region filling functions (such as imagefill
+ * and imagefilledpolygon) when filling with the special
+ * color IMG_COLOR_TILED.
+ *
+ * A tile is an image used to fill an area with a repeated pattern. Any
+ * GD image can be used as a tile, and by setting the transparent color index of the tile
+ * image with imagecolortransparent, a tile allows certain parts
+ * of the underlying area to shine through can be created.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param resource $tile The image resource to be used as a tile.
+ * @throws ImageException
+ *
+ */
+function imagesettile($image, $tile): void
+{
+ error_clear_last();
+ $result = \imagesettile($image, $tile);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Draws a string at the given coordinates.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $font Can be 1, 2, 3, 4, 5 for built-in
+ * fonts in latin2 encoding (where higher numbers corresponding to larger fonts) or any of your
+ * own font identifiers registered with imageloadfont.
+ * @param int $x x-coordinate of the upper left corner.
+ * @param int $y y-coordinate of the upper left corner.
+ * @param string $string The string to be written.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagestring($image, int $font, int $x, int $y, string $string, int $color): void
+{
+ error_clear_last();
+ $result = \imagestring($image, $font, $x, $y, $string, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Draws a string vertically at the given
+ * coordinates.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param int $font Can be 1, 2, 3, 4, 5 for built-in
+ * fonts in latin2 encoding (where higher numbers corresponding to larger fonts) or any of your
+ * own font identifiers registered with imageloadfont.
+ * @param int $x x-coordinate of the bottom left corner.
+ * @param int $y y-coordinate of the bottom left corner.
+ * @param string $string The string to be written.
+ * @param int $color A color identifier created with imagecolorallocate.
+ * @throws ImageException
+ *
+ */
+function imagestringup($image, int $font, int $x, int $y, string $string, int $color): void
+{
+ error_clear_last();
+ $result = \imagestringup($image, $font, $x, $y, $string, $color);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Returns the width of the given image resource.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @return int Return the width of the images.
+ * @throws ImageException
+ *
+ */
+function imagesx($image): int
+{
+ error_clear_last();
+ $result = \imagesx($image);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Returns the height of the given image resource.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @return int Return the height of the images.
+ * @throws ImageException
+ *
+ */
+function imagesy($image): int
+{
+ error_clear_last();
+ $result = \imagesy($image);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagetruecolortopalette converts a truecolor image
+ * to a palette image. The code for this function was originally drawn from
+ * the Independent JPEG Group library code, which is excellent. The code
+ * has been modified to preserve as much alpha channel information as
+ * possible in the resulting palette, in addition to preserving colors as
+ * well as possible. This does not work as well as might be hoped. It is
+ * usually best to simply produce a truecolor output image instead, which
+ * guarantees the highest output quality.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param bool $dither Indicates if the image should be dithered - if it is TRUE then
+ * dithering will be used which will result in a more speckled image but
+ * with better color approximation.
+ * @param int $ncolors Sets the maximum number of colors that should be retained in the palette.
+ * @throws ImageException
+ *
+ */
+function imagetruecolortopalette($image, bool $dither, int $ncolors): void
+{
+ error_clear_last();
+ $result = \imagetruecolortopalette($image, $dither, $ncolors);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * This function calculates and returns the bounding box in pixels
+ * for a TrueType text.
+ *
+ * @param float $size The font size in points.
+ * @param float $angle Angle in degrees in which text will be measured.
+ * @param string $fontfile The path to the TrueType font you wish to use.
+ *
+ * Depending on which version of the GD library PHP is using, when
+ * fontfile does not begin with a leading
+ * / then .ttf will be appended
+ * to the filename and the library will attempt to search for that
+ * filename along a library-defined font path.
+ *
+ * When using versions of the GD library lower than 2.0.18, a space character,
+ * rather than a semicolon, was used as the 'path separator' for different font files.
+ * Unintentional use of this feature will result in the warning message:
+ * Warning: Could not find/open font. For these affected versions, the
+ * only solution is moving the font to a path which does not contain spaces.
+ *
+ * In many cases where a font resides in the same directory as the script using it
+ * the following trick will alleviate any include problems.
+ *
+ *
+ * ]]>
+ *
+ *
+ * Note that open_basedir does
+ * not apply to fontfile.
+ * @param string $text The string to be measured.
+ * @return array imagettfbbox returns an array with 8
+ * elements representing four points making the bounding box of the
+ * text on success and FALSE on error.
+ *
+ *
+ *
+ *
+ * key
+ * contents
+ *
+ *
+ *
+ *
+ * 0
+ * lower left corner, X position
+ *
+ *
+ * 1
+ * lower left corner, Y position
+ *
+ *
+ * 2
+ * lower right corner, X position
+ *
+ *
+ * 3
+ * lower right corner, Y position
+ *
+ *
+ * 4
+ * upper right corner, X position
+ *
+ *
+ * 5
+ * upper right corner, Y position
+ *
+ *
+ * 6
+ * upper left corner, X position
+ *
+ *
+ * 7
+ * upper left corner, Y position
+ *
+ *
+ *
+ *
+ *
+ * The points are relative to the text regardless of the
+ * angle, so "upper left" means in the top left-hand
+ * corner seeing the text horizontally.
+ * @throws ImageException
+ *
+ */
+function imagettfbbox(float $size, float $angle, string $fontfile, string $text): array
+{
+ error_clear_last();
+ $result = \imagettfbbox($size, $angle, $fontfile, $text);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Writes the given text into the image using TrueType
+ * fonts.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param float $size The font size in points.
+ * @param float $angle The angle in degrees, with 0 degrees being left-to-right reading text.
+ * Higher values represent a counter-clockwise rotation. For example, a
+ * value of 90 would result in bottom-to-top reading text.
+ * @param int $x The coordinates given by x and
+ * y will define the basepoint of the first
+ * character (roughly the lower-left corner of the character). This
+ * is different from the imagestring, where
+ * x and y define the
+ * upper-left corner of the first character. For example, "top left"
+ * is 0, 0.
+ * @param int $y The y-ordinate. This sets the position of the fonts baseline, not the
+ * very bottom of the character.
+ * @param int $color The color index. Using the negative of a color index has the effect of
+ * turning off antialiasing. See imagecolorallocate.
+ * @param string $fontfile The path to the TrueType font you wish to use.
+ *
+ * Depending on which version of the GD library PHP is using, when
+ * fontfile does not begin with a leading
+ * / then .ttf will be appended
+ * to the filename and the library will attempt to search for that
+ * filename along a library-defined font path.
+ *
+ * When using versions of the GD library lower than 2.0.18, a space character,
+ * rather than a semicolon, was used as the 'path separator' for different font files.
+ * Unintentional use of this feature will result in the warning message:
+ * Warning: Could not find/open font. For these affected versions, the
+ * only solution is moving the font to a path which does not contain spaces.
+ *
+ * In many cases where a font resides in the same directory as the script using it
+ * the following trick will alleviate any include problems.
+ *
+ *
+ * ]]>
+ *
+ *
+ * Note that open_basedir does
+ * not apply to fontfile.
+ * @param string $text The text string in UTF-8 encoding.
+ *
+ * May include decimal numeric character references (of the form:
+ * €) to access characters in a font beyond position 127.
+ * The hexadecimal format (like ©) is supported.
+ * Strings in UTF-8 encoding can be passed directly.
+ *
+ * Named entities, such as ©, are not supported. Consider using
+ * html_entity_decode
+ * to decode these named entities into UTF-8 strings.
+ *
+ * If a character is used in the string which is not supported by the
+ * font, a hollow rectangle will replace the character.
+ * @return array Returns an array with 8 elements representing four points making the
+ * bounding box of the text. The order of the points is lower left, lower
+ * right, upper right, upper left. The points are relative to the text
+ * regardless of the angle, so "upper left" means in the top left-hand
+ * corner when you see the text horizontally.
+ * @throws ImageException
+ *
+ */
+function imagettftext($image, float $size, float $angle, int $x, int $y, int $color, string $fontfile, string $text): array
+{
+ error_clear_last();
+ $result = \imagettftext($image, $size, $angle, $x, $y, $color, $fontfile, $text);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * imagewbmp outputs or save a WBMP
+ * version of the given image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param mixed $to The path or an open stream resource (which is automatically being closed after this function returns) to save the file to. If not set or NULL, the raw image stream will be outputted directly.
+ * @param int $foreground You can set the foreground color with this parameter by setting an
+ * identifier obtained from imagecolorallocate.
+ * The default foreground color is black.
+ * @throws ImageException
+ *
+ */
+function imagewbmp($image, $to = null, int $foreground = null): void
+{
+ error_clear_last();
+ if ($foreground !== null) {
+ $result = \imagewbmp($image, $to, $foreground);
+ } else {
+ $result = \imagewbmp($image, $to);
+ }
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Outputs or saves a WebP version of the given image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param mixed $to The path or an open stream resource (which is automatically being closed after this function returns) to save the file to. If not set or NULL, the raw image stream will be outputted directly.
+ * @param int $quality quality ranges from 0 (worst
+ * quality, smaller file) to 100 (best quality, biggest file).
+ * @throws ImageException
+ *
+ */
+function imagewebp($image, $to = null, int $quality = 80): void
+{
+ error_clear_last();
+ $result = \imagewebp($image, $to, $quality);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Outputs or save an XBM version of the given
+ * image.
+ *
+ * @param resource $image An image resource, returned by one of the image creation functions,
+ * such as imagecreatetruecolor.
+ * @param string|null $filename The path to save the file to, given as string. If NULL, the raw image stream will be output directly.
+ *
+ * The filename (without the .xbm extension) is also
+ * used for the C identifiers of the XBM, whereby non
+ * alphanumeric characters of the current locale are substituted by
+ * underscores. If filename is set to NULL,
+ * image is used to build the C identifiers.
+ * @param int $foreground You can set the foreground color with this parameter by setting an
+ * identifier obtained from imagecolorallocate.
+ * The default foreground color is black. All other colors are treated as
+ * background.
+ * @throws ImageException
+ *
+ */
+function imagexbm($image, ?string $filename, int $foreground = null): void
+{
+ error_clear_last();
+ if ($foreground !== null) {
+ $result = \imagexbm($image, $filename, $foreground);
+ } else {
+ $result = \imagexbm($image, $filename);
+ }
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Embeds binary IPTC data into a JPEG image.
+ *
+ * @param string $iptcdata The data to be written.
+ * @param string $jpeg_file_name Path to the JPEG image.
+ * @param int $spool Spool flag. If the spool flag is less than 2 then the JPEG will be
+ * returned as a string. Otherwise the JPEG will be printed to STDOUT.
+ * @return string|bool If spool is less than 2, the JPEG will be returned. Otherwise returns TRUE on success.
+ * @throws ImageException
+ *
+ */
+function iptcembed(string $iptcdata, string $jpeg_file_name, int $spool = 0)
+{
+ error_clear_last();
+ $result = \iptcembed($iptcdata, $jpeg_file_name, $spool);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Parses an IPTC block into its single tags.
+ *
+ * @param string $iptcblock A binary IPTC block.
+ * @return array Returns an array using the tagmarker as an index and the value as the
+ * value. It returns FALSE on error or if no IPTC data was found.
+ * @throws ImageException
+ *
+ */
+function iptcparse(string $iptcblock): array
+{
+ error_clear_last();
+ $result = \iptcparse($iptcblock);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Converts a JPEG file into a WBMP file.
+ *
+ * @param string $jpegname Path to JPEG file.
+ * @param string $wbmpname Path to destination WBMP file.
+ * @param int $dest_height Destination image height.
+ * @param int $dest_width Destination image width.
+ * @param int $threshold Threshold value, between 0 and 8 (inclusive).
+ * @throws ImageException
+ *
+ */
+function jpeg2wbmp(string $jpegname, string $wbmpname, int $dest_height, int $dest_width, int $threshold): void
+{
+ error_clear_last();
+ $result = \jpeg2wbmp($jpegname, $wbmpname, $dest_height, $dest_width, $threshold);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Converts a PNG file into a WBMP file.
+ *
+ * @param string $pngname Path to PNG file.
+ * @param string $wbmpname Path to destination WBMP file.
+ * @param int $dest_height Destination image height.
+ * @param int $dest_width Destination image width.
+ * @param int $threshold Threshold value, between 0 and 8 (inclusive).
+ * @throws ImageException
+ *
+ */
+function png2wbmp(string $pngname, string $wbmpname, int $dest_height, int $dest_width, int $threshold): void
+{
+ error_clear_last();
+ $result = \png2wbmp($pngname, $wbmpname, $dest_height, $dest_width, $threshold);
+ if ($result === false) {
+ throw ImageException::createFromPhpError();
+ }
+}
diff --git a/vendor/thecodingmachine/safe/generated/imap.php b/vendor/thecodingmachine/safe/generated/imap.php
new file mode 100644
index 000000000..acd8672c6
--- /dev/null
+++ b/vendor/thecodingmachine/safe/generated/imap.php
@@ -0,0 +1,1481 @@
+
+ *
+ *
+ * @param array $serverctrls Array of LDAP Controls to send with the request.
+ * @throws LdapException
+ *
+ */
+function ldap_add($link_identifier, string $dn, array $entry, array $serverctrls = null): void
+{
+ error_clear_last();
+ $result = \ldap_add($link_identifier, $dn, $entry, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Does the same thing as ldap_bind but returns the LDAP result resource to be parsed with ldap_parse_result.
+ *
+ * @param resource $link_identifier
+ * @param string|null $bind_rdn
+ * @param string|null $bind_password
+ * @param array $serverctrls
+ * @return resource Returns an LDAP result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_bind_ext($link_identifier, ?string $bind_rdn = null, ?string $bind_password = null, array $serverctrls = null)
+{
+ error_clear_last();
+ $result = \ldap_bind_ext($link_identifier, $bind_rdn, $bind_password, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Binds to the LDAP directory with specified RDN and password.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string|null $bind_rdn
+ * @param string|null $bind_password
+ * @throws LdapException
+ *
+ */
+function ldap_bind($link_identifier, ?string $bind_rdn = null, ?string $bind_password = null): void
+{
+ error_clear_last();
+ $result = \ldap_bind($link_identifier, $bind_rdn, $bind_password);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Retrieve the pagination information send by the server.
+ *
+ * @param resource $link An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result
+ * @param string|null $cookie An opaque structure sent by the server.
+ * @param int|null $estimated The estimated number of entries to retrieve.
+ * @throws LdapException
+ *
+ */
+function ldap_control_paged_result_response($link, $result, ?string &$cookie = null, ?int &$estimated = null): void
+{
+ error_clear_last();
+ $result = \ldap_control_paged_result_response($link, $result, $cookie, $estimated);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Enable LDAP pagination by sending the pagination control (page size, cookie...).
+ *
+ * @param resource $link An LDAP link identifier, returned by ldap_connect.
+ * @param int $pagesize The number of entries by page.
+ * @param bool $iscritical Indicates whether the pagination is critical or not.
+ * If true and if the server doesn't support pagination, the search
+ * will return no result.
+ * @param string $cookie An opaque structure sent by the server
+ * (ldap_control_paged_result_response).
+ * @throws LdapException
+ *
+ */
+function ldap_control_paged_result($link, int $pagesize, bool $iscritical = false, string $cookie = ""): void
+{
+ error_clear_last();
+ $result = \ldap_control_paged_result($link, $pagesize, $iscritical, $cookie);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Returns the number of entries stored in the result of previous search
+ * operations.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result_identifier The internal LDAP result.
+ * @return int Returns number of entries in the result.
+ * @throws LdapException
+ *
+ */
+function ldap_count_entries($link_identifier, $result_identifier): int
+{
+ error_clear_last();
+ $result = \ldap_count_entries($link_identifier, $result_identifier);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Does the same thing as ldap_delete but returns the LDAP result resource to be parsed with ldap_parse_result.
+ *
+ * @param resource $link_identifier
+ * @param string $dn
+ * @param array $serverctrls
+ * @return resource Returns an LDAP result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_delete_ext($link_identifier, string $dn, array $serverctrls = null)
+{
+ error_clear_last();
+ $result = \ldap_delete_ext($link_identifier, $dn, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Deletes a particular entry in LDAP directory.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string $dn The distinguished name of an LDAP entity.
+ * @param array $serverctrls Array of LDAP Controls to send with the request.
+ * @throws LdapException
+ *
+ */
+function ldap_delete($link_identifier, string $dn, array $serverctrls = null): void
+{
+ error_clear_last();
+ $result = \ldap_delete($link_identifier, $dn, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Performs a PASSWD extended operation.
+ *
+ * @param resource $link An LDAP link identifier, returned by ldap_connect.
+ * @param string $user dn of the user to change the password of.
+ * @param string $oldpw The old password of this user. May be ommited depending of server configuration.
+ * @param string $newpw The new password for this user. May be omitted or empty to have a generated password.
+ * @param array $serverctrls If provided, a password policy request control is send with the request and this is
+ * filled with an array of LDAP Controls
+ * returned with the request.
+ * @return mixed Returns the generated password if newpw is empty or omitted.
+ * Otherwise returns TRUE on success.
+ * @throws LdapException
+ *
+ */
+function ldap_exop_passwd($link, string $user = "", string $oldpw = "", string $newpw = "", array &$serverctrls = null)
+{
+ error_clear_last();
+ $result = \ldap_exop_passwd($link, $user, $oldpw, $newpw, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Performs a WHOAMI extended operation and returns the data.
+ *
+ * @param resource $link An LDAP link identifier, returned by ldap_connect.
+ * @return string The data returned by the server.
+ * @throws LdapException
+ *
+ */
+function ldap_exop_whoami($link): string
+{
+ error_clear_last();
+ $result = \ldap_exop_whoami($link);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Performs an extended operation on the specified link with
+ * reqoid the OID of the operation and
+ * reqdata the data.
+ *
+ * @param resource $link An LDAP link identifier, returned by ldap_connect.
+ * @param string $reqoid The extended operation request OID. You may use one of LDAP_EXOP_START_TLS, LDAP_EXOP_MODIFY_PASSWD, LDAP_EXOP_REFRESH, LDAP_EXOP_WHO_AM_I, LDAP_EXOP_TURN, or a string with the OID of the operation you want to send.
+ * @param string $reqdata The extended operation request data. May be NULL for some operations like LDAP_EXOP_WHO_AM_I, may also need to be BER encoded.
+ * @param array|null $serverctrls Array of LDAP Controls to send with the request.
+ * @param string|null $retdata Will be filled with the extended operation response data if provided.
+ * If not provided you may use ldap_parse_exop on the result object
+ * later to get this data.
+ * @param string|null $retoid Will be filled with the response OID if provided, usually equal to the request OID.
+ * @return mixed When used with retdata, returns TRUE on success.
+ * When used without retdata, returns a result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_exop($link, string $reqoid, string $reqdata = null, ?array $serverctrls = null, ?string &$retdata = null, ?string &$retoid = null)
+{
+ error_clear_last();
+ $result = \ldap_exop($link, $reqoid, $reqdata, $serverctrls, $retdata, $retoid);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Splits the DN returned by ldap_get_dn and breaks it
+ * up into its component parts. Each part is known as Relative Distinguished
+ * Name, or RDN.
+ *
+ * @param string $dn The distinguished name of an LDAP entity.
+ * @param int $with_attrib Used to request if the RDNs are returned with only values or their
+ * attributes as well. To get RDNs with the attributes (i.e. in
+ * attribute=value format) set with_attrib to 0
+ * and to get only values set it to 1.
+ * @return array Returns an array of all DN components.
+ * The first element in the array has count key and
+ * represents the number of returned values, next elements are numerically
+ * indexed DN components.
+ * @throws LdapException
+ *
+ */
+function ldap_explode_dn(string $dn, int $with_attrib): array
+{
+ error_clear_last();
+ $result = \ldap_explode_dn($dn, $with_attrib);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Gets the first attribute in the given entry. Remaining attributes are
+ * retrieved by calling ldap_next_attribute successively.
+ *
+ * Similar to reading entries, attributes are also read one by one from a
+ * particular entry.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result_entry_identifier
+ * @return string Returns the first attribute in the entry on success and FALSE on
+ * error.
+ * @throws LdapException
+ *
+ */
+function ldap_first_attribute($link_identifier, $result_entry_identifier): string
+{
+ error_clear_last();
+ $result = \ldap_first_attribute($link_identifier, $result_entry_identifier);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Returns the entry identifier for first entry in the result. This entry
+ * identifier is then supplied to ldap_next_entry
+ * routine to get successive entries from the result.
+ *
+ * Entries in the LDAP result are read sequentially using the
+ * ldap_first_entry and
+ * ldap_next_entry functions.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result_identifier
+ * @return resource Returns the result entry identifier for the first entry on success and
+ * FALSE on error.
+ * @throws LdapException
+ *
+ */
+function ldap_first_entry($link_identifier, $result_identifier)
+{
+ error_clear_last();
+ $result = \ldap_first_entry($link_identifier, $result_identifier);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Frees up the memory allocated internally to store the result. All result
+ * memory will be automatically freed when the script terminates.
+ *
+ * Typically all the memory allocated for the LDAP result gets freed at the
+ * end of the script. In case the script is making successive searches which
+ * return large result sets, ldap_free_result could be
+ * called to keep the runtime memory usage by the script low.
+ *
+ * @param resource $result_identifier
+ * @throws LdapException
+ *
+ */
+function ldap_free_result($result_identifier): void
+{
+ error_clear_last();
+ $result = \ldap_free_result($result_identifier);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Reads attributes and values from an entry in the search result.
+ *
+ * Having located a specific entry in the directory, you can find out what
+ * information is held for that entry by using this call. You would use this
+ * call for an application which "browses" directory entries and/or where you
+ * do not know the structure of the directory entries. In many applications
+ * you will be searching for a specific attribute such as an email address or
+ * a surname, and won't care what other data is held.
+ *
+ *
+ *
+ *
+ *
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result_entry_identifier
+ * @return array Returns a complete entry information in a multi-dimensional array
+ * on success and FALSE on error.
+ * @throws LdapException
+ *
+ */
+function ldap_get_attributes($link_identifier, $result_entry_identifier): array
+{
+ error_clear_last();
+ $result = \ldap_get_attributes($link_identifier, $result_entry_identifier);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Finds out the DN of an entry in the result.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result_entry_identifier
+ * @return string Returns the DN of the result entry and FALSE on error.
+ * @throws LdapException
+ *
+ */
+function ldap_get_dn($link_identifier, $result_entry_identifier): string
+{
+ error_clear_last();
+ $result = \ldap_get_dn($link_identifier, $result_entry_identifier);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Reads multiple entries from the given result, and then reading the
+ * attributes and multiple values.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result_identifier
+ * @return array Returns a complete result information in a multi-dimensional array on
+ * success and FALSE on error.
+ *
+ * The structure of the array is as follows.
+ * The attribute index is converted to lowercase. (Attributes are
+ * case-insensitive for directory servers, but not when used as
+ * array indices.)
+ *
+ *
+ *
+ *
+ *
+ * @throws LdapException
+ *
+ */
+function ldap_get_entries($link_identifier, $result_identifier): array
+{
+ error_clear_last();
+ $result = \ldap_get_entries($link_identifier, $result_identifier);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Sets retval to the value of the specified option.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param int $option The parameter option can be one of:
+ *
+ *
+ *
+ *
+ * Option
+ * Type
+ * since
+ *
+ *
+ *
+ *
+ * LDAP_OPT_DEREF
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_SIZELIMIT
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_TIMELIMIT
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_NETWORK_TIMEOUT
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_PROTOCOL_VERSION
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_ERROR_NUMBER
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_DIAGNOSTIC_MESSAGE
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_REFERRALS
+ * bool
+ *
+ *
+ *
+ * LDAP_OPT_RESTART
+ * bool
+ *
+ *
+ *
+ * LDAP_OPT_HOST_NAME
+ * string
+ *
+ *
+ *
+ * LDAP_OPT_ERROR_STRING
+ * string
+ *
+ *
+ *
+ * LDAP_OPT_MATCHED_DN
+ * string
+ *
+ *
+ *
+ * LDAP_OPT_SERVER_CONTROLS
+ * array
+ *
+ *
+ *
+ * LDAP_OPT_CLIENT_CONTROLS
+ * array
+ *
+ *
+ *
+ * LDAP_OPT_X_KEEPALIVE_IDLE
+ * int
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_KEEPALIVE_PROBES
+ * int
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_KEEPALIVE_INTERVAL
+ * int
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_CACERTDIR
+ * string
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_CACERTFILE
+ * string
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_CERTFILE
+ * string
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_CIPHER_SUITE
+ * string
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_CRLCHECK
+ * integer
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_CRL_NONE
+ * integer
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_CRL_PEER
+ * integer
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_CRL_ALL
+ * integer
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_CRLFILE
+ * string
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_DHFILE
+ * string
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_KEYILE
+ * string
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_PACKAGE
+ * string
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_PROTOCOL_MIN
+ * integer
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_RANDOM_FILE
+ * string
+ * 7.1
+ *
+ *
+ * LDAP_OPT_X_TLS_REQUIRE_CERT
+ * integer
+ *
+ *
+ *
+ *
+ *
+ * @param mixed $retval This will be set to the option value.
+ * @throws LdapException
+ *
+ */
+function ldap_get_option($link_identifier, int $option, &$retval): void
+{
+ error_clear_last();
+ $result = \ldap_get_option($link_identifier, $option, $retval);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Reads all the values of the attribute in the entry in the result.
+ *
+ * This function is used exactly like ldap_get_values
+ * except that it handles binary data and not string data.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result_entry_identifier
+ * @param string $attribute
+ * @return array Returns an array of values for the attribute on success and FALSE on
+ * error. Individual values are accessed by integer index in the array. The
+ * first index is 0. The number of values can be found by indexing "count"
+ * in the resultant array.
+ * @throws LdapException
+ *
+ */
+function ldap_get_values_len($link_identifier, $result_entry_identifier, string $attribute): array
+{
+ error_clear_last();
+ $result = \ldap_get_values_len($link_identifier, $result_entry_identifier, $attribute);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Reads all the values of the attribute in the entry in the result.
+ *
+ * This call needs a result_entry_identifier,
+ * so needs to be preceded by one of the ldap search calls and one
+ * of the calls to get an individual entry.
+ *
+ * You application will either be hard coded to look for certain
+ * attributes (such as "surname" or "mail") or you will have to use
+ * the ldap_get_attributes call to work out
+ * what attributes exist for a given entry.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result_entry_identifier
+ * @param string $attribute
+ * @return array Returns an array of values for the attribute on success and FALSE on
+ * error. The number of values can be found by indexing "count" in the
+ * resultant array. Individual values are accessed by integer index in the
+ * array. The first index is 0.
+ *
+ * LDAP allows more than one entry for an attribute, so it can, for example,
+ * store a number of email addresses for one person's directory entry all
+ * labeled with the attribute "mail"
+ *
+ *
+ * return_value["count"] = number of values for attribute
+ * return_value[0] = first value of attribute
+ * return_value[i] = ith value of attribute
+ *
+ *
+ * @throws LdapException
+ *
+ */
+function ldap_get_values($link_identifier, $result_entry_identifier, string $attribute): array
+{
+ error_clear_last();
+ $result = \ldap_get_values($link_identifier, $result_entry_identifier, $attribute);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Performs the search for a specified filter on the
+ * directory with the scope LDAP_SCOPE_ONELEVEL.
+ *
+ * LDAP_SCOPE_ONELEVEL means that the search should only
+ * return information that is at the level immediately below the
+ * base_dn given in the call.
+ * (Equivalent to typing "ls" and getting a list of files and folders in the
+ * current working directory.)
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string $base_dn The base DN for the directory.
+ * @param string $filter
+ * @param array $attributes An array of the required attributes, e.g. array("mail", "sn", "cn").
+ * Note that the "dn" is always returned irrespective of which attributes
+ * types are requested.
+ *
+ * Using this parameter is much more efficient than the default action
+ * (which is to return all attributes and their associated values).
+ * The use of this parameter should therefore be considered good
+ * practice.
+ * @param int $attrsonly Should be set to 1 if only attribute types are wanted. If set to 0
+ * both attributes types and attribute values are fetched which is the
+ * default behaviour.
+ * @param int $sizelimit Enables you to limit the count of entries fetched. Setting this to 0
+ * means no limit.
+ *
+ * This parameter can NOT override server-side preset sizelimit. You can
+ * set it lower though.
+ *
+ * Some directory server hosts will be configured to return no more than
+ * a preset number of entries. If this occurs, the server will indicate
+ * that it has only returned a partial results set. This also occurs if
+ * you use this parameter to limit the count of fetched entries.
+ * @param int $timelimit Sets the number of seconds how long is spend on the search. Setting
+ * this to 0 means no limit.
+ *
+ * This parameter can NOT override server-side preset timelimit. You can
+ * set it lower though.
+ * @param int $deref Specifies how aliases should be handled during the search. It can be
+ * one of the following:
+ *
+ *
+ *
+ * LDAP_DEREF_NEVER - (default) aliases are never
+ * dereferenced.
+ *
+ *
+ *
+ *
+ * LDAP_DEREF_SEARCHING - aliases should be
+ * dereferenced during the search but not when locating the base object
+ * of the search.
+ *
+ *
+ *
+ *
+ * LDAP_DEREF_FINDING - aliases should be
+ * dereferenced when locating the base object but not during the search.
+ *
+ *
+ *
+ *
+ * LDAP_DEREF_ALWAYS - aliases should be dereferenced
+ * always.
+ *
+ *
+ *
+ * @param array $serverctrls Array of LDAP Controls to send with the request.
+ * @return resource Returns a search result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_list($link_identifier, string $base_dn, string $filter, array $attributes = null, int $attrsonly = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, array $serverctrls = null)
+{
+ error_clear_last();
+ if ($serverctrls !== null) {
+ $result = \ldap_list($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref, $serverctrls);
+ } elseif ($deref !== LDAP_DEREF_NEVER) {
+ $result = \ldap_list($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref);
+ } elseif ($timelimit !== -1) {
+ $result = \ldap_list($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit, $timelimit);
+ } elseif ($sizelimit !== -1) {
+ $result = \ldap_list($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit);
+ } elseif ($attrsonly !== 0) {
+ $result = \ldap_list($link_identifier, $base_dn, $filter, $attributes, $attrsonly);
+ } elseif ($attributes !== null) {
+ $result = \ldap_list($link_identifier, $base_dn, $filter, $attributes);
+ } else {
+ $result = \ldap_list($link_identifier, $base_dn, $filter);
+ }
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Does the same thing as ldap_mod_add but returns the LDAP result resource to be parsed with ldap_parse_result.
+ *
+ * @param resource $link_identifier
+ * @param string $dn
+ * @param array $entry
+ * @param array $serverctrls
+ * @return resource Returns an LDAP result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_mod_add_ext($link_identifier, string $dn, array $entry, array $serverctrls = null)
+{
+ error_clear_last();
+ $result = \ldap_mod_add_ext($link_identifier, $dn, $entry, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Adds one or more attribute values to the specified dn.
+ * To add a whole new object see ldap_add function.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string $dn The distinguished name of an LDAP entity.
+ * @param array $entry An associative array listing the attirbute values to add. If an attribute was not existing yet it will be added. If an attribute is existing you can only add values to it if it supports multiple values.
+ * @param array $serverctrls Array of LDAP Controls to send with the request.
+ * @throws LdapException
+ *
+ */
+function ldap_mod_add($link_identifier, string $dn, array $entry, array $serverctrls = null): void
+{
+ error_clear_last();
+ $result = \ldap_mod_add($link_identifier, $dn, $entry, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Does the same thing as ldap_mod_del but returns the LDAP result resource to be parsed with ldap_parse_result.
+ *
+ * @param resource $link_identifier
+ * @param string $dn
+ * @param array $entry
+ * @param array $serverctrls
+ * @return resource Returns an LDAP result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_mod_del_ext($link_identifier, string $dn, array $entry, array $serverctrls = null)
+{
+ error_clear_last();
+ $result = \ldap_mod_del_ext($link_identifier, $dn, $entry, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Removes one or more attribute values from the specified dn.
+ * Object deletions are done by the
+ * ldap_delete function.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string $dn The distinguished name of an LDAP entity.
+ * @param array $entry
+ * @param array $serverctrls Array of LDAP Controls to send with the request.
+ * @throws LdapException
+ *
+ */
+function ldap_mod_del($link_identifier, string $dn, array $entry, array $serverctrls = null): void
+{
+ error_clear_last();
+ $result = \ldap_mod_del($link_identifier, $dn, $entry, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Does the same thing as ldap_mod_replace but returns the LDAP result resource to be parsed with ldap_parse_result.
+ *
+ * @param resource $link_identifier
+ * @param string $dn
+ * @param array $entry
+ * @param array $serverctrls
+ * @return resource Returns an LDAP result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_mod_replace_ext($link_identifier, string $dn, array $entry, array $serverctrls = null)
+{
+ error_clear_last();
+ $result = \ldap_mod_replace_ext($link_identifier, $dn, $entry, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Replaces one or more attributes from the specified dn.
+ * It may also add or remove attributes.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string $dn The distinguished name of an LDAP entity.
+ * @param array $entry An associative array listing the attributes to replace. Sending an empty array as value will remove the attribute, while sending an attribute not existing yet on this entry will add it.
+ * @param array $serverctrls Array of LDAP Controls to send with the request.
+ * @throws LdapException
+ *
+ */
+function ldap_mod_replace($link_identifier, string $dn, array $entry, array $serverctrls = null): void
+{
+ error_clear_last();
+ $result = \ldap_mod_replace($link_identifier, $dn, $entry, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Modifies an existing entry in the LDAP directory. Allows detailed
+ * specification of the modifications to perform.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string $dn The distinguished name of an LDAP entity.
+ * @param array $entry An array that specifies the modifications to make. Each entry in this
+ * array is an associative array with two or three keys:
+ * attrib maps to the name of the attribute to modify,
+ * modtype maps to the type of modification to perform,
+ * and (depending on the type of modification) values
+ * maps to an array of attribute values relevant to the modification.
+ *
+ * Possible values for modtype include:
+ *
+ *
+ * LDAP_MODIFY_BATCH_ADD
+ *
+ *
+ * Each value specified through values is added (as
+ * an additional value) to the attribute named by
+ * attrib.
+ *
+ *
+ *
+ *
+ * LDAP_MODIFY_BATCH_REMOVE
+ *
+ *
+ * Each value specified through values is removed
+ * from the attribute named by attrib. Any value of
+ * the attribute not contained in the values array
+ * will remain untouched.
+ *
+ *
+ *
+ *
+ * LDAP_MODIFY_BATCH_REMOVE_ALL
+ *
+ *
+ * All values are removed from the attribute named by
+ * attrib. A values entry must
+ * not be provided.
+ *
+ *
+ *
+ *
+ * LDAP_MODIFY_BATCH_REPLACE
+ *
+ *
+ * All current values of the attribute named by
+ * attrib are replaced with the values specified
+ * through values.
+ *
+ *
+ *
+ *
+ *
+ * Each value specified through values is added (as
+ * an additional value) to the attribute named by
+ * attrib.
+ *
+ * Each value specified through values is removed
+ * from the attribute named by attrib. Any value of
+ * the attribute not contained in the values array
+ * will remain untouched.
+ *
+ * All values are removed from the attribute named by
+ * attrib. A values entry must
+ * not be provided.
+ *
+ * All current values of the attribute named by
+ * attrib are replaced with the values specified
+ * through values.
+ *
+ * Note that any value for attrib must be a string, any
+ * value for values must be an array of strings, and
+ * any value for modtype must be one of the
+ * LDAP_MODIFY_BATCH_* constants listed above.
+ * @param array $serverctrls Each value specified through values is added (as
+ * an additional value) to the attribute named by
+ * attrib.
+ * @throws LdapException
+ *
+ */
+function ldap_modify_batch($link_identifier, string $dn, array $entry, array $serverctrls = null): void
+{
+ error_clear_last();
+ $result = \ldap_modify_batch($link_identifier, $dn, $entry, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Retrieves the attributes in an entry. The first call to
+ * ldap_next_attribute is made with the
+ * result_entry_identifier returned from
+ * ldap_first_attribute.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result_entry_identifier
+ * @return string Returns the next attribute in an entry on success and FALSE on
+ * error.
+ * @throws LdapException
+ *
+ */
+function ldap_next_attribute($link_identifier, $result_entry_identifier): string
+{
+ error_clear_last();
+ $result = \ldap_next_attribute($link_identifier, $result_entry_identifier);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Parse LDAP extended operation data from result object result
+ *
+ * @param resource $link An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result An LDAP result resource, returned by ldap_exop.
+ * @param string|null $retdata Will be filled by the response data.
+ * @param string|null $retoid Will be filled by the response OID.
+ * @throws LdapException
+ *
+ */
+function ldap_parse_exop($link, $result, ?string &$retdata = null, ?string &$retoid = null): void
+{
+ error_clear_last();
+ $result = \ldap_parse_exop($link, $result, $retdata, $retoid);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Parses an LDAP search result.
+ *
+ * @param resource $link An LDAP link identifier, returned by ldap_connect.
+ * @param resource $result An LDAP result resource, returned by ldap_list or
+ * ldap_search.
+ * @param int|null $errcode A reference to a variable that will be set to the LDAP error code in
+ * the result, or 0 if no error occurred.
+ * @param string|null $matcheddn A reference to a variable that will be set to a matched DN if one was
+ * recognised within the request, otherwise it will be set to NULL.
+ * @param string|null $errmsg A reference to a variable that will be set to the LDAP error message in
+ * the result, or an empty string if no error occurred.
+ * @param array|null $referrals A reference to a variable that will be set to an array set
+ * to all of the referral strings in the result, or an empty array if no
+ * referrals were returned.
+ * @param array|null $serverctrls An array of LDAP Controls which have been sent with the response.
+ * @throws LdapException
+ *
+ */
+function ldap_parse_result($link, $result, ?int &$errcode, ?string &$matcheddn = null, ?string &$errmsg = null, ?array &$referrals = null, ?array &$serverctrls = null): void
+{
+ error_clear_last();
+ $result = \ldap_parse_result($link, $result, $errcode, $matcheddn, $errmsg, $referrals, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Performs the search for a specified filter on the
+ * directory with the scope LDAP_SCOPE_BASE. So it is
+ * equivalent to reading an entry from the directory.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string $base_dn The base DN for the directory.
+ * @param string $filter An empty filter is not allowed. If you want to retrieve absolutely all
+ * information for this entry, use a filter of
+ * objectClass=*. If you know which entry types are
+ * used on the directory server, you might use an appropriate filter such
+ * as objectClass=inetOrgPerson.
+ * @param array $attributes An array of the required attributes, e.g. array("mail", "sn", "cn").
+ * Note that the "dn" is always returned irrespective of which attributes
+ * types are requested.
+ *
+ * Using this parameter is much more efficient than the default action
+ * (which is to return all attributes and their associated values).
+ * The use of this parameter should therefore be considered good
+ * practice.
+ * @param int $attrsonly Should be set to 1 if only attribute types are wanted. If set to 0
+ * both attributes types and attribute values are fetched which is the
+ * default behaviour.
+ * @param int $sizelimit Enables you to limit the count of entries fetched. Setting this to 0
+ * means no limit.
+ *
+ * This parameter can NOT override server-side preset sizelimit. You can
+ * set it lower though.
+ *
+ * Some directory server hosts will be configured to return no more than
+ * a preset number of entries. If this occurs, the server will indicate
+ * that it has only returned a partial results set. This also occurs if
+ * you use this parameter to limit the count of fetched entries.
+ * @param int $timelimit Sets the number of seconds how long is spend on the search. Setting
+ * this to 0 means no limit.
+ *
+ * This parameter can NOT override server-side preset timelimit. You can
+ * set it lower though.
+ * @param int $deref Specifies how aliases should be handled during the search. It can be
+ * one of the following:
+ *
+ *
+ *
+ * LDAP_DEREF_NEVER - (default) aliases are never
+ * dereferenced.
+ *
+ *
+ *
+ *
+ * LDAP_DEREF_SEARCHING - aliases should be
+ * dereferenced during the search but not when locating the base object
+ * of the search.
+ *
+ *
+ *
+ *
+ * LDAP_DEREF_FINDING - aliases should be
+ * dereferenced when locating the base object but not during the search.
+ *
+ *
+ *
+ *
+ * LDAP_DEREF_ALWAYS - aliases should be dereferenced
+ * always.
+ *
+ *
+ *
+ * @param array $serverctrls Array of LDAP Controls to send with the request.
+ * @return resource Returns a search result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_read($link_identifier, string $base_dn, string $filter, array $attributes = null, int $attrsonly = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, array $serverctrls = null)
+{
+ error_clear_last();
+ if ($serverctrls !== null) {
+ $result = \ldap_read($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref, $serverctrls);
+ } elseif ($deref !== LDAP_DEREF_NEVER) {
+ $result = \ldap_read($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref);
+ } elseif ($timelimit !== -1) {
+ $result = \ldap_read($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit, $timelimit);
+ } elseif ($sizelimit !== -1) {
+ $result = \ldap_read($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit);
+ } elseif ($attrsonly !== 0) {
+ $result = \ldap_read($link_identifier, $base_dn, $filter, $attributes, $attrsonly);
+ } elseif ($attributes !== null) {
+ $result = \ldap_read($link_identifier, $base_dn, $filter, $attributes);
+ } else {
+ $result = \ldap_read($link_identifier, $base_dn, $filter);
+ }
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Does the same thing as ldap_rename but returns the LDAP result resource to be parsed with ldap_parse_result.
+ *
+ * @param resource $link_identifier
+ * @param string $dn
+ * @param string $newrdn
+ * @param string $newparent
+ * @param bool $deleteoldrdn
+ * @param array $serverctrls
+ * @return resource Returns an LDAP result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_rename_ext($link_identifier, string $dn, string $newrdn, string $newparent, bool $deleteoldrdn, array $serverctrls = null)
+{
+ error_clear_last();
+ $result = \ldap_rename_ext($link_identifier, $dn, $newrdn, $newparent, $deleteoldrdn, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * The entry specified by dn is renamed/moved.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string $dn The distinguished name of an LDAP entity.
+ * @param string $newrdn The new RDN.
+ * @param string $newparent The new parent/superior entry.
+ * @param bool $deleteoldrdn If TRUE the old RDN value(s) is removed, else the old RDN value(s)
+ * is retained as non-distinguished values of the entry.
+ * @param array $serverctrls Array of LDAP Controls to send with the request.
+ * @throws LdapException
+ *
+ */
+function ldap_rename($link_identifier, string $dn, string $newrdn, string $newparent, bool $deleteoldrdn, array $serverctrls = null): void
+{
+ error_clear_last();
+ $result = \ldap_rename($link_identifier, $dn, $newrdn, $newparent, $deleteoldrdn, $serverctrls);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ *
+ *
+ * @param resource $link
+ * @param string $binddn
+ * @param string $password
+ * @param string $sasl_mech
+ * @param string $sasl_realm
+ * @param string $sasl_authc_id
+ * @param string $sasl_authz_id
+ * @param string $props
+ * @throws LdapException
+ *
+ */
+function ldap_sasl_bind($link, string $binddn = null, string $password = null, string $sasl_mech = null, string $sasl_realm = null, string $sasl_authc_id = null, string $sasl_authz_id = null, string $props = null): void
+{
+ error_clear_last();
+ $result = \ldap_sasl_bind($link, $binddn, $password, $sasl_mech, $sasl_realm, $sasl_authc_id, $sasl_authz_id, $props);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Performs the search for a specified filter on the directory with the scope
+ * of LDAP_SCOPE_SUBTREE. This is equivalent to searching
+ * the entire directory.
+ *
+ * From 4.0.5 on it's also possible to do parallel searches. To do this
+ * you use an array of link identifiers, rather than a single identifier,
+ * as the first argument. If you don't want the same base DN and the
+ * same filter for all the searches, you can also use an array of base DNs
+ * and/or an array of filters. Those arrays must be of the same size as
+ * the link identifier array since the first entries of the arrays are
+ * used for one search, the second entries are used for another, and so
+ * on. When doing parallel searches an array of search result
+ * identifiers is returned, except in case of error, then the entry
+ * corresponding to the search will be FALSE. This is very much like
+ * the value normally returned, except that a result identifier is always
+ * returned when a search was made. There are some rare cases where the
+ * normal search returns FALSE while the parallel search returns an
+ * identifier.
+ *
+ * @param resource|array $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param string $base_dn The base DN for the directory.
+ * @param string $filter The search filter can be simple or advanced, using boolean operators in
+ * the format described in the LDAP documentation (see the Netscape Directory SDK or
+ * RFC4515 for full
+ * information on filters).
+ * @param array $attributes An array of the required attributes, e.g. array("mail", "sn", "cn").
+ * Note that the "dn" is always returned irrespective of which attributes
+ * types are requested.
+ *
+ * Using this parameter is much more efficient than the default action
+ * (which is to return all attributes and their associated values).
+ * The use of this parameter should therefore be considered good
+ * practice.
+ * @param int $attrsonly Should be set to 1 if only attribute types are wanted. If set to 0
+ * both attributes types and attribute values are fetched which is the
+ * default behaviour.
+ * @param int $sizelimit Enables you to limit the count of entries fetched. Setting this to 0
+ * means no limit.
+ *
+ * This parameter can NOT override server-side preset sizelimit. You can
+ * set it lower though.
+ *
+ * Some directory server hosts will be configured to return no more than
+ * a preset number of entries. If this occurs, the server will indicate
+ * that it has only returned a partial results set. This also occurs if
+ * you use this parameter to limit the count of fetched entries.
+ * @param int $timelimit Sets the number of seconds how long is spend on the search. Setting
+ * this to 0 means no limit.
+ *
+ * This parameter can NOT override server-side preset timelimit. You can
+ * set it lower though.
+ * @param int $deref Specifies how aliases should be handled during the search. It can be
+ * one of the following:
+ *
+ *
+ *
+ * LDAP_DEREF_NEVER - (default) aliases are never
+ * dereferenced.
+ *
+ *
+ *
+ *
+ * LDAP_DEREF_SEARCHING - aliases should be
+ * dereferenced during the search but not when locating the base object
+ * of the search.
+ *
+ *
+ *
+ *
+ * LDAP_DEREF_FINDING - aliases should be
+ * dereferenced when locating the base object but not during the search.
+ *
+ *
+ *
+ *
+ * LDAP_DEREF_ALWAYS - aliases should be dereferenced
+ * always.
+ *
+ *
+ *
+ * @param array $serverctrls Array of LDAP Controls to send with the request.
+ * @return resource Returns a search result identifier.
+ * @throws LdapException
+ *
+ */
+function ldap_search($link_identifier, string $base_dn, string $filter, array $attributes = null, int $attrsonly = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, array $serverctrls = null)
+{
+ error_clear_last();
+ if ($serverctrls !== null) {
+ $result = \ldap_search($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref, $serverctrls);
+ } elseif ($deref !== LDAP_DEREF_NEVER) {
+ $result = \ldap_search($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit, $timelimit, $deref);
+ } elseif ($timelimit !== -1) {
+ $result = \ldap_search($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit, $timelimit);
+ } elseif ($sizelimit !== -1) {
+ $result = \ldap_search($link_identifier, $base_dn, $filter, $attributes, $attrsonly, $sizelimit);
+ } elseif ($attrsonly !== 0) {
+ $result = \ldap_search($link_identifier, $base_dn, $filter, $attributes, $attrsonly);
+ } elseif ($attributes !== null) {
+ $result = \ldap_search($link_identifier, $base_dn, $filter, $attributes);
+ } else {
+ $result = \ldap_search($link_identifier, $base_dn, $filter);
+ }
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Sets the value of the specified option to be newval.
+ *
+ * @param resource|null $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @param int $option The parameter option can be one of:
+ *
+ *
+ *
+ *
+ * Option
+ * Type
+ * Available since
+ *
+ *
+ *
+ *
+ * LDAP_OPT_DEREF
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_SIZELIMIT
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_TIMELIMIT
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_NETWORK_TIMEOUT
+ * integer
+ * PHP 5.3.0
+ *
+ *
+ * LDAP_OPT_PROTOCOL_VERSION
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_ERROR_NUMBER
+ * integer
+ *
+ *
+ *
+ * LDAP_OPT_REFERRALS
+ * bool
+ *
+ *
+ *
+ * LDAP_OPT_RESTART
+ * bool
+ *
+ *
+ *
+ * LDAP_OPT_HOST_NAME
+ * string
+ *
+ *
+ *
+ * LDAP_OPT_ERROR_STRING
+ * string
+ *
+ *
+ *
+ * LDAP_OPT_DIAGNOSTIC_MESSAGE
+ * string
+ *
+ *
+ *
+ * LDAP_OPT_MATCHED_DN
+ * string
+ *
+ *
+ *
+ * LDAP_OPT_SERVER_CONTROLS
+ * array
+ *
+ *
+ *
+ * LDAP_OPT_CLIENT_CONTROLS
+ * array
+ *
+ *
+ *
+ * LDAP_OPT_X_KEEPALIVE_IDLE
+ * int
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_KEEPALIVE_PROBES
+ * int
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_KEEPALIVE_INTERVAL
+ * int
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_CACERTDIR
+ * string
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_CACERTFILE
+ * string
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_CERTFILE
+ * string
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_CIPHER_SUITE
+ * string
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_CRLCHECK
+ * integer
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_CRLFILE
+ * string
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_DHFILE
+ * string
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_KEYFILE
+ * string
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_PROTOCOL_MIN
+ * integer
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_RANDOM_FILE
+ * string
+ * PHP 7.1.0
+ *
+ *
+ * LDAP_OPT_X_TLS_REQUIRE_CERT
+ * integer
+ * PHP 7.0.5
+ *
+ *
+ *
+ *
+ *
+ * LDAP_OPT_SERVER_CONTROLS and
+ * LDAP_OPT_CLIENT_CONTROLS require a list of
+ * controls, this means that the value must be an array of controls. A
+ * control consists of an oid identifying the control,
+ * an optional value, and an optional flag for
+ * criticality. In PHP a control is given by an
+ * array containing an element with the key oid
+ * and string value, and two optional elements. The optional
+ * elements are key value with string value
+ * and key iscritical with boolean value.
+ * iscritical defaults to FALSE
+ * if not supplied. See draft-ietf-ldapext-ldap-c-api-xx.txt
+ * for details. See also the second example below.
+ * @param mixed $newval The new value for the specified option.
+ * @throws LdapException
+ *
+ */
+function ldap_set_option($link_identifier, int $option, $newval): void
+{
+ error_clear_last();
+ $result = \ldap_set_option($link_identifier, $option, $newval);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
+
+
+/**
+ * Unbinds from the LDAP directory.
+ *
+ * @param resource $link_identifier An LDAP link identifier, returned by ldap_connect.
+ * @throws LdapException
+ *
+ */
+function ldap_unbind($link_identifier): void
+{
+ error_clear_last();
+ $result = \ldap_unbind($link_identifier);
+ if ($result === false) {
+ throw LdapException::createFromPhpError();
+ }
+}
diff --git a/vendor/thecodingmachine/safe/generated/libxml.php b/vendor/thecodingmachine/safe/generated/libxml.php
new file mode 100644
index 000000000..cef784c42
--- /dev/null
+++ b/vendor/thecodingmachine/safe/generated/libxml.php
@@ -0,0 +1,43 @@
+
+ *
+ * The above example will output:
+ *
+ * example: , this is a test
+ * example: , this is a test
+ * ]]>
+ *
+ *
+ * So, $out[0] contains array of strings that matched full pattern,
+ * and $out[1] contains array of strings enclosed by tags.
+ *
+ *
+ *
+ *
+ * If the pattern contains named subpatterns, $matches
+ * additionally contains entries for keys with the subpattern name.
+ *
+ *
+ * If the pattern contains duplicate named subpatterns, only the rightmost
+ * subpattern is stored in $matches[NAME].
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ *
+ * [1] => bar
+ * )
+ * ]]>
+ *
+ *
+ *
+ *
+ *
+ *
+ * PREG_SET_ORDER
+ *
+ *
+ * Orders results so that $matches[0] is an array of first set
+ * of matches, $matches[1] is an array of second set of matches,
+ * and so on.
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ * example: , example:
+ * this is a test, this is a test
+ * ]]>
+ *
+ *
+ *
+ *
+ *
+ *
+ * PREG_OFFSET_CAPTURE
+ *
+ *
+ * If this flag is passed, for every occurring match the appendant string
+ * offset (in bytes) will also be returned. Note that this changes the value of
+ * matches into an array of arrays where every element is an
+ * array consisting of the matched string at offset 0
+ * and its string offset into subject at offset
+ * 1.
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ * Array
+ * (
+ * [0] => Array
+ * (
+ * [0] => foobarbaz
+ * [1] => 0
+ * )
+ *
+ * )
+ *
+ * [1] => Array
+ * (
+ * [0] => Array
+ * (
+ * [0] => foo
+ * [1] => 0
+ * )
+ *
+ * )
+ *
+ * [2] => Array
+ * (
+ * [0] => Array
+ * (
+ * [0] => bar
+ * [1] => 3
+ * )
+ *
+ * )
+ *
+ * [3] => Array
+ * (
+ * [0] => Array
+ * (
+ * [0] => baz
+ * [1] => 6
+ * )
+ *
+ * )
+ *
+ * )
+ * ]]>
+ *
+ *
+ *
+ *
+ *
+ *
+ * PREG_UNMATCHED_AS_NULL
+ *
+ *
+ * If this flag is passed, unmatched subpatterns are reported as NULL;
+ * otherwise they are reported as an empty string.
+ *
+ *
+ *
+ *
+ *
+ * Orders results so that $matches[0] is an array of full
+ * pattern matches, $matches[1] is an array of strings matched by
+ * the first parenthesized subpattern, and so on.
+ *
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ * example: , this is a test
+ * example: , this is a test
+ * ]]>
+ *
+ *
+ * So, $out[0] contains array of strings that matched full pattern,
+ * and $out[1] contains array of strings enclosed by tags.
+ *
+ *
+ *
+ * The above example will output:
+ *
+ * So, $out[0] contains array of strings that matched full pattern,
+ * and $out[1] contains array of strings enclosed by tags.
+ *
+ * If the pattern contains named subpatterns, $matches
+ * additionally contains entries for keys with the subpattern name.
+ *
+ * If the pattern contains duplicate named subpatterns, only the rightmost
+ * subpattern is stored in $matches[NAME].
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ *
+ * [1] => bar
+ * )
+ * ]]>
+ *
+ *
+ *
+ * The above example will output:
+ *
+ * Orders results so that $matches[0] is an array of first set
+ * of matches, $matches[1] is an array of second set of matches,
+ * and so on.
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ * example: , example:
+ * this is a test, this is a test
+ * ]]>
+ *
+ *
+ *
+ * The above example will output:
+ *
+ * If this flag is passed, for every occurring match the appendant string
+ * offset (in bytes) will also be returned. Note that this changes the value of
+ * matches into an array of arrays where every element is an
+ * array consisting of the matched string at offset 0
+ * and its string offset into subject at offset
+ * 1.
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ * Array
+ * (
+ * [0] => Array
+ * (
+ * [0] => foobarbaz
+ * [1] => 0
+ * )
+ *
+ * )
+ *
+ * [1] => Array
+ * (
+ * [0] => Array
+ * (
+ * [0] => foo
+ * [1] => 0
+ * )
+ *
+ * )
+ *
+ * [2] => Array
+ * (
+ * [0] => Array
+ * (
+ * [0] => bar
+ * [1] => 3
+ * )
+ *
+ * )
+ *
+ * [3] => Array
+ * (
+ * [0] => Array
+ * (
+ * [0] => baz
+ * [1] => 6
+ * )
+ *
+ * )
+ *
+ * )
+ * ]]>
+ *
+ *
+ *
+ * The above example will output:
+ *
+ * If this flag is passed, unmatched subpatterns are reported as NULL;
+ * otherwise they are reported as an empty string.
+ *
+ * If no order flag is given, PREG_PATTERN_ORDER is
+ * assumed.
+ * @param int $offset Orders results so that $matches[0] is an array of full
+ * pattern matches, $matches[1] is an array of strings matched by
+ * the first parenthesized subpattern, and so on.
+ *
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ * example: , this is a test
+ * example: , this is a test
+ * ]]>
+ *
+ *
+ * So, $out[0] contains array of strings that matched full pattern,
+ * and $out[1] contains array of strings enclosed by tags.
+ *
+ *
+ *
+ * The above example will output:
+ *
+ * So, $out[0] contains array of strings that matched full pattern,
+ * and $out[1] contains array of strings enclosed by tags.
+ *
+ * If the pattern contains named subpatterns, $matches
+ * additionally contains entries for keys with the subpattern name.
+ *
+ * If the pattern contains duplicate named subpatterns, only the rightmost
+ * subpattern is stored in $matches[NAME].
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ *
+ * [1] => bar
+ * )
+ * ]]>
+ *
+ *
+ *
+ * The above example will output:
+ * @return int Returns the number of full pattern matches (which might be zero).
+ * @throws PcreException
+ *
+ */
+function preg_match_all(string $pattern, string $subject, array &$matches = null, int $flags = PREG_PATTERN_ORDER, int $offset = 0): int
+{
+ error_clear_last();
+ $result = \preg_match_all($pattern, $subject, $matches, $flags, $offset);
+ if ($result === false) {
+ throw PcreException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Searches subject for a match to the regular
+ * expression given in pattern.
+ *
+ * @param string $pattern The pattern to search for, as a string.
+ * @param string $subject The input string.
+ * @param array $matches If matches is provided, then it is filled with
+ * the results of search. $matches[0] will contain the
+ * text that matched the full pattern, $matches[1]
+ * will have the text that matched the first captured parenthesized
+ * subpattern, and so on.
+ * @param int $flags flags can be a combination of the following flags:
+ *
+ *
+ * PREG_OFFSET_CAPTURE
+ *
+ *
+ * If this flag is passed, for every occurring match the appendant string
+ * offset (in bytes) will also be returned. Note that this changes the value of
+ * matches into an array where every element is an
+ * array consisting of the matched string at offset 0
+ * and its string offset into subject at offset
+ * 1.
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ * Array
+ * (
+ * [0] => foobarbaz
+ * [1] => 0
+ * )
+ *
+ * [1] => Array
+ * (
+ * [0] => foo
+ * [1] => 0
+ * )
+ *
+ * [2] => Array
+ * (
+ * [0] => bar
+ * [1] => 3
+ * )
+ *
+ * [3] => Array
+ * (
+ * [0] => baz
+ * [1] => 6
+ * )
+ *
+ * )
+ * ]]>
+ *
+ *
+ *
+ *
+ *
+ *
+ * PREG_UNMATCHED_AS_NULL
+ *
+ *
+ * If this flag is passed, unmatched subpatterns are reported as NULL;
+ * otherwise they are reported as an empty string.
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ *
+ * string(2) "ac"
+ * [1]=>
+ * string(1) "a"
+ * [2]=>
+ * string(0) ""
+ * [3]=>
+ * string(1) "c"
+ * }
+ * array(4) {
+ * [0]=>
+ * string(2) "ac"
+ * [1]=>
+ * string(1) "a"
+ * [2]=>
+ * NULL
+ * [3]=>
+ * string(1) "c"
+ * }
+ * ]]>
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * If this flag is passed, for every occurring match the appendant string
+ * offset (in bytes) will also be returned. Note that this changes the value of
+ * matches into an array where every element is an
+ * array consisting of the matched string at offset 0
+ * and its string offset into subject at offset
+ * 1.
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ * Array
+ * (
+ * [0] => foobarbaz
+ * [1] => 0
+ * )
+ *
+ * [1] => Array
+ * (
+ * [0] => foo
+ * [1] => 0
+ * )
+ *
+ * [2] => Array
+ * (
+ * [0] => bar
+ * [1] => 3
+ * )
+ *
+ * [3] => Array
+ * (
+ * [0] => baz
+ * [1] => 6
+ * )
+ *
+ * )
+ * ]]>
+ *
+ *
+ *
+ * The above example will output:
+ *
+ * If this flag is passed, unmatched subpatterns are reported as NULL;
+ * otherwise they are reported as an empty string.
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ *
+ * string(2) "ac"
+ * [1]=>
+ * string(1) "a"
+ * [2]=>
+ * string(0) ""
+ * [3]=>
+ * string(1) "c"
+ * }
+ * array(4) {
+ * [0]=>
+ * string(2) "ac"
+ * [1]=>
+ * string(1) "a"
+ * [2]=>
+ * NULL
+ * [3]=>
+ * string(1) "c"
+ * }
+ * ]]>
+ *
+ *
+ *
+ * The above example will output:
+ * @param int $offset If this flag is passed, for every occurring match the appendant string
+ * offset (in bytes) will also be returned. Note that this changes the value of
+ * matches into an array where every element is an
+ * array consisting of the matched string at offset 0
+ * and its string offset into subject at offset
+ * 1.
+ *
+ *
+ *
+ * ]]>
+ *
+ * The above example will output:
+ *
+ * Array
+ * (
+ * [0] => foobarbaz
+ * [1] => 0
+ * )
+ *
+ * [1] => Array
+ * (
+ * [0] => foo
+ * [1] => 0
+ * )
+ *
+ * [2] => Array
+ * (
+ * [0] => bar
+ * [1] => 3
+ * )
+ *
+ * [3] => Array
+ * (
+ * [0] => baz
+ * [1] => 6
+ * )
+ *
+ * )
+ * ]]>
+ *
+ *
+ *
+ * The above example will output:
+ * @return int preg_match returns 1 if the pattern
+ * matches given subject, 0 if it does not.
+ * @throws PcreException
+ *
+ */
+function preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int
+{
+ error_clear_last();
+ $result = \preg_match($pattern, $subject, $matches, $flags, $offset);
+ if ($result === false) {
+ throw PcreException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Split the given string by a regular expression.
+ *
+ * @param string $pattern The pattern to search for, as a string.
+ * @param string $subject The input string.
+ * @param int|null $limit If specified, then only substrings up to limit
+ * are returned with the rest of the string being placed in the last
+ * substring. A limit of -1 or 0 means "no limit".
+ * @param int $flags flags can be any combination of the following
+ * flags (combined with the | bitwise operator):
+ *
+ *
+ * PREG_SPLIT_NO_EMPTY
+ *
+ *
+ * If this flag is set, only non-empty pieces will be returned by
+ * preg_split.
+ *
+ *
+ *
+ *
+ * PREG_SPLIT_DELIM_CAPTURE
+ *
+ *
+ * If this flag is set, parenthesized expression in the delimiter pattern
+ * will be captured and returned as well.
+ *
+ *
+ *
+ *
+ * PREG_SPLIT_OFFSET_CAPTURE
+ *
+ *
+ * If this flag is set, for every occurring match the appendant string
+ * offset will also be returned. Note that this changes the return
+ * value in an array where every element is an array consisting of the
+ * matched string at offset 0 and its string offset
+ * into subject at offset 1.
+ *
+ *
+ *
+ *
+ *
+ * If this flag is set, for every occurring match the appendant string
+ * offset will also be returned. Note that this changes the return
+ * value in an array where every element is an array consisting of the
+ * matched string at offset 0 and its string offset
+ * into subject at offset 1.
+ * @return array Returns an array containing substrings of subject
+ * split along boundaries matched by pattern.
+ * @throws PcreException
+ *
+ */
+function preg_split(string $pattern, string $subject, ?int $limit = -1, int $flags = 0): array
+{
+ error_clear_last();
+ $result = \preg_split($pattern, $subject, $limit, $flags);
+ if ($result === false) {
+ throw PcreException::createFromPhpError();
+ }
+ return $result;
+}
diff --git a/vendor/thecodingmachine/safe/generated/pdf.php b/vendor/thecodingmachine/safe/generated/pdf.php
new file mode 100644
index 000000000..d039b27a9
--- /dev/null
+++ b/vendor/thecodingmachine/safe/generated/pdf.php
@@ -0,0 +1,1553 @@
+
+ * ]]>
+ *
+ *
+ *
+ * @param string $prompt The prompt message.
+ * @param callable $callback The callback function takes one parameter; the
+ * user input returned.
+ * @throws ReadlineException
+ *
+ */
+function readline_callback_handler_install(string $prompt, callable $callback): void
+{
+ error_clear_last();
+ $result = \readline_callback_handler_install($prompt, $callback);
+ if ($result === false) {
+ throw ReadlineException::createFromPhpError();
+ }
+}
+
+
+/**
+ * This function clears the entire command line history.
+ *
+ * @throws ReadlineException
+ *
+ */
+function readline_clear_history(): void
+{
+ error_clear_last();
+ $result = \readline_clear_history();
+ if ($result === false) {
+ throw ReadlineException::createFromPhpError();
+ }
+}
+
+
+/**
+ * This function registers a completion function. This is the same kind of
+ * functionality you'd get if you hit your tab key while using Bash.
+ *
+ * @param callable $function You must supply the name of an existing function which accepts a
+ * partial command line and returns an array of possible matches.
+ * @throws ReadlineException
+ *
+ */
+function readline_completion_function(callable $function): void
+{
+ error_clear_last();
+ $result = \readline_completion_function($function);
+ if ($result === false) {
+ throw ReadlineException::createFromPhpError();
+ }
+}
+
+
+/**
+ * This function reads a command history from a file.
+ *
+ * @param string $filename Path to the filename containing the command history.
+ * @throws ReadlineException
+ *
+ */
+function readline_read_history(string $filename = null): void
+{
+ error_clear_last();
+ if ($filename !== null) {
+ $result = \readline_read_history($filename);
+ } else {
+ $result = \readline_read_history();
+ }
+ if ($result === false) {
+ throw ReadlineException::createFromPhpError();
+ }
+}
+
+
+/**
+ * This function writes the command history to a file.
+ *
+ * @param string $filename Path to the saved file.
+ * @throws ReadlineException
+ *
+ */
+function readline_write_history(string $filename = null): void
+{
+ error_clear_last();
+ if ($filename !== null) {
+ $result = \readline_write_history($filename);
+ } else {
+ $result = \readline_write_history();
+ }
+ if ($result === false) {
+ throw ReadlineException::createFromPhpError();
+ }
+}
diff --git a/vendor/thecodingmachine/safe/generated/rpminfo.php b/vendor/thecodingmachine/safe/generated/rpminfo.php
new file mode 100644
index 000000000..44de1ce23
--- /dev/null
+++ b/vendor/thecodingmachine/safe/generated/rpminfo.php
@@ -0,0 +1,21 @@
+
+ *
+ *
+ * @param int $length If length is given and is positive, the string
+ * returned will contain at most length characters
+ * beginning from start (depending on the length of
+ * string).
+ *
+ * If length is given and is negative, then that many
+ * characters will be omitted from the end of string
+ * (after the start position has been calculated when a
+ * start is negative). If
+ * start denotes the position of this truncation or
+ * beyond, FALSE will be returned.
+ *
+ * If length is given and is 0,
+ * FALSE or NULL, an empty string will be returned.
+ *
+ * If length is omitted, the substring starting from
+ * start until the end of the string will be
+ * returned.
+ * @return string Returns the extracted part of string;, or
+ * an empty string.
+ * @throws StringsException
+ *
+ */
+function substr(string $string, int $start, int $length = null): string
+{
+ error_clear_last();
+ if ($length !== null) {
+ $result = \substr($string, $start, $length);
+ } else {
+ $result = \substr($string, $start);
+ }
+ if ($result === false) {
+ throw StringsException::createFromPhpError();
+ }
+ return $result;
+}
+
+
+/**
+ * Operates as sprintf but accepts an array of
+ * arguments, rather than a variable number of arguments.
+ *
+ * @param string $format The format string is composed of zero or more directives:
+ * ordinary characters (excluding %) that are
+ * copied directly to the result and conversion
+ * specifications, each of which results in fetching its
+ * own parameter.
+ *
+ * A conversion specification follows this prototype:
+ * %[argnum$][flags][width][.precision]specifier.
+ *
+ * An integer followed by a dollar sign $,
+ * to specify which number argument to treat in the conversion.
+ *
+ *
+ * Flags
+ *
+ *
+ *
+ * Flag
+ * Description
+ *
+ *
+ *
+ *
+ * -
+ *
+ * Left-justify within the given field width;
+ * Right justification is the default
+ *
+ *
+ *
+ * +
+ *
+ * Prefix positive numbers with a plus sign
+ * +; Default only negative
+ * are prefixed with a negative sign.
+ *
+ *
+ *
+ * (space)
+ *
+ * Pads the result with spaces.
+ * This is the default.
+ *
+ *
+ *
+ * 0
+ *
+ * Only left-pads numbers with zeros.
+ * With s specifiers this can
+ * also right-pad with zeros.
+ *
+ *
+ *
+ * '(char)
+ *
+ * Pads the result with the character (char).
+ *
+ *
+ *
+ *
+ *
+ *
+ * An integer that says how many characters (minimum)
+ * this conversion should result in.
+ *
+ * A period . followed by an integer
+ * who's meaning depends on the specifier:
+ *
+ *
+ *
+ * For e, E,
+ * f and F
+ * specifiers: this is the number of digits to be printed
+ * after the decimal point (by default, this is 6).
+ *
+ *
+ *
+ *
+ * For g and G
+ * specifiers: this is the maximum number of significant
+ * digits to be printed.
+ *
+ *
+ *
+ *
+ * For s specifier: it acts as a cutoff point,
+ * setting a maximum character limit to the string.
+ *
+ *
+ *
+ *
+ *
+ * If the period is specified without an explicit value for precision,
+ * 0 is assumed.
+ *
+ *
+ *
+ *
+ * Specifiers
+ *
+ *
+ *
+ * Specifier
+ * Description
+ *
+ *
+ *
+ *
+ * %
+ *
+ * A literal percent character. No argument is required.
+ *
+ *
+ *
+ * b
+ *
+ * The argument is treated as an integer and presented
+ * as a binary number.
+ *
+ *
+ *
+ * c
+ *
+ * The argument is treated as an integer and presented
+ * as the character with that ASCII.
+ *
+ *
+ *
+ * d
+ *
+ * The argument is treated as an integer and presented
+ * as a (signed) decimal number.
+ *
+ *
+ *
+ * e
+ *
+ * The argument is treated as scientific notation (e.g. 1.2e+2).
+ * The precision specifier stands for the number of digits after the
+ * decimal point since PHP 5.2.1. In earlier versions, it was taken as
+ * number of significant digits (one less).
+ *
+ *
+ *
+ * E
+ *
+ * Like the e specifier but uses
+ * uppercase letter (e.g. 1.2E+2).
+ *
+ *
+ *
+ * f
+ *
+ * The argument is treated as a float and presented
+ * as a floating-point number (locale aware).
+ *
+ *
+ *
+ * F
+ *
+ * The argument is treated as a float and presented
+ * as a floating-point number (non-locale aware).
+ * Available as of PHP 5.0.3.
+ *
+ *
+ *
+ * g
+ *
+ *
+ * General format.
+ *
+ *
+ * Let P equal the precision if nonzero, 6 if the precision is omitted,
+ * or 1 if the precision is zero.
+ * Then, if a conversion with style E would have an exponent of X:
+ *
+ *
+ * If P > X ≥ −4, the conversion is with style f and precision P − (X + 1).
+ * Otherwise, the conversion is with style e and precision P − 1.
+ *
+ *
+ *
+ *
+ * G
+ *
+ * Like the g specifier but uses
+ * E and f.
+ *
+ *
+ *
+ * o
+ *
+ * The argument is treated as an integer and presented
+ * as an octal number.
+ *
+ *
+ *
+ * s
+ *
+ * The argument is treated and presented as a string.
+ *
+ *
+ *
+ * u
+ *
+ * The argument is treated as an integer and presented
+ * as an unsigned decimal number.
+ *
+ *
+ *
+ * x
+ *
+ * The argument is treated as an integer and presented
+ * as a hexadecimal number (with lowercase letters).
+ *
+ *
+ *
+ * X
+ *
+ * The argument is treated as an integer and presented
+ * as a hexadecimal number (with uppercase letters).
+ *
+ *
+ *
+ *
+ *
+ *
+ * General format.
+ *
+ * Let P equal the precision if nonzero, 6 if the precision is omitted,
+ * or 1 if the precision is zero.
+ * Then, if a conversion with style E would have an exponent of X:
+ *
+ * If P > X ≥ −4, the conversion is with style f and precision P − (X + 1).
+ * Otherwise, the conversion is with style e and precision P − 1.
+ *
+ * The c type specifier ignores padding and width
+ *
+ * Attempting to use a combination of the string and width specifiers with character sets that require more than one byte per character may result in unexpected results
+ *
+ * Variables will be co-erced to a suitable type for the specifier:
+ *
+ * Type Handling
+ *
+ *
+ *
+ * Type
+ * Specifiers
+ *
+ *
+ *
+ *
+ * string
+ * s
+ *
+ *
+ * integer
+ *
+ * d,
+ * u,
+ * c,
+ * o,
+ * x,
+ * X,
+ * b
+ *
+ *
+ *
+ * double
+ *
+ * g,
+ * G,
+ * e,
+ * E,
+ * f,
+ * F
+ *
+ *
+ *
+ *
+ *
+ * @param array $args
+ * @return string Return array values as a formatted string according to
+ * format.
+ * @throws StringsException
+ *
+ */
+function vsprintf(string $format, array $args): string
+{
+ error_clear_last();
+ $result = \vsprintf($format, $args);
+ if ($result === false) {
+ throw StringsException::createFromPhpError();
+ }
+ return $result;
+}
diff --git a/vendor/thecodingmachine/safe/generated/swoole.php b/vendor/thecodingmachine/safe/generated/swoole.php
new file mode 100644
index 000000000..334d96bd9
--- /dev/null
+++ b/vendor/thecodingmachine/safe/generated/swoole.php
@@ -0,0 +1,108 @@
+format('Y-m-d H:i:s.u'), $datetime->getTimezone());
+ }
+
+ /**
+ * @param string $format
+ * @param string $time
+ * @param DateTimeZone|null $timezone
+ * @throws DatetimeException
+ */
+ public static function createFromFormat($format, $time, $timezone = null): self
+ {
+ $datetime = parent::createFromFormat($format, $time, $timezone);
+ if ($datetime === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return self::createFromRegular($datetime);
+ }
+
+ /**
+ * @param DateTimeInterface $datetime2 The date to compare to.
+ * @param boolean $absolute [optional] Whether to return absolute difference.
+ * @return DateInterval The DateInterval object representing the difference between the two dates.
+ * @throws DatetimeException
+ */
+ public function diff($datetime2, $absolute = false): DateInterval
+ {
+ /** @var \DateInterval|false $result */
+ $result = parent::diff($datetime2, $absolute);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return $result;
+ }
+
+ /**
+ * @param string $modify A date/time string. Valid formats are explained in Date and Time Formats.
+ * @return DateTime Returns the DateTime object for method chaining.
+ * @throws DatetimeException
+ */
+ public function modify($modify): self
+ {
+ /** @var DateTime|false $result */
+ $result = parent::modify($modify);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return $result;
+ }
+
+ /**
+ * @param int $year
+ * @param int $month
+ * @param int $day
+ * @return DateTime
+ * @throws DatetimeException
+ */
+ public function setDate($year, $month, $day): self
+ {
+ /** @var DateTime|false $result */
+ $result = parent::setDate($year, $month, $day);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return $result;
+ }
+}
diff --git a/vendor/thecodingmachine/safe/lib/DateTimeImmutable.php b/vendor/thecodingmachine/safe/lib/DateTimeImmutable.php
new file mode 100644
index 000000000..114ec3a3d
--- /dev/null
+++ b/vendor/thecodingmachine/safe/lib/DateTimeImmutable.php
@@ -0,0 +1,262 @@
+innerDateTime = new parent($time, $timezone);
+ }
+
+ //switch between regular datetime and safe version
+ public static function createFromRegular(\DateTimeImmutable $datetime): self
+ {
+ $safeDatetime = new self($datetime->format('Y-m-d H:i:s.u'), $datetime->getTimezone()); //we need to also update the wrapper to not break the operators '<' and '>'
+ $safeDatetime->innerDateTime = $datetime; //to make sure we don't lose information because of the format().
+ return $safeDatetime;
+ }
+
+ //usefull if you need to switch back to regular DateTimeImmutable (for example when using DatePeriod)
+ public function getInnerDateTime(): \DateTimeImmutable
+ {
+ return $this->innerDateTime;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ // overload functions with false errors
+
+ /**
+ * @param string $format
+ * @param string $time
+ * @param DateTimeZone|null $timezone
+ * @throws DatetimeException
+ */
+ public static function createFromFormat($format, $time, $timezone = null): self
+ {
+ $datetime = parent::createFromFormat($format, $time, $timezone);
+ if ($datetime === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return self::createFromRegular($datetime);
+ }
+
+ /**
+ * @param string $format
+ * @return string
+ * @throws DatetimeException
+ */
+ public function format($format): string
+ {
+ /** @var string|false $result */
+ $result = $this->innerDateTime->format($format);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return $result;
+ }
+
+ /**
+ * @param DateTimeInterface $datetime2
+ * @param bool $absolute
+ * @return DateInterval
+ * @throws DatetimeException
+ */
+ public function diff($datetime2, $absolute = false): DateInterval
+ {
+ /** @var \DateInterval|false $result */
+ $result = $this->innerDateTime->diff($datetime2, $absolute);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return $result;
+ }
+
+ /**
+ * @param string $modify
+ * @return DateTimeImmutable
+ * @throws DatetimeException
+ */
+ public function modify($modify): self
+ {
+ /** @var \DateTimeImmutable|false $result */
+ $result = $this->innerDateTime->modify($modify);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable
+ }
+
+ /**
+ * @param int $year
+ * @param int $month
+ * @param int $day
+ * @return DateTimeImmutable
+ * @throws DatetimeException
+ */
+ public function setDate($year, $month, $day): self
+ {
+ /** @var \DateTimeImmutable|false $result */
+ $result = $this->innerDateTime->setDate($year, $month, $day);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable
+ }
+
+ /**
+ * @param int $year
+ * @param int $week
+ * @param int $day
+ * @return DateTimeImmutable
+ * @throws DatetimeException
+ */
+ public function setISODate($year, $week, $day = 1): self
+ {
+ /** @var \DateTimeImmutable|false $result */
+ $result = $this->innerDateTime->setISODate($year, $week, $day);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return self::createFromRegular($result); //we have to recreate a safe datetime because modify create a new instance of \DateTimeImmutable
+ }
+
+ /**
+ * @param int $hour
+ * @param int $minute
+ * @param int $second
+ * @param int $microseconds
+ * @return DateTimeImmutable
+ * @throws DatetimeException
+ */
+ public function setTime($hour, $minute, $second = 0, $microseconds = 0): self
+ {
+ /** @var \DateTimeImmutable|false $result */
+ $result = $this->innerDateTime->setTime($hour, $minute, $second, $microseconds);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return self::createFromRegular($result);
+ }
+
+ /**
+ * @param int $unixtimestamp
+ * @return DateTimeImmutable
+ * @throws DatetimeException
+ */
+ public function setTimestamp($unixtimestamp): self
+ {
+ /** @var \DateTimeImmutable|false $result */
+ $result = $this->innerDateTime->setTimestamp($unixtimestamp);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return self::createFromRegular($result);
+ }
+
+ /**
+ * @param DateTimeZone $timezone
+ * @return DateTimeImmutable
+ * @throws DatetimeException
+ */
+ public function setTimezone($timezone): self
+ {
+ /** @var \DateTimeImmutable|false $result */
+ $result = $this->innerDateTime->setTimezone($timezone);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return self::createFromRegular($result);
+ }
+
+ /**
+ * @param DateInterval $interval
+ * @return DateTimeImmutable
+ * @throws DatetimeException
+ */
+ public function sub($interval): self
+ {
+ /** @var \DateTimeImmutable|false $result */
+ $result = $this->innerDateTime->sub($interval);
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return self::createFromRegular($result);
+ }
+
+ /**
+ * @throws DatetimeException
+ */
+ public function getOffset(): int
+ {
+ /** @var int|false $result */
+ $result = $this->innerDateTime->getOffset();
+ if ($result === false) {
+ throw DatetimeException::createFromPhpError();
+ }
+ return $result;
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ //overload getters to use the inner datetime immutable instead of itself
+
+ /**
+ * @param DateInterval $interval
+ * @return DateTimeImmutable
+ */
+ public function add($interval): self
+ {
+ return self::createFromRegular($this->innerDateTime->add($interval));
+ }
+
+ /**
+ * @param DateTime $dateTime
+ * @return DateTimeImmutable
+ */
+ public static function createFromMutable($dateTime): self
+ {
+ return self::createFromRegular(parent::createFromMutable($dateTime));
+ }
+
+ /**
+ * @param mixed[] $array
+ * @return DateTimeImmutable
+ */
+ public static function __set_state($array): self
+ {
+ return self::createFromRegular(parent::__set_state($array));
+ }
+
+ public function getTimezone(): DateTimeZone
+ {
+ return $this->innerDateTime->getTimezone();
+ }
+
+ public function getTimestamp(): int
+ {
+ return $this->innerDateTime->getTimestamp();
+ }
+}
diff --git a/vendor/thecodingmachine/safe/lib/Exceptions/CurlException.php b/vendor/thecodingmachine/safe/lib/Exceptions/CurlException.php
new file mode 100644
index 000000000..2814066b0
--- /dev/null
+++ b/vendor/thecodingmachine/safe/lib/Exceptions/CurlException.php
@@ -0,0 +1,15 @@
+ 'PREG_INTERNAL_ERROR: Internal error',
+ PREG_BACKTRACK_LIMIT_ERROR => 'PREG_BACKTRACK_LIMIT_ERROR: Backtrack limit reached',
+ PREG_RECURSION_LIMIT_ERROR => 'PREG_RECURSION_LIMIT_ERROR: Recursion limit reached',
+ PREG_BAD_UTF8_ERROR => 'PREG_BAD_UTF8_ERROR: Invalid UTF8 character',
+ PREG_BAD_UTF8_OFFSET_ERROR => 'PREG_BAD_UTF8_OFFSET_ERROR',
+ PREG_JIT_STACKLIMIT_ERROR => 'PREG_JIT_STACKLIMIT_ERROR',
+ ];
+ $errMsg = $errorMap[preg_last_error()] ?? 'Unknown PCRE error: '.preg_last_error();
+ return new self($errMsg, \preg_last_error());
+ }
+}
diff --git a/vendor/thecodingmachine/safe/lib/Exceptions/SafeExceptionInterface.php b/vendor/thecodingmachine/safe/lib/Exceptions/SafeExceptionInterface.php
new file mode 100644
index 000000000..fbea6ad25
--- /dev/null
+++ b/vendor/thecodingmachine/safe/lib/Exceptions/SafeExceptionInterface.php
@@ -0,0 +1,9 @@
+services();
+
+ $services->set(RenameFunctionRector::class)
+ ->call('configure', [[ RenameFunctionRector::OLD_FUNCTION_TO_NEW_FUNCTION => [
+ 'apache_getenv' => 'Safe\apache_getenv',
+ 'apache_get_version' => 'Safe\apache_get_version',
+ 'apache_request_headers' => 'Safe\apache_request_headers',
+ 'apache_reset_timeout' => 'Safe\apache_reset_timeout',
+ 'apache_response_headers' => 'Safe\apache_response_headers',
+ 'apache_setenv' => 'Safe\apache_setenv',
+ 'apcu_cache_info' => 'Safe\apcu_cache_info',
+ 'apcu_cas' => 'Safe\apcu_cas',
+ 'apcu_dec' => 'Safe\apcu_dec',
+ 'apcu_fetch' => 'Safe\apcu_fetch',
+ 'apcu_inc' => 'Safe\apcu_inc',
+ 'apcu_sma_info' => 'Safe\apcu_sma_info',
+ 'apc_fetch' => 'Safe\apc_fetch',
+ 'array_combine' => 'Safe\array_combine',
+ 'array_flip' => 'Safe\array_flip',
+ 'array_replace' => 'Safe\array_replace',
+ 'array_replace_recursive' => 'Safe\array_replace_recursive',
+ 'array_walk_recursive' => 'Safe\array_walk_recursive',
+ 'arsort' => 'Safe\arsort',
+ 'asort' => 'Safe\asort',
+ 'base64_decode' => 'Safe\base64_decode',
+ 'bzclose' => 'Safe\bzclose',
+ 'bzflush' => 'Safe\bzflush',
+ 'bzread' => 'Safe\bzread',
+ 'bzwrite' => 'Safe\bzwrite',
+ 'chdir' => 'Safe\chdir',
+ 'chgrp' => 'Safe\chgrp',
+ 'chmod' => 'Safe\chmod',
+ 'chown' => 'Safe\chown',
+ 'chroot' => 'Safe\chroot',
+ 'class_alias' => 'Safe\class_alias',
+ 'class_implements' => 'Safe\class_implements',
+ 'class_parents' => 'Safe\class_parents',
+ 'class_uses' => 'Safe\class_uses',
+ 'cli_set_process_title' => 'Safe\cli_set_process_title',
+ 'closelog' => 'Safe\closelog',
+ 'com_event_sink' => 'Safe\com_event_sink',
+ 'com_load_typelib' => 'Safe\com_load_typelib',
+ 'com_print_typeinfo' => 'Safe\com_print_typeinfo',
+ 'convert_uudecode' => 'Safe\convert_uudecode',
+ 'convert_uuencode' => 'Safe\convert_uuencode',
+ 'copy' => 'Safe\copy',
+ 'create_function' => 'Safe\create_function',
+ 'cubrid_free_result' => 'Safe\cubrid_free_result',
+ 'cubrid_get_charset' => 'Safe\cubrid_get_charset',
+ 'cubrid_get_client_info' => 'Safe\cubrid_get_client_info',
+ 'cubrid_get_db_parameter' => 'Safe\cubrid_get_db_parameter',
+ 'cubrid_get_server_info' => 'Safe\cubrid_get_server_info',
+ 'cubrid_insert_id' => 'Safe\cubrid_insert_id',
+ 'cubrid_lob2_new' => 'Safe\cubrid_lob2_new',
+ 'cubrid_lob2_size' => 'Safe\cubrid_lob2_size',
+ 'cubrid_lob2_size64' => 'Safe\cubrid_lob2_size64',
+ 'cubrid_lob2_tell' => 'Safe\cubrid_lob2_tell',
+ 'cubrid_lob2_tell64' => 'Safe\cubrid_lob2_tell64',
+ 'cubrid_set_db_parameter' => 'Safe\cubrid_set_db_parameter',
+ 'curl_escape' => 'Safe\curl_escape',
+ 'curl_exec' => 'Safe\curl_exec',
+ 'curl_getinfo' => 'Safe\curl_getinfo',
+ 'curl_init' => 'Safe\curl_init',
+ 'curl_multi_errno' => 'Safe\curl_multi_errno',
+ 'curl_multi_info_read' => 'Safe\curl_multi_info_read',
+ 'curl_multi_init' => 'Safe\curl_multi_init',
+ 'curl_setopt' => 'Safe\curl_setopt',
+ 'curl_share_errno' => 'Safe\curl_share_errno',
+ 'curl_share_setopt' => 'Safe\curl_share_setopt',
+ 'curl_unescape' => 'Safe\curl_unescape',
+ 'date' => 'Safe\date',
+ 'date_parse' => 'Safe\date_parse',
+ 'date_parse_from_format' => 'Safe\date_parse_from_format',
+ 'date_sunrise' => 'Safe\date_sunrise',
+ 'date_sunset' => 'Safe\date_sunset',
+ 'date_sun_info' => 'Safe\date_sun_info',
+ 'db2_autocommit' => 'Safe\db2_autocommit',
+ 'db2_bind_param' => 'Safe\db2_bind_param',
+ 'db2_client_info' => 'Safe\db2_client_info',
+ 'db2_close' => 'Safe\db2_close',
+ 'db2_commit' => 'Safe\db2_commit',
+ 'db2_execute' => 'Safe\db2_execute',
+ 'db2_free_result' => 'Safe\db2_free_result',
+ 'db2_free_stmt' => 'Safe\db2_free_stmt',
+ 'db2_get_option' => 'Safe\db2_get_option',
+ 'db2_pclose' => 'Safe\db2_pclose',
+ 'db2_rollback' => 'Safe\db2_rollback',
+ 'db2_server_info' => 'Safe\db2_server_info',
+ 'db2_set_option' => 'Safe\db2_set_option',
+ 'define' => 'Safe\define',
+ 'deflate_add' => 'Safe\deflate_add',
+ 'deflate_init' => 'Safe\deflate_init',
+ 'disk_free_space' => 'Safe\disk_free_space',
+ 'disk_total_space' => 'Safe\disk_total_space',
+ 'dl' => 'Safe\dl',
+ 'dns_get_record' => 'Safe\dns_get_record',
+ 'eio_busy' => 'Safe\eio_busy',
+ 'eio_chmod' => 'Safe\eio_chmod',
+ 'eio_chown' => 'Safe\eio_chown',
+ 'eio_close' => 'Safe\eio_close',
+ 'eio_custom' => 'Safe\eio_custom',
+ 'eio_dup2' => 'Safe\eio_dup2',
+ 'eio_event_loop' => 'Safe\eio_event_loop',
+ 'eio_fallocate' => 'Safe\eio_fallocate',
+ 'eio_fchmod' => 'Safe\eio_fchmod',
+ 'eio_fdatasync' => 'Safe\eio_fdatasync',
+ 'eio_fstat' => 'Safe\eio_fstat',
+ 'eio_fstatvfs' => 'Safe\eio_fstatvfs',
+ 'eio_fsync' => 'Safe\eio_fsync',
+ 'eio_ftruncate' => 'Safe\eio_ftruncate',
+ 'eio_futime' => 'Safe\eio_futime',
+ 'eio_grp' => 'Safe\eio_grp',
+ 'eio_lstat' => 'Safe\eio_lstat',
+ 'eio_mkdir' => 'Safe\eio_mkdir',
+ 'eio_mknod' => 'Safe\eio_mknod',
+ 'eio_nop' => 'Safe\eio_nop',
+ 'eio_readahead' => 'Safe\eio_readahead',
+ 'eio_readdir' => 'Safe\eio_readdir',
+ 'eio_readlink' => 'Safe\eio_readlink',
+ 'eio_rename' => 'Safe\eio_rename',
+ 'eio_rmdir' => 'Safe\eio_rmdir',
+ 'eio_seek' => 'Safe\eio_seek',
+ 'eio_sendfile' => 'Safe\eio_sendfile',
+ 'eio_stat' => 'Safe\eio_stat',
+ 'eio_statvfs' => 'Safe\eio_statvfs',
+ 'eio_symlink' => 'Safe\eio_symlink',
+ 'eio_sync' => 'Safe\eio_sync',
+ 'eio_syncfs' => 'Safe\eio_syncfs',
+ 'eio_sync_file_range' => 'Safe\eio_sync_file_range',
+ 'eio_truncate' => 'Safe\eio_truncate',
+ 'eio_unlink' => 'Safe\eio_unlink',
+ 'eio_utime' => 'Safe\eio_utime',
+ 'eio_write' => 'Safe\eio_write',
+ 'error_log' => 'Safe\error_log',
+ 'fastcgi_finish_request' => 'Safe\fastcgi_finish_request',
+ 'fbird_blob_cancel' => 'Safe\fbird_blob_cancel',
+ 'fclose' => 'Safe\fclose',
+ 'fflush' => 'Safe\fflush',
+ 'file' => 'Safe\file',
+ 'fileatime' => 'Safe\fileatime',
+ 'filectime' => 'Safe\filectime',
+ 'fileinode' => 'Safe\fileinode',
+ 'filemtime' => 'Safe\filemtime',
+ 'fileowner' => 'Safe\fileowner',
+ 'filesize' => 'Safe\filesize',
+ 'file_get_contents' => 'Safe\file_get_contents',
+ 'file_put_contents' => 'Safe\file_put_contents',
+ 'filter_input_array' => 'Safe\filter_input_array',
+ 'filter_var_array' => 'Safe\filter_var_array',
+ 'finfo_close' => 'Safe\finfo_close',
+ 'finfo_open' => 'Safe\finfo_open',
+ 'flock' => 'Safe\flock',
+ 'fopen' => 'Safe\fopen',
+ 'fputcsv' => 'Safe\fputcsv',
+ 'fread' => 'Safe\fread',
+ 'fsockopen' => 'Safe\fsockopen',
+ 'ftp_alloc' => 'Safe\ftp_alloc',
+ 'ftp_append' => 'Safe\ftp_append',
+ 'ftp_cdup' => 'Safe\ftp_cdup',
+ 'ftp_chdir' => 'Safe\ftp_chdir',
+ 'ftp_chmod' => 'Safe\ftp_chmod',
+ 'ftp_close' => 'Safe\ftp_close',
+ 'ftp_connect' => 'Safe\ftp_connect',
+ 'ftp_delete' => 'Safe\ftp_delete',
+ 'ftp_fget' => 'Safe\ftp_fget',
+ 'ftp_fput' => 'Safe\ftp_fput',
+ 'ftp_get' => 'Safe\ftp_get',
+ 'ftp_login' => 'Safe\ftp_login',
+ 'ftp_mkdir' => 'Safe\ftp_mkdir',
+ 'ftp_mlsd' => 'Safe\ftp_mlsd',
+ 'ftp_nlist' => 'Safe\ftp_nlist',
+ 'ftp_pasv' => 'Safe\ftp_pasv',
+ 'ftp_put' => 'Safe\ftp_put',
+ 'ftp_pwd' => 'Safe\ftp_pwd',
+ 'ftp_rename' => 'Safe\ftp_rename',
+ 'ftp_rmdir' => 'Safe\ftp_rmdir',
+ 'ftp_site' => 'Safe\ftp_site',
+ 'ftp_ssl_connect' => 'Safe\ftp_ssl_connect',
+ 'ftp_systype' => 'Safe\ftp_systype',
+ 'ftruncate' => 'Safe\ftruncate',
+ 'fwrite' => 'Safe\fwrite',
+ 'getallheaders' => 'Safe\getallheaders',
+ 'getcwd' => 'Safe\getcwd',
+ 'gethostname' => 'Safe\gethostname',
+ 'getimagesize' => 'Safe\getimagesize',
+ 'getlastmod' => 'Safe\getlastmod',
+ 'getmygid' => 'Safe\getmygid',
+ 'getmyinode' => 'Safe\getmyinode',
+ 'getmypid' => 'Safe\getmypid',
+ 'getmyuid' => 'Safe\getmyuid',
+ 'getopt' => 'Safe\getopt',
+ 'getprotobyname' => 'Safe\getprotobyname',
+ 'getprotobynumber' => 'Safe\getprotobynumber',
+ 'get_headers' => 'Safe\get_headers',
+ 'glob' => 'Safe\glob',
+ 'gmdate' => 'Safe\gmdate',
+ 'gmp_binomial' => 'Safe\gmp_binomial',
+ 'gmp_export' => 'Safe\gmp_export',
+ 'gmp_import' => 'Safe\gmp_import',
+ 'gmp_random_seed' => 'Safe\gmp_random_seed',
+ 'gnupg_adddecryptkey' => 'Safe\gnupg_adddecryptkey',
+ 'gnupg_addencryptkey' => 'Safe\gnupg_addencryptkey',
+ 'gnupg_addsignkey' => 'Safe\gnupg_addsignkey',
+ 'gnupg_cleardecryptkeys' => 'Safe\gnupg_cleardecryptkeys',
+ 'gnupg_clearencryptkeys' => 'Safe\gnupg_clearencryptkeys',
+ 'gnupg_clearsignkeys' => 'Safe\gnupg_clearsignkeys',
+ 'gnupg_setarmor' => 'Safe\gnupg_setarmor',
+ 'gnupg_setsignmode' => 'Safe\gnupg_setsignmode',
+ 'gzclose' => 'Safe\gzclose',
+ 'gzcompress' => 'Safe\gzcompress',
+ 'gzdecode' => 'Safe\gzdecode',
+ 'gzdeflate' => 'Safe\gzdeflate',
+ 'gzencode' => 'Safe\gzencode',
+ 'gzgets' => 'Safe\gzgets',
+ 'gzgetss' => 'Safe\gzgetss',
+ 'gzinflate' => 'Safe\gzinflate',
+ 'gzpassthru' => 'Safe\gzpassthru',
+ 'gzrewind' => 'Safe\gzrewind',
+ 'gzuncompress' => 'Safe\gzuncompress',
+ 'hash_hkdf' => 'Safe\hash_hkdf',
+ 'hash_update_file' => 'Safe\hash_update_file',
+ 'header_register_callback' => 'Safe\header_register_callback',
+ 'hex2bin' => 'Safe\hex2bin',
+ 'highlight_file' => 'Safe\highlight_file',
+ 'highlight_string' => 'Safe\highlight_string',
+ 'ibase_add_user' => 'Safe\ibase_add_user',
+ 'ibase_backup' => 'Safe\ibase_backup',
+ 'ibase_blob_cancel' => 'Safe\ibase_blob_cancel',
+ 'ibase_blob_create' => 'Safe\ibase_blob_create',
+ 'ibase_blob_get' => 'Safe\ibase_blob_get',
+ 'ibase_close' => 'Safe\ibase_close',
+ 'ibase_commit' => 'Safe\ibase_commit',
+ 'ibase_commit_ret' => 'Safe\ibase_commit_ret',
+ 'ibase_connect' => 'Safe\ibase_connect',
+ 'ibase_delete_user' => 'Safe\ibase_delete_user',
+ 'ibase_drop_db' => 'Safe\ibase_drop_db',
+ 'ibase_free_event_handler' => 'Safe\ibase_free_event_handler',
+ 'ibase_free_query' => 'Safe\ibase_free_query',
+ 'ibase_free_result' => 'Safe\ibase_free_result',
+ 'ibase_maintain_db' => 'Safe\ibase_maintain_db',
+ 'ibase_modify_user' => 'Safe\ibase_modify_user',
+ 'ibase_name_result' => 'Safe\ibase_name_result',
+ 'ibase_pconnect' => 'Safe\ibase_pconnect',
+ 'ibase_restore' => 'Safe\ibase_restore',
+ 'ibase_rollback' => 'Safe\ibase_rollback',
+ 'ibase_rollback_ret' => 'Safe\ibase_rollback_ret',
+ 'ibase_service_attach' => 'Safe\ibase_service_attach',
+ 'ibase_service_detach' => 'Safe\ibase_service_detach',
+ 'iconv' => 'Safe\iconv',
+ 'iconv_get_encoding' => 'Safe\iconv_get_encoding',
+ 'iconv_set_encoding' => 'Safe\iconv_set_encoding',
+ 'image2wbmp' => 'Safe\image2wbmp',
+ 'imageaffine' => 'Safe\imageaffine',
+ 'imageaffinematrixconcat' => 'Safe\imageaffinematrixconcat',
+ 'imageaffinematrixget' => 'Safe\imageaffinematrixget',
+ 'imagealphablending' => 'Safe\imagealphablending',
+ 'imageantialias' => 'Safe\imageantialias',
+ 'imagearc' => 'Safe\imagearc',
+ 'imagebmp' => 'Safe\imagebmp',
+ 'imagechar' => 'Safe\imagechar',
+ 'imagecharup' => 'Safe\imagecharup',
+ 'imagecolorat' => 'Safe\imagecolorat',
+ 'imagecolordeallocate' => 'Safe\imagecolordeallocate',
+ 'imagecolormatch' => 'Safe\imagecolormatch',
+ 'imageconvolution' => 'Safe\imageconvolution',
+ 'imagecopy' => 'Safe\imagecopy',
+ 'imagecopymerge' => 'Safe\imagecopymerge',
+ 'imagecopymergegray' => 'Safe\imagecopymergegray',
+ 'imagecopyresampled' => 'Safe\imagecopyresampled',
+ 'imagecopyresized' => 'Safe\imagecopyresized',
+ 'imagecreate' => 'Safe\imagecreate',
+ 'imagecreatefrombmp' => 'Safe\imagecreatefrombmp',
+ 'imagecreatefromgd' => 'Safe\imagecreatefromgd',
+ 'imagecreatefromgd2' => 'Safe\imagecreatefromgd2',
+ 'imagecreatefromgd2part' => 'Safe\imagecreatefromgd2part',
+ 'imagecreatefromgif' => 'Safe\imagecreatefromgif',
+ 'imagecreatefromjpeg' => 'Safe\imagecreatefromjpeg',
+ 'imagecreatefrompng' => 'Safe\imagecreatefrompng',
+ 'imagecreatefromwbmp' => 'Safe\imagecreatefromwbmp',
+ 'imagecreatefromwebp' => 'Safe\imagecreatefromwebp',
+ 'imagecreatefromxbm' => 'Safe\imagecreatefromxbm',
+ 'imagecreatefromxpm' => 'Safe\imagecreatefromxpm',
+ 'imagecreatetruecolor' => 'Safe\imagecreatetruecolor',
+ 'imagecrop' => 'Safe\imagecrop',
+ 'imagecropauto' => 'Safe\imagecropauto',
+ 'imagedashedline' => 'Safe\imagedashedline',
+ 'imagedestroy' => 'Safe\imagedestroy',
+ 'imageellipse' => 'Safe\imageellipse',
+ 'imagefill' => 'Safe\imagefill',
+ 'imagefilledarc' => 'Safe\imagefilledarc',
+ 'imagefilledellipse' => 'Safe\imagefilledellipse',
+ 'imagefilledpolygon' => 'Safe\imagefilledpolygon',
+ 'imagefilledrectangle' => 'Safe\imagefilledrectangle',
+ 'imagefilltoborder' => 'Safe\imagefilltoborder',
+ 'imagefilter' => 'Safe\imagefilter',
+ 'imageflip' => 'Safe\imageflip',
+ 'imagegammacorrect' => 'Safe\imagegammacorrect',
+ 'imagegd' => 'Safe\imagegd',
+ 'imagegd2' => 'Safe\imagegd2',
+ 'imagegif' => 'Safe\imagegif',
+ 'imagegrabscreen' => 'Safe\imagegrabscreen',
+ 'imagegrabwindow' => 'Safe\imagegrabwindow',
+ 'imagejpeg' => 'Safe\imagejpeg',
+ 'imagelayereffect' => 'Safe\imagelayereffect',
+ 'imageline' => 'Safe\imageline',
+ 'imageloadfont' => 'Safe\imageloadfont',
+ 'imageopenpolygon' => 'Safe\imageopenpolygon',
+ 'imagepng' => 'Safe\imagepng',
+ 'imagepolygon' => 'Safe\imagepolygon',
+ 'imagerectangle' => 'Safe\imagerectangle',
+ 'imagerotate' => 'Safe\imagerotate',
+ 'imagesavealpha' => 'Safe\imagesavealpha',
+ 'imagescale' => 'Safe\imagescale',
+ 'imagesetbrush' => 'Safe\imagesetbrush',
+ 'imagesetclip' => 'Safe\imagesetclip',
+ 'imagesetinterpolation' => 'Safe\imagesetinterpolation',
+ 'imagesetpixel' => 'Safe\imagesetpixel',
+ 'imagesetstyle' => 'Safe\imagesetstyle',
+ 'imagesetthickness' => 'Safe\imagesetthickness',
+ 'imagesettile' => 'Safe\imagesettile',
+ 'imagestring' => 'Safe\imagestring',
+ 'imagestringup' => 'Safe\imagestringup',
+ 'imagesx' => 'Safe\imagesx',
+ 'imagesy' => 'Safe\imagesy',
+ 'imagetruecolortopalette' => 'Safe\imagetruecolortopalette',
+ 'imagettfbbox' => 'Safe\imagettfbbox',
+ 'imagettftext' => 'Safe\imagettftext',
+ 'imagewbmp' => 'Safe\imagewbmp',
+ 'imagewebp' => 'Safe\imagewebp',
+ 'imagexbm' => 'Safe\imagexbm',
+ 'imap_append' => 'Safe\imap_append',
+ 'imap_check' => 'Safe\imap_check',
+ 'imap_clearflag_full' => 'Safe\imap_clearflag_full',
+ 'imap_close' => 'Safe\imap_close',
+ 'imap_createmailbox' => 'Safe\imap_createmailbox',
+ 'imap_deletemailbox' => 'Safe\imap_deletemailbox',
+ 'imap_fetchstructure' => 'Safe\imap_fetchstructure',
+ 'imap_gc' => 'Safe\imap_gc',
+ 'imap_headerinfo' => 'Safe\imap_headerinfo',
+ 'imap_mail' => 'Safe\imap_mail',
+ 'imap_mailboxmsginfo' => 'Safe\imap_mailboxmsginfo',
+ 'imap_mail_compose' => 'Safe\imap_mail_compose',
+ 'imap_mail_copy' => 'Safe\imap_mail_copy',
+ 'imap_mail_move' => 'Safe\imap_mail_move',
+ 'imap_mutf7_to_utf8' => 'Safe\imap_mutf7_to_utf8',
+ 'imap_num_msg' => 'Safe\imap_num_msg',
+ 'imap_open' => 'Safe\imap_open',
+ 'imap_renamemailbox' => 'Safe\imap_renamemailbox',
+ 'imap_savebody' => 'Safe\imap_savebody',
+ 'imap_setacl' => 'Safe\imap_setacl',
+ 'imap_setflag_full' => 'Safe\imap_setflag_full',
+ 'imap_set_quota' => 'Safe\imap_set_quota',
+ 'imap_sort' => 'Safe\imap_sort',
+ 'imap_subscribe' => 'Safe\imap_subscribe',
+ 'imap_thread' => 'Safe\imap_thread',
+ 'imap_timeout' => 'Safe\imap_timeout',
+ 'imap_undelete' => 'Safe\imap_undelete',
+ 'imap_unsubscribe' => 'Safe\imap_unsubscribe',
+ 'imap_utf8_to_mutf7' => 'Safe\imap_utf8_to_mutf7',
+ 'inet_ntop' => 'Safe\inet_ntop',
+ 'inflate_add' => 'Safe\inflate_add',
+ 'inflate_get_read_len' => 'Safe\inflate_get_read_len',
+ 'inflate_get_status' => 'Safe\inflate_get_status',
+ 'inflate_init' => 'Safe\inflate_init',
+ 'ingres_autocommit' => 'Safe\ingres_autocommit',
+ 'ingres_close' => 'Safe\ingres_close',
+ 'ingres_commit' => 'Safe\ingres_commit',
+ 'ingres_connect' => 'Safe\ingres_connect',
+ 'ingres_execute' => 'Safe\ingres_execute',
+ 'ingres_field_name' => 'Safe\ingres_field_name',
+ 'ingres_field_type' => 'Safe\ingres_field_type',
+ 'ingres_free_result' => 'Safe\ingres_free_result',
+ 'ingres_pconnect' => 'Safe\ingres_pconnect',
+ 'ingres_result_seek' => 'Safe\ingres_result_seek',
+ 'ingres_rollback' => 'Safe\ingres_rollback',
+ 'ingres_set_environment' => 'Safe\ingres_set_environment',
+ 'ini_get' => 'Safe\ini_get',
+ 'ini_set' => 'Safe\ini_set',
+ 'inotify_init' => 'Safe\inotify_init',
+ 'inotify_rm_watch' => 'Safe\inotify_rm_watch',
+ 'iptcembed' => 'Safe\iptcembed',
+ 'iptcparse' => 'Safe\iptcparse',
+ 'jdtounix' => 'Safe\jdtounix',
+ 'jpeg2wbmp' => 'Safe\jpeg2wbmp',
+ 'json_decode' => 'Safe\json_decode',
+ 'json_encode' => 'Safe\json_encode',
+ 'json_last_error_msg' => 'Safe\json_last_error_msg',
+ 'krsort' => 'Safe\krsort',
+ 'ksort' => 'Safe\ksort',
+ 'lchgrp' => 'Safe\lchgrp',
+ 'lchown' => 'Safe\lchown',
+ 'ldap_add' => 'Safe\ldap_add',
+ 'ldap_add_ext' => 'Safe\ldap_add_ext',
+ 'ldap_bind' => 'Safe\ldap_bind',
+ 'ldap_bind_ext' => 'Safe\ldap_bind_ext',
+ 'ldap_control_paged_result' => 'Safe\ldap_control_paged_result',
+ 'ldap_control_paged_result_response' => 'Safe\ldap_control_paged_result_response',
+ 'ldap_count_entries' => 'Safe\ldap_count_entries',
+ 'ldap_delete' => 'Safe\ldap_delete',
+ 'ldap_delete_ext' => 'Safe\ldap_delete_ext',
+ 'ldap_exop' => 'Safe\ldap_exop',
+ 'ldap_exop_passwd' => 'Safe\ldap_exop_passwd',
+ 'ldap_exop_whoami' => 'Safe\ldap_exop_whoami',
+ 'ldap_explode_dn' => 'Safe\ldap_explode_dn',
+ 'ldap_first_attribute' => 'Safe\ldap_first_attribute',
+ 'ldap_first_entry' => 'Safe\ldap_first_entry',
+ 'ldap_free_result' => 'Safe\ldap_free_result',
+ 'ldap_get_attributes' => 'Safe\ldap_get_attributes',
+ 'ldap_get_dn' => 'Safe\ldap_get_dn',
+ 'ldap_get_entries' => 'Safe\ldap_get_entries',
+ 'ldap_get_option' => 'Safe\ldap_get_option',
+ 'ldap_get_values' => 'Safe\ldap_get_values',
+ 'ldap_get_values_len' => 'Safe\ldap_get_values_len',
+ 'ldap_list' => 'Safe\ldap_list',
+ 'ldap_modify_batch' => 'Safe\ldap_modify_batch',
+ 'ldap_mod_add' => 'Safe\ldap_mod_add',
+ 'ldap_mod_add_ext' => 'Safe\ldap_mod_add_ext',
+ 'ldap_mod_del' => 'Safe\ldap_mod_del',
+ 'ldap_mod_del_ext' => 'Safe\ldap_mod_del_ext',
+ 'ldap_mod_replace' => 'Safe\ldap_mod_replace',
+ 'ldap_mod_replace_ext' => 'Safe\ldap_mod_replace_ext',
+ 'ldap_next_attribute' => 'Safe\ldap_next_attribute',
+ 'ldap_parse_exop' => 'Safe\ldap_parse_exop',
+ 'ldap_parse_result' => 'Safe\ldap_parse_result',
+ 'ldap_read' => 'Safe\ldap_read',
+ 'ldap_rename' => 'Safe\ldap_rename',
+ 'ldap_rename_ext' => 'Safe\ldap_rename_ext',
+ 'ldap_sasl_bind' => 'Safe\ldap_sasl_bind',
+ 'ldap_search' => 'Safe\ldap_search',
+ 'ldap_set_option' => 'Safe\ldap_set_option',
+ 'ldap_unbind' => 'Safe\ldap_unbind',
+ 'libxml_get_last_error' => 'Safe\libxml_get_last_error',
+ 'libxml_set_external_entity_loader' => 'Safe\libxml_set_external_entity_loader',
+ 'link' => 'Safe\link',
+ 'lzf_compress' => 'Safe\lzf_compress',
+ 'lzf_decompress' => 'Safe\lzf_decompress',
+ 'mailparse_msg_extract_part_file' => 'Safe\mailparse_msg_extract_part_file',
+ 'mailparse_msg_free' => 'Safe\mailparse_msg_free',
+ 'mailparse_msg_parse' => 'Safe\mailparse_msg_parse',
+ 'mailparse_msg_parse_file' => 'Safe\mailparse_msg_parse_file',
+ 'mailparse_stream_encode' => 'Safe\mailparse_stream_encode',
+ 'mb_chr' => 'Safe\mb_chr',
+ 'mb_detect_order' => 'Safe\mb_detect_order',
+ 'mb_encoding_aliases' => 'Safe\mb_encoding_aliases',
+ 'mb_eregi_replace' => 'Safe\mb_eregi_replace',
+ 'mb_ereg_replace' => 'Safe\mb_ereg_replace',
+ 'mb_ereg_replace_callback' => 'Safe\mb_ereg_replace_callback',
+ 'mb_ereg_search_getregs' => 'Safe\mb_ereg_search_getregs',
+ 'mb_ereg_search_init' => 'Safe\mb_ereg_search_init',
+ 'mb_ereg_search_regs' => 'Safe\mb_ereg_search_regs',
+ 'mb_ereg_search_setpos' => 'Safe\mb_ereg_search_setpos',
+ 'mb_http_output' => 'Safe\mb_http_output',
+ 'mb_internal_encoding' => 'Safe\mb_internal_encoding',
+ 'mb_ord' => 'Safe\mb_ord',
+ 'mb_parse_str' => 'Safe\mb_parse_str',
+ 'mb_regex_encoding' => 'Safe\mb_regex_encoding',
+ 'mb_send_mail' => 'Safe\mb_send_mail',
+ 'mb_split' => 'Safe\mb_split',
+ 'mb_str_split' => 'Safe\mb_str_split',
+ 'md5_file' => 'Safe\md5_file',
+ 'metaphone' => 'Safe\metaphone',
+ 'mime_content_type' => 'Safe\mime_content_type',
+ 'mkdir' => 'Safe\mkdir',
+ 'mktime' => 'Safe\mktime',
+ 'msg_queue_exists' => 'Safe\msg_queue_exists',
+ 'msg_receive' => 'Safe\msg_receive',
+ 'msg_remove_queue' => 'Safe\msg_remove_queue',
+ 'msg_send' => 'Safe\msg_send',
+ 'msg_set_queue' => 'Safe\msg_set_queue',
+ 'msql_affected_rows' => 'Safe\msql_affected_rows',
+ 'msql_close' => 'Safe\msql_close',
+ 'msql_connect' => 'Safe\msql_connect',
+ 'msql_create_db' => 'Safe\msql_create_db',
+ 'msql_data_seek' => 'Safe\msql_data_seek',
+ 'msql_db_query' => 'Safe\msql_db_query',
+ 'msql_drop_db' => 'Safe\msql_drop_db',
+ 'msql_field_len' => 'Safe\msql_field_len',
+ 'msql_field_name' => 'Safe\msql_field_name',
+ 'msql_field_seek' => 'Safe\msql_field_seek',
+ 'msql_field_table' => 'Safe\msql_field_table',
+ 'msql_field_type' => 'Safe\msql_field_type',
+ 'msql_free_result' => 'Safe\msql_free_result',
+ 'msql_pconnect' => 'Safe\msql_pconnect',
+ 'msql_query' => 'Safe\msql_query',
+ 'msql_select_db' => 'Safe\msql_select_db',
+ 'mysqli_get_cache_stats' => 'Safe\mysqli_get_cache_stats',
+ 'mysqli_get_client_stats' => 'Safe\mysqli_get_client_stats',
+ 'mysqlnd_ms_dump_servers' => 'Safe\mysqlnd_ms_dump_servers',
+ 'mysqlnd_ms_fabric_select_global' => 'Safe\mysqlnd_ms_fabric_select_global',
+ 'mysqlnd_ms_fabric_select_shard' => 'Safe\mysqlnd_ms_fabric_select_shard',
+ 'mysqlnd_ms_get_last_used_connection' => 'Safe\mysqlnd_ms_get_last_used_connection',
+ 'mysqlnd_qc_clear_cache' => 'Safe\mysqlnd_qc_clear_cache',
+ 'mysqlnd_qc_set_is_select' => 'Safe\mysqlnd_qc_set_is_select',
+ 'mysqlnd_qc_set_storage_handler' => 'Safe\mysqlnd_qc_set_storage_handler',
+ 'mysql_close' => 'Safe\mysql_close',
+ 'mysql_connect' => 'Safe\mysql_connect',
+ 'mysql_create_db' => 'Safe\mysql_create_db',
+ 'mysql_data_seek' => 'Safe\mysql_data_seek',
+ 'mysql_db_name' => 'Safe\mysql_db_name',
+ 'mysql_db_query' => 'Safe\mysql_db_query',
+ 'mysql_drop_db' => 'Safe\mysql_drop_db',
+ 'mysql_fetch_lengths' => 'Safe\mysql_fetch_lengths',
+ 'mysql_field_flags' => 'Safe\mysql_field_flags',
+ 'mysql_field_len' => 'Safe\mysql_field_len',
+ 'mysql_field_name' => 'Safe\mysql_field_name',
+ 'mysql_field_seek' => 'Safe\mysql_field_seek',
+ 'mysql_free_result' => 'Safe\mysql_free_result',
+ 'mysql_get_host_info' => 'Safe\mysql_get_host_info',
+ 'mysql_get_proto_info' => 'Safe\mysql_get_proto_info',
+ 'mysql_get_server_info' => 'Safe\mysql_get_server_info',
+ 'mysql_info' => 'Safe\mysql_info',
+ 'mysql_list_dbs' => 'Safe\mysql_list_dbs',
+ 'mysql_list_fields' => 'Safe\mysql_list_fields',
+ 'mysql_list_processes' => 'Safe\mysql_list_processes',
+ 'mysql_list_tables' => 'Safe\mysql_list_tables',
+ 'mysql_num_fields' => 'Safe\mysql_num_fields',
+ 'mysql_num_rows' => 'Safe\mysql_num_rows',
+ 'mysql_query' => 'Safe\mysql_query',
+ 'mysql_real_escape_string' => 'Safe\mysql_real_escape_string',
+ 'mysql_result' => 'Safe\mysql_result',
+ 'mysql_select_db' => 'Safe\mysql_select_db',
+ 'mysql_set_charset' => 'Safe\mysql_set_charset',
+ 'mysql_tablename' => 'Safe\mysql_tablename',
+ 'mysql_thread_id' => 'Safe\mysql_thread_id',
+ 'mysql_unbuffered_query' => 'Safe\mysql_unbuffered_query',
+ 'natcasesort' => 'Safe\natcasesort',
+ 'natsort' => 'Safe\natsort',
+ 'ob_end_clean' => 'Safe\ob_end_clean',
+ 'ob_end_flush' => 'Safe\ob_end_flush',
+ 'oci_bind_array_by_name' => 'Safe\oci_bind_array_by_name',
+ 'oci_bind_by_name' => 'Safe\oci_bind_by_name',
+ 'oci_cancel' => 'Safe\oci_cancel',
+ 'oci_close' => 'Safe\oci_close',
+ 'oci_commit' => 'Safe\oci_commit',
+ 'oci_connect' => 'Safe\oci_connect',
+ 'oci_define_by_name' => 'Safe\oci_define_by_name',
+ 'oci_execute' => 'Safe\oci_execute',
+ 'oci_fetch_all' => 'Safe\oci_fetch_all',
+ 'oci_field_name' => 'Safe\oci_field_name',
+ 'oci_field_precision' => 'Safe\oci_field_precision',
+ 'oci_field_scale' => 'Safe\oci_field_scale',
+ 'oci_field_size' => 'Safe\oci_field_size',
+ 'oci_field_type' => 'Safe\oci_field_type',
+ 'oci_field_type_raw' => 'Safe\oci_field_type_raw',
+ 'oci_free_descriptor' => 'Safe\oci_free_descriptor',
+ 'oci_free_statement' => 'Safe\oci_free_statement',
+ 'oci_new_collection' => 'Safe\oci_new_collection',
+ 'oci_new_connect' => 'Safe\oci_new_connect',
+ 'oci_new_cursor' => 'Safe\oci_new_cursor',
+ 'oci_new_descriptor' => 'Safe\oci_new_descriptor',
+ 'oci_num_fields' => 'Safe\oci_num_fields',
+ 'oci_num_rows' => 'Safe\oci_num_rows',
+ 'oci_parse' => 'Safe\oci_parse',
+ 'oci_pconnect' => 'Safe\oci_pconnect',
+ 'oci_result' => 'Safe\oci_result',
+ 'oci_rollback' => 'Safe\oci_rollback',
+ 'oci_server_version' => 'Safe\oci_server_version',
+ 'oci_set_action' => 'Safe\oci_set_action',
+ 'oci_set_call_timeout' => 'Safe\oci_set_call_timeout',
+ 'oci_set_client_identifier' => 'Safe\oci_set_client_identifier',
+ 'oci_set_client_info' => 'Safe\oci_set_client_info',
+ 'oci_set_db_operation' => 'Safe\oci_set_db_operation',
+ 'oci_set_edition' => 'Safe\oci_set_edition',
+ 'oci_set_module_name' => 'Safe\oci_set_module_name',
+ 'oci_set_prefetch' => 'Safe\oci_set_prefetch',
+ 'oci_statement_type' => 'Safe\oci_statement_type',
+ 'oci_unregister_taf_callback' => 'Safe\oci_unregister_taf_callback',
+ 'odbc_autocommit' => 'Safe\odbc_autocommit',
+ 'odbc_binmode' => 'Safe\odbc_binmode',
+ 'odbc_columnprivileges' => 'Safe\odbc_columnprivileges',
+ 'odbc_columns' => 'Safe\odbc_columns',
+ 'odbc_commit' => 'Safe\odbc_commit',
+ 'odbc_data_source' => 'Safe\odbc_data_source',
+ 'odbc_exec' => 'Safe\odbc_exec',
+ 'odbc_execute' => 'Safe\odbc_execute',
+ 'odbc_fetch_into' => 'Safe\odbc_fetch_into',
+ 'odbc_field_len' => 'Safe\odbc_field_len',
+ 'odbc_field_name' => 'Safe\odbc_field_name',
+ 'odbc_field_num' => 'Safe\odbc_field_num',
+ 'odbc_field_scale' => 'Safe\odbc_field_scale',
+ 'odbc_field_type' => 'Safe\odbc_field_type',
+ 'odbc_foreignkeys' => 'Safe\odbc_foreignkeys',
+ 'odbc_gettypeinfo' => 'Safe\odbc_gettypeinfo',
+ 'odbc_longreadlen' => 'Safe\odbc_longreadlen',
+ 'odbc_prepare' => 'Safe\odbc_prepare',
+ 'odbc_primarykeys' => 'Safe\odbc_primarykeys',
+ 'odbc_result' => 'Safe\odbc_result',
+ 'odbc_result_all' => 'Safe\odbc_result_all',
+ 'odbc_rollback' => 'Safe\odbc_rollback',
+ 'odbc_setoption' => 'Safe\odbc_setoption',
+ 'odbc_specialcolumns' => 'Safe\odbc_specialcolumns',
+ 'odbc_statistics' => 'Safe\odbc_statistics',
+ 'odbc_tableprivileges' => 'Safe\odbc_tableprivileges',
+ 'odbc_tables' => 'Safe\odbc_tables',
+ 'opcache_compile_file' => 'Safe\opcache_compile_file',
+ 'opcache_get_status' => 'Safe\opcache_get_status',
+ 'opendir' => 'Safe\opendir',
+ 'openlog' => 'Safe\openlog',
+ 'openssl_cipher_iv_length' => 'Safe\openssl_cipher_iv_length',
+ 'openssl_csr_export' => 'Safe\openssl_csr_export',
+ 'openssl_csr_export_to_file' => 'Safe\openssl_csr_export_to_file',
+ 'openssl_csr_get_subject' => 'Safe\openssl_csr_get_subject',
+ 'openssl_csr_new' => 'Safe\openssl_csr_new',
+ 'openssl_csr_sign' => 'Safe\openssl_csr_sign',
+ 'openssl_decrypt' => 'Safe\openssl_decrypt',
+ 'openssl_dh_compute_key' => 'Safe\openssl_dh_compute_key',
+ 'openssl_digest' => 'Safe\openssl_digest',
+ 'openssl_encrypt' => 'Safe\openssl_encrypt',
+ 'openssl_open' => 'Safe\openssl_open',
+ 'openssl_pbkdf2' => 'Safe\openssl_pbkdf2',
+ 'openssl_pkcs7_decrypt' => 'Safe\openssl_pkcs7_decrypt',
+ 'openssl_pkcs7_encrypt' => 'Safe\openssl_pkcs7_encrypt',
+ 'openssl_pkcs7_read' => 'Safe\openssl_pkcs7_read',
+ 'openssl_pkcs7_sign' => 'Safe\openssl_pkcs7_sign',
+ 'openssl_pkcs12_export' => 'Safe\openssl_pkcs12_export',
+ 'openssl_pkcs12_export_to_file' => 'Safe\openssl_pkcs12_export_to_file',
+ 'openssl_pkcs12_read' => 'Safe\openssl_pkcs12_read',
+ 'openssl_pkey_export' => 'Safe\openssl_pkey_export',
+ 'openssl_pkey_export_to_file' => 'Safe\openssl_pkey_export_to_file',
+ 'openssl_pkey_get_private' => 'Safe\openssl_pkey_get_private',
+ 'openssl_pkey_get_public' => 'Safe\openssl_pkey_get_public',
+ 'openssl_pkey_new' => 'Safe\openssl_pkey_new',
+ 'openssl_private_decrypt' => 'Safe\openssl_private_decrypt',
+ 'openssl_private_encrypt' => 'Safe\openssl_private_encrypt',
+ 'openssl_public_decrypt' => 'Safe\openssl_public_decrypt',
+ 'openssl_public_encrypt' => 'Safe\openssl_public_encrypt',
+ 'openssl_random_pseudo_bytes' => 'Safe\openssl_random_pseudo_bytes',
+ 'openssl_seal' => 'Safe\openssl_seal',
+ 'openssl_sign' => 'Safe\openssl_sign',
+ 'openssl_x509_export' => 'Safe\openssl_x509_export',
+ 'openssl_x509_export_to_file' => 'Safe\openssl_x509_export_to_file',
+ 'openssl_x509_fingerprint' => 'Safe\openssl_x509_fingerprint',
+ 'openssl_x509_read' => 'Safe\openssl_x509_read',
+ 'output_add_rewrite_var' => 'Safe\output_add_rewrite_var',
+ 'output_reset_rewrite_vars' => 'Safe\output_reset_rewrite_vars',
+ 'pack' => 'Safe\pack',
+ 'parse_ini_file' => 'Safe\parse_ini_file',
+ 'parse_ini_string' => 'Safe\parse_ini_string',
+ 'parse_url' => 'Safe\parse_url',
+ 'password_hash' => 'Safe\password_hash',
+ 'pcntl_exec' => 'Safe\pcntl_exec',
+ 'pcntl_getpriority' => 'Safe\pcntl_getpriority',
+ 'pcntl_setpriority' => 'Safe\pcntl_setpriority',
+ 'pcntl_signal_dispatch' => 'Safe\pcntl_signal_dispatch',
+ 'pcntl_sigprocmask' => 'Safe\pcntl_sigprocmask',
+ 'pcntl_strerror' => 'Safe\pcntl_strerror',
+ 'PDF_activate_item' => 'Safe\PDF_activate_item',
+ 'PDF_add_locallink' => 'Safe\PDF_add_locallink',
+ 'PDF_add_nameddest' => 'Safe\PDF_add_nameddest',
+ 'PDF_add_note' => 'Safe\PDF_add_note',
+ 'PDF_add_pdflink' => 'Safe\PDF_add_pdflink',
+ 'PDF_add_thumbnail' => 'Safe\PDF_add_thumbnail',
+ 'PDF_add_weblink' => 'Safe\PDF_add_weblink',
+ 'PDF_attach_file' => 'Safe\PDF_attach_file',
+ 'PDF_begin_layer' => 'Safe\PDF_begin_layer',
+ 'PDF_begin_page' => 'Safe\PDF_begin_page',
+ 'PDF_begin_page_ext' => 'Safe\PDF_begin_page_ext',
+ 'PDF_circle' => 'Safe\PDF_circle',
+ 'PDF_clip' => 'Safe\PDF_clip',
+ 'PDF_close' => 'Safe\PDF_close',
+ 'PDF_closepath' => 'Safe\PDF_closepath',
+ 'PDF_closepath_fill_stroke' => 'Safe\PDF_closepath_fill_stroke',
+ 'PDF_closepath_stroke' => 'Safe\PDF_closepath_stroke',
+ 'PDF_close_pdi' => 'Safe\PDF_close_pdi',
+ 'PDF_close_pdi_page' => 'Safe\PDF_close_pdi_page',
+ 'PDF_concat' => 'Safe\PDF_concat',
+ 'PDF_continue_text' => 'Safe\PDF_continue_text',
+ 'PDF_curveto' => 'Safe\PDF_curveto',
+ 'PDF_delete' => 'Safe\PDF_delete',
+ 'PDF_end_layer' => 'Safe\PDF_end_layer',
+ 'PDF_end_page' => 'Safe\PDF_end_page',
+ 'PDF_end_page_ext' => 'Safe\PDF_end_page_ext',
+ 'PDF_end_pattern' => 'Safe\PDF_end_pattern',
+ 'PDF_end_template' => 'Safe\PDF_end_template',
+ 'PDF_fill' => 'Safe\PDF_fill',
+ 'PDF_fill_stroke' => 'Safe\PDF_fill_stroke',
+ 'PDF_fit_image' => 'Safe\PDF_fit_image',
+ 'PDF_fit_pdi_page' => 'Safe\PDF_fit_pdi_page',
+ 'PDF_fit_textline' => 'Safe\PDF_fit_textline',
+ 'PDF_initgraphics' => 'Safe\PDF_initgraphics',
+ 'PDF_lineto' => 'Safe\PDF_lineto',
+ 'PDF_makespotcolor' => 'Safe\PDF_makespotcolor',
+ 'PDF_moveto' => 'Safe\PDF_moveto',
+ 'PDF_open_file' => 'Safe\PDF_open_file',
+ 'PDF_place_image' => 'Safe\PDF_place_image',
+ 'PDF_place_pdi_page' => 'Safe\PDF_place_pdi_page',
+ 'PDF_rect' => 'Safe\PDF_rect',
+ 'PDF_restore' => 'Safe\PDF_restore',
+ 'PDF_rotate' => 'Safe\PDF_rotate',
+ 'PDF_save' => 'Safe\PDF_save',
+ 'PDF_scale' => 'Safe\PDF_scale',
+ 'PDF_setcolor' => 'Safe\PDF_setcolor',
+ 'PDF_setdash' => 'Safe\PDF_setdash',
+ 'PDF_setdashpattern' => 'Safe\PDF_setdashpattern',
+ 'PDF_setflat' => 'Safe\PDF_setflat',
+ 'PDF_setfont' => 'Safe\PDF_setfont',
+ 'PDF_setgray' => 'Safe\PDF_setgray',
+ 'PDF_setgray_fill' => 'Safe\PDF_setgray_fill',
+ 'PDF_setgray_stroke' => 'Safe\PDF_setgray_stroke',
+ 'PDF_setlinejoin' => 'Safe\PDF_setlinejoin',
+ 'PDF_setlinewidth' => 'Safe\PDF_setlinewidth',
+ 'PDF_setmatrix' => 'Safe\PDF_setmatrix',
+ 'PDF_setmiterlimit' => 'Safe\PDF_setmiterlimit',
+ 'PDF_setrgbcolor' => 'Safe\PDF_setrgbcolor',
+ 'PDF_setrgbcolor_fill' => 'Safe\PDF_setrgbcolor_fill',
+ 'PDF_setrgbcolor_stroke' => 'Safe\PDF_setrgbcolor_stroke',
+ 'PDF_set_border_color' => 'Safe\PDF_set_border_color',
+ 'PDF_set_border_dash' => 'Safe\PDF_set_border_dash',
+ 'PDF_set_border_style' => 'Safe\PDF_set_border_style',
+ 'PDF_set_info' => 'Safe\PDF_set_info',
+ 'PDF_set_layer_dependency' => 'Safe\PDF_set_layer_dependency',
+ 'PDF_set_parameter' => 'Safe\PDF_set_parameter',
+ 'PDF_set_text_pos' => 'Safe\PDF_set_text_pos',
+ 'PDF_set_value' => 'Safe\PDF_set_value',
+ 'PDF_show' => 'Safe\PDF_show',
+ 'PDF_show_xy' => 'Safe\PDF_show_xy',
+ 'PDF_skew' => 'Safe\PDF_skew',
+ 'PDF_stroke' => 'Safe\PDF_stroke',
+ 'pg_cancel_query' => 'Safe\pg_cancel_query',
+ 'pg_client_encoding' => 'Safe\pg_client_encoding',
+ 'pg_close' => 'Safe\pg_close',
+ 'pg_connect' => 'Safe\pg_connect',
+ 'pg_connection_reset' => 'Safe\pg_connection_reset',
+ 'pg_convert' => 'Safe\pg_convert',
+ 'pg_copy_from' => 'Safe\pg_copy_from',
+ 'pg_copy_to' => 'Safe\pg_copy_to',
+ 'pg_dbname' => 'Safe\pg_dbname',
+ 'pg_delete' => 'Safe\pg_delete',
+ 'pg_end_copy' => 'Safe\pg_end_copy',
+ 'pg_execute' => 'Safe\pg_execute',
+ 'pg_field_name' => 'Safe\pg_field_name',
+ 'pg_field_table' => 'Safe\pg_field_table',
+ 'pg_field_type' => 'Safe\pg_field_type',
+ 'pg_flush' => 'Safe\pg_flush',
+ 'pg_free_result' => 'Safe\pg_free_result',
+ 'pg_host' => 'Safe\pg_host',
+ 'pg_insert' => 'Safe\pg_insert',
+ 'pg_last_error' => 'Safe\pg_last_error',
+ 'pg_last_notice' => 'Safe\pg_last_notice',
+ 'pg_last_oid' => 'Safe\pg_last_oid',
+ 'pg_lo_close' => 'Safe\pg_lo_close',
+ 'pg_lo_export' => 'Safe\pg_lo_export',
+ 'pg_lo_import' => 'Safe\pg_lo_import',
+ 'pg_lo_open' => 'Safe\pg_lo_open',
+ 'pg_lo_read' => 'Safe\pg_lo_read',
+ 'pg_lo_read_all' => 'Safe\pg_lo_read_all',
+ 'pg_lo_seek' => 'Safe\pg_lo_seek',
+ 'pg_lo_truncate' => 'Safe\pg_lo_truncate',
+ 'pg_lo_unlink' => 'Safe\pg_lo_unlink',
+ 'pg_lo_write' => 'Safe\pg_lo_write',
+ 'pg_meta_data' => 'Safe\pg_meta_data',
+ 'pg_options' => 'Safe\pg_options',
+ 'pg_parameter_status' => 'Safe\pg_parameter_status',
+ 'pg_pconnect' => 'Safe\pg_pconnect',
+ 'pg_ping' => 'Safe\pg_ping',
+ 'pg_port' => 'Safe\pg_port',
+ 'pg_prepare' => 'Safe\pg_prepare',
+ 'pg_put_line' => 'Safe\pg_put_line',
+ 'pg_query' => 'Safe\pg_query',
+ 'pg_query_params' => 'Safe\pg_query_params',
+ 'pg_result_error_field' => 'Safe\pg_result_error_field',
+ 'pg_result_seek' => 'Safe\pg_result_seek',
+ 'pg_select' => 'Safe\pg_select',
+ 'pg_send_execute' => 'Safe\pg_send_execute',
+ 'pg_send_prepare' => 'Safe\pg_send_prepare',
+ 'pg_send_query' => 'Safe\pg_send_query',
+ 'pg_send_query_params' => 'Safe\pg_send_query_params',
+ 'pg_socket' => 'Safe\pg_socket',
+ 'pg_trace' => 'Safe\pg_trace',
+ 'pg_tty' => 'Safe\pg_tty',
+ 'pg_update' => 'Safe\pg_update',
+ 'pg_version' => 'Safe\pg_version',
+ 'phpcredits' => 'Safe\phpcredits',
+ 'phpinfo' => 'Safe\phpinfo',
+ 'png2wbmp' => 'Safe\png2wbmp',
+ 'posix_access' => 'Safe\posix_access',
+ 'posix_getgrnam' => 'Safe\posix_getgrnam',
+ 'posix_getpgid' => 'Safe\posix_getpgid',
+ 'posix_initgroups' => 'Safe\posix_initgroups',
+ 'posix_kill' => 'Safe\posix_kill',
+ 'posix_mkfifo' => 'Safe\posix_mkfifo',
+ 'posix_mknod' => 'Safe\posix_mknod',
+ 'posix_setegid' => 'Safe\posix_setegid',
+ 'posix_seteuid' => 'Safe\posix_seteuid',
+ 'posix_setgid' => 'Safe\posix_setgid',
+ 'posix_setpgid' => 'Safe\posix_setpgid',
+ 'posix_setrlimit' => 'Safe\posix_setrlimit',
+ 'posix_setuid' => 'Safe\posix_setuid',
+ 'preg_match' => 'Safe\preg_match',
+ 'preg_match_all' => 'Safe\preg_match_all',
+ 'preg_replace' => 'Safe\preg_replace',
+ 'preg_split' => 'Safe\preg_split',
+ 'proc_get_status' => 'Safe\proc_get_status',
+ 'proc_nice' => 'Safe\proc_nice',
+ 'pspell_add_to_personal' => 'Safe\pspell_add_to_personal',
+ 'pspell_add_to_session' => 'Safe\pspell_add_to_session',
+ 'pspell_clear_session' => 'Safe\pspell_clear_session',
+ 'pspell_config_create' => 'Safe\pspell_config_create',
+ 'pspell_config_data_dir' => 'Safe\pspell_config_data_dir',
+ 'pspell_config_dict_dir' => 'Safe\pspell_config_dict_dir',
+ 'pspell_config_ignore' => 'Safe\pspell_config_ignore',
+ 'pspell_config_mode' => 'Safe\pspell_config_mode',
+ 'pspell_config_personal' => 'Safe\pspell_config_personal',
+ 'pspell_config_repl' => 'Safe\pspell_config_repl',
+ 'pspell_config_runtogether' => 'Safe\pspell_config_runtogether',
+ 'pspell_config_save_repl' => 'Safe\pspell_config_save_repl',
+ 'pspell_new' => 'Safe\pspell_new',
+ 'pspell_new_config' => 'Safe\pspell_new_config',
+ 'pspell_save_wordlist' => 'Safe\pspell_save_wordlist',
+ 'pspell_store_replacement' => 'Safe\pspell_store_replacement',
+ 'ps_add_launchlink' => 'Safe\ps_add_launchlink',
+ 'ps_add_locallink' => 'Safe\ps_add_locallink',
+ 'ps_add_note' => 'Safe\ps_add_note',
+ 'ps_add_pdflink' => 'Safe\ps_add_pdflink',
+ 'ps_add_weblink' => 'Safe\ps_add_weblink',
+ 'ps_arc' => 'Safe\ps_arc',
+ 'ps_arcn' => 'Safe\ps_arcn',
+ 'ps_begin_page' => 'Safe\ps_begin_page',
+ 'ps_begin_pattern' => 'Safe\ps_begin_pattern',
+ 'ps_begin_template' => 'Safe\ps_begin_template',
+ 'ps_circle' => 'Safe\ps_circle',
+ 'ps_clip' => 'Safe\ps_clip',
+ 'ps_close' => 'Safe\ps_close',
+ 'ps_closepath' => 'Safe\ps_closepath',
+ 'ps_closepath_stroke' => 'Safe\ps_closepath_stroke',
+ 'ps_close_image' => 'Safe\ps_close_image',
+ 'ps_continue_text' => 'Safe\ps_continue_text',
+ 'ps_curveto' => 'Safe\ps_curveto',
+ 'ps_delete' => 'Safe\ps_delete',
+ 'ps_end_page' => 'Safe\ps_end_page',
+ 'ps_end_pattern' => 'Safe\ps_end_pattern',
+ 'ps_end_template' => 'Safe\ps_end_template',
+ 'ps_fill' => 'Safe\ps_fill',
+ 'ps_fill_stroke' => 'Safe\ps_fill_stroke',
+ 'ps_get_parameter' => 'Safe\ps_get_parameter',
+ 'ps_hyphenate' => 'Safe\ps_hyphenate',
+ 'ps_include_file' => 'Safe\ps_include_file',
+ 'ps_lineto' => 'Safe\ps_lineto',
+ 'ps_moveto' => 'Safe\ps_moveto',
+ 'ps_new' => 'Safe\ps_new',
+ 'ps_open_file' => 'Safe\ps_open_file',
+ 'ps_place_image' => 'Safe\ps_place_image',
+ 'ps_rect' => 'Safe\ps_rect',
+ 'ps_restore' => 'Safe\ps_restore',
+ 'ps_rotate' => 'Safe\ps_rotate',
+ 'ps_save' => 'Safe\ps_save',
+ 'ps_scale' => 'Safe\ps_scale',
+ 'ps_setcolor' => 'Safe\ps_setcolor',
+ 'ps_setdash' => 'Safe\ps_setdash',
+ 'ps_setflat' => 'Safe\ps_setflat',
+ 'ps_setfont' => 'Safe\ps_setfont',
+ 'ps_setgray' => 'Safe\ps_setgray',
+ 'ps_setlinecap' => 'Safe\ps_setlinecap',
+ 'ps_setlinejoin' => 'Safe\ps_setlinejoin',
+ 'ps_setlinewidth' => 'Safe\ps_setlinewidth',
+ 'ps_setmiterlimit' => 'Safe\ps_setmiterlimit',
+ 'ps_setoverprintmode' => 'Safe\ps_setoverprintmode',
+ 'ps_setpolydash' => 'Safe\ps_setpolydash',
+ 'ps_set_border_color' => 'Safe\ps_set_border_color',
+ 'ps_set_border_dash' => 'Safe\ps_set_border_dash',
+ 'ps_set_border_style' => 'Safe\ps_set_border_style',
+ 'ps_set_info' => 'Safe\ps_set_info',
+ 'ps_set_parameter' => 'Safe\ps_set_parameter',
+ 'ps_set_text_pos' => 'Safe\ps_set_text_pos',
+ 'ps_set_value' => 'Safe\ps_set_value',
+ 'ps_shading' => 'Safe\ps_shading',
+ 'ps_shading_pattern' => 'Safe\ps_shading_pattern',
+ 'ps_shfill' => 'Safe\ps_shfill',
+ 'ps_show' => 'Safe\ps_show',
+ 'ps_show2' => 'Safe\ps_show2',
+ 'ps_show_xy' => 'Safe\ps_show_xy',
+ 'ps_show_xy2' => 'Safe\ps_show_xy2',
+ 'ps_stroke' => 'Safe\ps_stroke',
+ 'ps_symbol' => 'Safe\ps_symbol',
+ 'ps_translate' => 'Safe\ps_translate',
+ 'putenv' => 'Safe\putenv',
+ 'readfile' => 'Safe\readfile',
+ 'readgzfile' => 'Safe\readgzfile',
+ 'readline_add_history' => 'Safe\readline_add_history',
+ 'readline_callback_handler_install' => 'Safe\readline_callback_handler_install',
+ 'readline_clear_history' => 'Safe\readline_clear_history',
+ 'readline_completion_function' => 'Safe\readline_completion_function',
+ 'readline_read_history' => 'Safe\readline_read_history',
+ 'readline_write_history' => 'Safe\readline_write_history',
+ 'readlink' => 'Safe\readlink',
+ 'realpath' => 'Safe\realpath',
+ 'register_tick_function' => 'Safe\register_tick_function',
+ 'rename' => 'Safe\rename',
+ 'rewind' => 'Safe\rewind',
+ 'rewinddir' => 'Safe\rewinddir',
+ 'rmdir' => 'Safe\rmdir',
+ 'rpmaddtag' => 'Safe\rpmaddtag',
+ 'rrd_create' => 'Safe\rrd_create',
+ 'rsort' => 'Safe\rsort',
+ 'sapi_windows_cp_conv' => 'Safe\sapi_windows_cp_conv',
+ 'sapi_windows_cp_set' => 'Safe\sapi_windows_cp_set',
+ 'sapi_windows_generate_ctrl_event' => 'Safe\sapi_windows_generate_ctrl_event',
+ 'sapi_windows_vt100_support' => 'Safe\sapi_windows_vt100_support',
+ 'scandir' => 'Safe\scandir',
+ 'sem_acquire' => 'Safe\sem_acquire',
+ 'sem_get' => 'Safe\sem_get',
+ 'sem_release' => 'Safe\sem_release',
+ 'sem_remove' => 'Safe\sem_remove',
+ 'session_abort' => 'Safe\session_abort',
+ 'session_decode' => 'Safe\session_decode',
+ 'session_destroy' => 'Safe\session_destroy',
+ 'session_regenerate_id' => 'Safe\session_regenerate_id',
+ 'session_reset' => 'Safe\session_reset',
+ 'session_unset' => 'Safe\session_unset',
+ 'session_write_close' => 'Safe\session_write_close',
+ 'settype' => 'Safe\settype',
+ 'set_include_path' => 'Safe\set_include_path',
+ 'set_time_limit' => 'Safe\set_time_limit',
+ 'sha1_file' => 'Safe\sha1_file',
+ 'shmop_delete' => 'Safe\shmop_delete',
+ 'shmop_read' => 'Safe\shmop_read',
+ 'shmop_write' => 'Safe\shmop_write',
+ 'shm_put_var' => 'Safe\shm_put_var',
+ 'shm_remove' => 'Safe\shm_remove',
+ 'shm_remove_var' => 'Safe\shm_remove_var',
+ 'shuffle' => 'Safe\shuffle',
+ 'simplexml_import_dom' => 'Safe\simplexml_import_dom',
+ 'simplexml_load_file' => 'Safe\simplexml_load_file',
+ 'simplexml_load_string' => 'Safe\simplexml_load_string',
+ 'sleep' => 'Safe\sleep',
+ 'socket_accept' => 'Safe\socket_accept',
+ 'socket_addrinfo_bind' => 'Safe\socket_addrinfo_bind',
+ 'socket_addrinfo_connect' => 'Safe\socket_addrinfo_connect',
+ 'socket_bind' => 'Safe\socket_bind',
+ 'socket_connect' => 'Safe\socket_connect',
+ 'socket_create' => 'Safe\socket_create',
+ 'socket_create_listen' => 'Safe\socket_create_listen',
+ 'socket_create_pair' => 'Safe\socket_create_pair',
+ 'socket_export_stream' => 'Safe\socket_export_stream',
+ 'socket_getpeername' => 'Safe\socket_getpeername',
+ 'socket_getsockname' => 'Safe\socket_getsockname',
+ 'socket_get_option' => 'Safe\socket_get_option',
+ 'socket_import_stream' => 'Safe\socket_import_stream',
+ 'socket_listen' => 'Safe\socket_listen',
+ 'socket_read' => 'Safe\socket_read',
+ 'socket_send' => 'Safe\socket_send',
+ 'socket_sendmsg' => 'Safe\socket_sendmsg',
+ 'socket_sendto' => 'Safe\socket_sendto',
+ 'socket_set_block' => 'Safe\socket_set_block',
+ 'socket_set_nonblock' => 'Safe\socket_set_nonblock',
+ 'socket_set_option' => 'Safe\socket_set_option',
+ 'socket_shutdown' => 'Safe\socket_shutdown',
+ 'socket_write' => 'Safe\socket_write',
+ 'socket_wsaprotocol_info_export' => 'Safe\socket_wsaprotocol_info_export',
+ 'socket_wsaprotocol_info_import' => 'Safe\socket_wsaprotocol_info_import',
+ 'socket_wsaprotocol_info_release' => 'Safe\socket_wsaprotocol_info_release',
+ 'sodium_crypto_pwhash' => 'Safe\sodium_crypto_pwhash',
+ 'sodium_crypto_pwhash_str' => 'Safe\sodium_crypto_pwhash_str',
+ 'solr_get_version' => 'Safe\solr_get_version',
+ 'sort' => 'Safe\sort',
+ 'soundex' => 'Safe\soundex',
+ 'spl_autoload_register' => 'Safe\spl_autoload_register',
+ 'spl_autoload_unregister' => 'Safe\spl_autoload_unregister',
+ 'sprintf' => 'Safe\sprintf',
+ 'sqlsrv_begin_transaction' => 'Safe\sqlsrv_begin_transaction',
+ 'sqlsrv_cancel' => 'Safe\sqlsrv_cancel',
+ 'sqlsrv_client_info' => 'Safe\sqlsrv_client_info',
+ 'sqlsrv_close' => 'Safe\sqlsrv_close',
+ 'sqlsrv_commit' => 'Safe\sqlsrv_commit',
+ 'sqlsrv_configure' => 'Safe\sqlsrv_configure',
+ 'sqlsrv_execute' => 'Safe\sqlsrv_execute',
+ 'sqlsrv_free_stmt' => 'Safe\sqlsrv_free_stmt',
+ 'sqlsrv_get_field' => 'Safe\sqlsrv_get_field',
+ 'sqlsrv_next_result' => 'Safe\sqlsrv_next_result',
+ 'sqlsrv_num_fields' => 'Safe\sqlsrv_num_fields',
+ 'sqlsrv_num_rows' => 'Safe\sqlsrv_num_rows',
+ 'sqlsrv_prepare' => 'Safe\sqlsrv_prepare',
+ 'sqlsrv_query' => 'Safe\sqlsrv_query',
+ 'sqlsrv_rollback' => 'Safe\sqlsrv_rollback',
+ 'ssdeep_fuzzy_compare' => 'Safe\ssdeep_fuzzy_compare',
+ 'ssdeep_fuzzy_hash' => 'Safe\ssdeep_fuzzy_hash',
+ 'ssdeep_fuzzy_hash_filename' => 'Safe\ssdeep_fuzzy_hash_filename',
+ 'ssh2_auth_agent' => 'Safe\ssh2_auth_agent',
+ 'ssh2_auth_hostbased_file' => 'Safe\ssh2_auth_hostbased_file',
+ 'ssh2_auth_password' => 'Safe\ssh2_auth_password',
+ 'ssh2_auth_pubkey_file' => 'Safe\ssh2_auth_pubkey_file',
+ 'ssh2_connect' => 'Safe\ssh2_connect',
+ 'ssh2_disconnect' => 'Safe\ssh2_disconnect',
+ 'ssh2_exec' => 'Safe\ssh2_exec',
+ 'ssh2_publickey_add' => 'Safe\ssh2_publickey_add',
+ 'ssh2_publickey_init' => 'Safe\ssh2_publickey_init',
+ 'ssh2_publickey_remove' => 'Safe\ssh2_publickey_remove',
+ 'ssh2_scp_recv' => 'Safe\ssh2_scp_recv',
+ 'ssh2_scp_send' => 'Safe\ssh2_scp_send',
+ 'ssh2_sftp' => 'Safe\ssh2_sftp',
+ 'ssh2_sftp_chmod' => 'Safe\ssh2_sftp_chmod',
+ 'ssh2_sftp_mkdir' => 'Safe\ssh2_sftp_mkdir',
+ 'ssh2_sftp_rename' => 'Safe\ssh2_sftp_rename',
+ 'ssh2_sftp_rmdir' => 'Safe\ssh2_sftp_rmdir',
+ 'ssh2_sftp_symlink' => 'Safe\ssh2_sftp_symlink',
+ 'ssh2_sftp_unlink' => 'Safe\ssh2_sftp_unlink',
+ 'stream_context_set_params' => 'Safe\stream_context_set_params',
+ 'stream_copy_to_stream' => 'Safe\stream_copy_to_stream',
+ 'stream_filter_append' => 'Safe\stream_filter_append',
+ 'stream_filter_prepend' => 'Safe\stream_filter_prepend',
+ 'stream_filter_register' => 'Safe\stream_filter_register',
+ 'stream_filter_remove' => 'Safe\stream_filter_remove',
+ 'stream_get_contents' => 'Safe\stream_get_contents',
+ 'stream_isatty' => 'Safe\stream_isatty',
+ 'stream_resolve_include_path' => 'Safe\stream_resolve_include_path',
+ 'stream_set_blocking' => 'Safe\stream_set_blocking',
+ 'stream_set_timeout' => 'Safe\stream_set_timeout',
+ 'stream_socket_accept' => 'Safe\stream_socket_accept',
+ 'stream_socket_client' => 'Safe\stream_socket_client',
+ 'stream_socket_pair' => 'Safe\stream_socket_pair',
+ 'stream_socket_server' => 'Safe\stream_socket_server',
+ 'stream_socket_shutdown' => 'Safe\stream_socket_shutdown',
+ 'stream_supports_lock' => 'Safe\stream_supports_lock',
+ 'stream_wrapper_register' => 'Safe\stream_wrapper_register',
+ 'stream_wrapper_restore' => 'Safe\stream_wrapper_restore',
+ 'stream_wrapper_unregister' => 'Safe\stream_wrapper_unregister',
+ 'strptime' => 'Safe\strptime',
+ 'strtotime' => 'Safe\strtotime',
+ 'substr' => 'Safe\substr',
+ 'swoole_async_write' => 'Safe\swoole_async_write',
+ 'swoole_async_writefile' => 'Safe\swoole_async_writefile',
+ 'swoole_event_defer' => 'Safe\swoole_event_defer',
+ 'swoole_event_del' => 'Safe\swoole_event_del',
+ 'swoole_event_write' => 'Safe\swoole_event_write',
+ 'symlink' => 'Safe\symlink',
+ 'syslog' => 'Safe\syslog',
+ 'system' => 'Safe\system',
+ 'tempnam' => 'Safe\tempnam',
+ 'timezone_name_from_abbr' => 'Safe\timezone_name_from_abbr',
+ 'time_nanosleep' => 'Safe\time_nanosleep',
+ 'time_sleep_until' => 'Safe\time_sleep_until',
+ 'tmpfile' => 'Safe\tmpfile',
+ 'touch' => 'Safe\touch',
+ 'uasort' => 'Safe\uasort',
+ 'uksort' => 'Safe\uksort',
+ 'unlink' => 'Safe\unlink',
+ 'unpack' => 'Safe\unpack',
+ 'uopz_extend' => 'Safe\uopz_extend',
+ 'uopz_implement' => 'Safe\uopz_implement',
+ 'usort' => 'Safe\usort',
+ 'virtual' => 'Safe\virtual',
+ 'vsprintf' => 'Safe\vsprintf',
+ 'xdiff_file_bdiff' => 'Safe\xdiff_file_bdiff',
+ 'xdiff_file_bpatch' => 'Safe\xdiff_file_bpatch',
+ 'xdiff_file_diff' => 'Safe\xdiff_file_diff',
+ 'xdiff_file_diff_binary' => 'Safe\xdiff_file_diff_binary',
+ 'xdiff_file_patch_binary' => 'Safe\xdiff_file_patch_binary',
+ 'xdiff_file_rabdiff' => 'Safe\xdiff_file_rabdiff',
+ 'xdiff_string_bpatch' => 'Safe\xdiff_string_bpatch',
+ 'xdiff_string_patch' => 'Safe\xdiff_string_patch',
+ 'xdiff_string_patch_binary' => 'Safe\xdiff_string_patch_binary',
+ 'xmlrpc_set_type' => 'Safe\xmlrpc_set_type',
+ 'xml_parser_create' => 'Safe\xml_parser_create',
+ 'xml_parser_create_ns' => 'Safe\xml_parser_create_ns',
+ 'xml_set_object' => 'Safe\xml_set_object',
+ 'yaml_parse' => 'Safe\yaml_parse',
+ 'yaml_parse_file' => 'Safe\yaml_parse_file',
+ 'yaml_parse_url' => 'Safe\yaml_parse_url',
+ 'yaz_ccl_parse' => 'Safe\yaz_ccl_parse',
+ 'yaz_close' => 'Safe\yaz_close',
+ 'yaz_connect' => 'Safe\yaz_connect',
+ 'yaz_database' => 'Safe\yaz_database',
+ 'yaz_element' => 'Safe\yaz_element',
+ 'yaz_present' => 'Safe\yaz_present',
+ 'yaz_search' => 'Safe\yaz_search',
+ 'yaz_wait' => 'Safe\yaz_wait',
+ 'zip_entry_close' => 'Safe\zip_entry_close',
+ 'zip_entry_open' => 'Safe\zip_entry_open',
+ 'zip_entry_read' => 'Safe\zip_entry_read',
+ 'zlib_decode' => 'Safe\zlib_decode',
+]]]);
+};