From e1f990190eb626678067a30289685fd47231f86c Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Mon, 6 Apr 2020 17:33:07 +0530 Subject: [PATCH] Added search object functionality. Fixes #2172 --- docs/en_US/getting_started.rst | 3 + docs/en_US/images/search_objects.png | Bin 0 -> 188209 bytes docs/en_US/images/toolbar.png | Bin 38057 -> 42931 bytes docs/en_US/release_notes_4_21.rst | 1 + docs/en_US/search_objects.rst | 34 + docs/en_US/toolbar.rst | 4 +- .../browser/register_browser_preferences.py | 15 + .../extensions/static/js/extension.js | 2 +- .../templates/packages/ppas/12_plus/nodes.sql | 11 + .../constraints/index_constraint/__init__.py | 4 +- .../schemas/tables/partitions/__init__.py | 7 +- .../tests/test_backend_supported.py | 10 +- .../templates/catalog/pg/macros/catalogs.sql | 18 + .../catalog/ppas/macros/catalogs.sql | 21 +- .../servers/roles/static/js/role.js | 1 + web/pgadmin/browser/static/js/collection.js | 15 +- web/pgadmin/browser/static/js/keyboard.js | 11 + web/pgadmin/browser/static/js/node.js | 25 +- web/pgadmin/browser/static/js/toolbar.js | 12 + .../browser/templates/browser/index.html | 2 +- web/pgadmin/static/bundle/slickgrid.js | 2 +- web/pgadmin/static/css/style.css | 3 +- .../static/js/alertify.pgadmin.defaults.js | 3 +- web/pgadmin/static/js/alertify/dialog.js | 33 + .../static/js/alertify/dialog_factory.js | 13 + .../static/js/alertify/dialog_wrapper.js | 6 +- .../slickgrid/plugins/slick.autocolumnsize.js | 4 +- web/pgadmin/static/js/tree/tree.js | 134 +- web/pgadmin/static/js/utils.js | 3 +- web/pgadmin/static/scss/_alert.scss | 17 +- .../static/scss/_webcabin.pgadmin.scss | 2 +- web/pgadmin/tools/search_objects/__init__.py | 87 ++ .../static/js/search_objects.js | 90 ++ .../static/js/search_objects_dialog.js | 40 + .../js/search_objects_dialog_wrapper.js | 649 +++++++++ .../static/scss/_search_objects.scss | 122 ++ .../search_objects/sql/pg/10_plus/search.sql | 435 ++++++ .../search_objects/sql/pg/11_plus/search.sql | 452 +++++++ .../search_objects/sql/pg/default/search.sql | 367 +++++ .../sql/ppas/10_plus/search.sql | 493 +++++++ .../sql/ppas/12_plus/search.sql | 516 ++++++++ .../sql/ppas/default/search.sql | 437 ++++++ .../tools/search_objects/tests/__init__.py | 0 .../search_objects/tests/test_api_search.py | 75 ++ .../search_objects/tests/test_api_types.py | 47 + .../tests/test_search_objects_helper.py | 117 ++ web/pgadmin/tools/search_objects/utils.py | 131 ++ .../tools/sqleditor/static/css/sqleditor.css | 2 +- web/regression/javascript/fake_endpoints.js | 2 + .../search_objects_dialog_spec.js | 155 +++ .../search_objects_dialog_wrapper_spec.js | 545 ++++++++ web/regression/javascript/tree/tree_fake.js | 3 + web/regression/javascript/tree/tree_spec.js | 98 +- web/webpack.config.js | 3 +- web/webpack.shim.js | 2 + web/webpack.test.config.js | 1 + web/yarn.lock | 1177 +++++++++++------ 57 files changed, 5968 insertions(+), 494 deletions(-) create mode 100644 docs/en_US/images/search_objects.png create mode 100644 docs/en_US/search_objects.rst create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/packages/templates/packages/ppas/12_plus/nodes.sql create mode 100644 web/pgadmin/tools/search_objects/__init__.py create mode 100644 web/pgadmin/tools/search_objects/static/js/search_objects.js create mode 100644 web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js create mode 100644 web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js create mode 100644 web/pgadmin/tools/search_objects/static/scss/_search_objects.scss create mode 100644 web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/10_plus/search.sql create mode 100644 web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/11_plus/search.sql create mode 100644 web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/default/search.sql create mode 100644 web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/10_plus/search.sql create mode 100644 web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/12_plus/search.sql create mode 100644 web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/default/search.sql create mode 100644 web/pgadmin/tools/search_objects/tests/__init__.py create mode 100644 web/pgadmin/tools/search_objects/tests/test_api_search.py create mode 100644 web/pgadmin/tools/search_objects/tests/test_api_types.py create mode 100644 web/pgadmin/tools/search_objects/tests/test_search_objects_helper.py create mode 100644 web/pgadmin/tools/search_objects/utils.py create mode 100644 web/regression/javascript/search_objects/search_objects_dialog_spec.js create mode 100644 web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js diff --git a/docs/en_US/getting_started.rst b/docs/en_US/getting_started.rst index 5b09c5b4c..2595505d2 100644 --- a/docs/en_US/getting_started.rst +++ b/docs/en_US/getting_started.rst @@ -64,6 +64,8 @@ display. To open the *Preferences* dialog, select *Preferences* from the *File* for the dialog. You can access additional Postgres help by navigating through the *Help* menu, and selecting the name of the resource that you wish to open. +You can search for objects in the database using the :ref:`Search objects ` + .. toctree:: :maxdepth: 2 @@ -74,6 +76,7 @@ the *Help* menu, and selecting the name of the resource that you wish to open. tree_control preferences keyboard_shortcuts + search_objects Before using pgAdmin to manage objects that reside on a server, you must define a connection to the server; for more information please see *Connecting to a Server* diff --git a/docs/en_US/images/search_objects.png b/docs/en_US/images/search_objects.png new file mode 100644 index 0000000000000000000000000000000000000000..950e813168a89fbd114a1852a2fc7d180f81df82 GIT binary patch literal 188209 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

h^IEZDYga{zQW3eFHE=IZY}(?h2~q+jj)S< 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 literal 0 HcmV?d00001 diff --git a/docs/en_US/images/toolbar.png b/docs/en_US/images/toolbar.png index 19c4c574a905fb30ea1828b4825e85af7cdb0c0e..aac16b967b93b44576bf2a042b989aa296251648 100644 GIT binary patch literal 42931 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%0D-NlnK%gelqO9|`%poZ~XyuF**dKg(*_% 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

k6m3s9%Y>P*~% zV>Ferj&30#Bd#?>9I z0R2z!^dxhK>BgBHYQp=up4I6~ibO3|;5SIohCIf#oE*5CljiP&{R=N60!fsRB z_+H@2@9tG46(Ji}#v#pxfX>5OMtUod>_qKMKofH;2{zrjhPZaS@clWNOs@zrEl6l| znB@OU2lN5~w>(_*pASc1a>x&^C{7*%IodJuw@qK)Y|*|^nIC!T1RDX!M6&`sc|5ID z25y>`>pCyo{U~WTk(Hg=6V!{BM#BQf;lgmK!dM(FamNRM_OoAac#7T@RfhHZVVrnK zl!XCZEA?!u5pkXvY2ZOuvk{+5rvt68aNKWl^hyG}<$(0urrCse`mF28OeU=JWjm#I z+AkXPJs{mg!bnibomJJ%R_yMCZZ-?-8!D>|0>d^v#A4RY?Z`kyYFZ4Zw|QS(6RbJr z+>ZBjK+1R%)@N1rRXmb%Kf_aUq4S`0RD{4z=ZCX^eJU9mNWHKJqhj@!##6x{iY{nL zPNh0dSBFgtZ>RUUjpJq(@gCHpo%gibQ&sWsesk3-$d z=&`W}1cFt%dbpW?J;Kds+V1x=h?q&lIujDTt~prgh0 zWr|70@fZiTJsg;YXk&?$zR~q^W6KYtc!8B_HFmJOo3=`#`)%qMGu)L-(+SWc?Fz^L1VgviEpD+#37*(+9U`= z1v-Cdv_w4(Pi*61UgT~4z^BGTYU0j{Sw_9Tw$jFLhO(360_OCBK&XC<_*`j-LwQ zf{UHmSC6%u3y14UN_*vJBjHP0*7&+8)yRmj&>R!A5>9!3Lr7383!*%t-y!ZF8r8pq ze`zP=uq6Pndg^87_=|YlSATz*8C__TQ~hYEpUZCGn*mJ~WGIqJfdSED6o?&KtP2V0 z^gf4csUWk1`!MXTW?auWo58gEkTCM?QjQOLkvnFm?*V@7FAQO&5|Gg8w3B4JzN{Oj z(g;!!Jp(SOF1e;tIs^l%dGqAdI;~}H-0*PWRquGf$Dui?x=-5<=F(W}fSh-ihvBT6 zqMb;(B83;0;0#})5Dp{G`w%|~o+030iaL#fjk*tW=xo(@xQN9g*(Zm4B2LcAuV-*5zw5QziiOWxt0QopVb8Y6&eGW<^u0hqhE z6C|v9EXBSHYB=xmnv@p?|FJL5q?fwYB1Y604+B|zN2I7lCQA0tLeMN|l#wsHOZOKM z>vv{y-0?%^Q(hDX>V%gUhi2RFlHYazGhU}wn6)Ow+sni%ZqqJstA`?41RAXO8DJ?l zHeOATCD-Uw2_|n9xvSxs$=Po#YKm1UJq1U*g4OA+>%RAaPbbNg-<;8?E;G+!E#o%- zn{fCaS2PX+EqacwpYeEv{F!_h{@{}t(60Ymk*KmLK(r?6hH8?2vXNsS4<%)}oki`^ z-6lrf&ma5rIFD?+obdl)C~FyQ^Ynp;Ss7Ute zc_l#X$T6Yw>B%=#lDEF19`vNGctw1U>`%>-Ki;yOnBhWD=R)L9#s;k!vXgTEPusJg zn7N4ES_lng_yXH!PZ^l1~LAX-Mp_y3L^uIUPkeygNr$^-S z>4!LZxoriG>KA#^f(oF{cUMMjiB{(xDsBH8g8yZG_P#~}8ylOD|K`%fN?%S;Ohny> zHT8?Cf0Qfs^c99ZYwTK^khLiL+b`nN;oWb2Q4bU^N4XG=75 zc1Ar?NmA6<|Nq00b|Hc`4`|N>k}|vUoWtPF(4S5j6`Eq>odEI@iuK->5W%MfQ z|BaphQcV4(4F&M7-ODo&%t%dxN;q1)jI>T*&4>OkG-;+Z9A$&Y!2G49iD8k||LIXR z%+oGRIa3HOVea&jqzc8}8OVj&?FiWlqyOJ~s}BOnVie^gM)kKZXm?n6i&iNOTzX2& zaK_NElT|0h;%TcZdUTOEaER}`PUBx5topRf419IGs+SD89DCr2^&BMWQ3pu$^=Yj%)Di*`WLi5-8gA*MTeWc z&6%H8oGB{4MR%XszTwn>WyQRzhcF3cer@Qe-Mipz$frN;;RZ2{tUR|*zO8+gFC2LU zFU`Dd^LcB&rY~62;JvdtsyTRWUof9Ox6^WUdLO%po1fo2?Krwu4K3_Uy>65oQA&SC ztNL?B-xj~($H+fFI zo;o_IeO6UHb45;%;5Jveyk&eY@$uzcO&CTSep!3l=+b*H=s$KL)C{EGTVLsn%2l9W->zB4eu&9$iaib`377=pQ>Hq0;ff+qQ8g5-4-Yqgx zj$BO^$0IDA@uEiLVNMB6hl~dbX+9@N(PPT1>SBwWWcr%!^q!2H$LDArCoQjEBP=}! zym=LmOa?C3E15nPOx!rdBzsOe$F;{EpIrqj(}PWj7T=pH*;&vVDqK%H>yj;9H&#U} zYpqY_w`t}8+(&8gGj4a&LfhjWt0JrKsjt^b2b*E=1^YlmaktFhoRfA}H&e!pJ`PF{ z-4=9_1H_#?pt3EbY8A$h&K2xt} zi@042J6sM|Qe02^8y?mbxOh<(1l3inukd@ni(^9+m9=RKwIu*qgIMJVLnc|$1nL51 z*qpmF^{f^(zbbG3&td9q8w7$TE`L6~7kAsyeu%gecBH2_!#0d+R>HNnA(; z`+xUMsGzz+*!C(Kud7DAwDjwI*Q{$W9bWhHCX8ErPh+5rvzs&W(}T}p;^OR#h)D2j zo`P7d({=}~w1(fjLNiQBc}b$6&)zI9(d&zj&-q_pX7KAaUwd^%NJs}*fpy#-(f-v| zQ~NL0%*0NA-&kxX?sq^t57+#f^H1gX5Ky7NQF~bmP+0%*uqkJ@4D}o$zA8X)|-f4?uNS zXjnkrF71-n7H<37A_+~(C5)>b)Kn=d7lm6@6$6WhP$mB@(3yHIeja9#PMTWqaIU|E zeR&F8Tn_#mgQRY5FRNVBO*H9pEr-05Ici&ly=s}6kWXX({pn0;OJehC%SY+YIJJk> zmRg>-7fF$ikYk4v34Js^H&HgeH8LJr@#MdbiY{6N`Hs^TkpGH$t`l7BZy_XPm)#D9 z=u+r*26Q82+%IoFa(v+n^M}C{7}`iqw;+2S64fW)S|ag68!3?x^u+vl=Cw8oW$a$_ z&}g`%)KNxd_M_$^3YZ-k{G@-92^qSSBl8YqN3(WiHfFKjcJg@Tnp99hR~`tGUS3@y zPteJ$rMA%jo|Co}TFTQk#wHlVw(JiD{42y2ncff*V`RFyRhTF zk(9}~90jJu913CI$9gge>fkWYyOri2^1vkhYz(ghj)M_)dT)ZZfw$XedQ zi8}+A*c3revaG$u8Kpw&KLP(>0vF37!i37nU<_!11DePg1W;HZqjtfoRSWnK(0R%l^J+Mri9~@DQh25U2mMCqFKIWB<%5SOhoeQJ+_J)df zN&Lr}+a6}LQ6tV!62+|bgNW5)l_?IWmSENJ%7V1zk?H@+&wlq9pzh@=fuhz(i8=vf zw1sIbi!`Px8=eH1yEJxnNb$N#)M(1e%zPum}`XT{R1Fm#I&Vn4mOn;Iujrt zok`j7L!O75Shnt4u7{u(=-6<^mXx#>r%{sm^a(jJDa2A^WW;gn8e7f|&QheLl<<^I0Xa!f(;FKO7#4{lO8-#ue24M*XhM_`@3n`#Gih?dk zO8cXh2h+VZ!zkVnv_yNy-$8poFi+Ig~Ou~=bhyJ=v9t=Imk3YS#@QvCOPIO zO!zX32#S=pG$C))%Nvp^{~L|%@Ss|j=edKD7jz&PrPKCuslnkE9p#W61iZ2r6u@{%l1<-BfKm;a zW_Ncg1I=d6)^X7)W>;lEli z%4Lxa=(CR)d}+lal}z-F{bgsV5#1>obzP&_+t^7?e!T|9ud+0-rVI!z2>_v#&`wHDm;H> zNJTMF2N7=)SX?QjxJ!|Fk>USL20YNeT}@LlYZNl0>rNMBB)oVL(tfc})Kqi{@$ty1 z_$j?_G_o?NDUv>^Dj`7-l5%=Ll>;AW@~ENj|3aa#IBavJvY5fa=G&hCWyGaX`Fy`S z#K*+}qc{tH7jSP(Oif9@JTGv2(=L?AUSP^EW`UnhnLCjXm4xA(4|z2hM_6vw%G*2G z&r(Fp@k{RQZKB}!1(4FxN+Cm1ls7}c!dvZ=KANyLsj|(}Re#J$m@x=x?)=h!?1Lm2 z4M(FvB`aI|8!7&Wg^>|ZJ>q3_JekI9y~z<_`xiEEnf*VLik=eA_C6ymiH@Q3CBN`e zGA;?HS;9?6Y=VpH^^cyJ?@RwaIr*yUcrBE%NmlH5JaJ%!4HBETKzt+?r`GXI4#iH- zna6AfCp*lR7SH#?3B_SjijKhR=D(9@{_~d9mUpGiWttWepI*3`0%oX>>I3HJhSq(x zkl=6-^@k((wR-z7I6SUHf3-mMjcu?($odA^QU0&jPFn3|t*7gCYij(Bz$<+LIT777 z4(CFik6lpvF|vfmi~H+x%-qs-Zb^2mpB2n9As%=3_t$fe75Q3^k5Ajne#B9lX?EQ1 zu3j!C?OZYNtclV^!T%%>NjO{%TLF`q9vNm9S%Hj}pL9F&Tj`Xs2xUOp{9d*%)oeXY8gf4#cv4AD1vla%sB^IJH0 zV9k(@Hn%*eUAhzy&x9`TetBG+YWg=RNp-)=N?%mF)vh=OPc{QH_%VOPU^(SBts4h5 z>_D7+BKXmwPoCxw@=<3ibBG{0>NN*`cE7YC&RKPyRKMfzBX--3D&n8>Te#c%yI7(D z@v^40YO?b3iXptuIan)E*_9--60{2T(R#A`qc94BIBx46X(2+Hi?gqlr1s`W!-s`} zwV+@HCl?jp4%Gh3wT7d!lAK{6#!T-yI(I=qKg*47X+GC)P`869_CnblzPk|q55X%- zN8qU}S%;bjcD{^0+~tpLKHQ$Pf#%1qDjTVit{b?5K6$mzDJ}e;j~8*fN&VNYuQlAA z_LiSzQSP(8F9OJp=R4jQPdf3~fY=}2Y&S+~I=^-ptyG8rC@O0DI1C*x?PBQ+>V;w% zP72s~U5VPer^~COpaH`H<*f(HDfi^W#D1`D9VDMyyScw{#$9cwx1o{Y@NAUhdp{J;WLT~vQEV^T-AWDZ$cV@j9%RL%8`K_?WLQRxf+yhn zXe2$J%Ag26Fj*y!-98>j#ONA_3XR5c1i8P{Lj5&89nMx9{Vib>CIcdVE7S zUk?v=&+S#SaAv86CtG6J&GlxI)BV}N+3ob7eGq}00icmzVg9GxpJ*;6W0fy(;p41s z_-TlVl?@RzwmQmDf1++Yu*YHVZM#)6H(hRcnGFUR6GF@aI_~diYQ|w_z7?;#PcZB^ zVyv5PqZp+FKo6ja|4t-V+24T1gr-z*w@QEabY1wyl#g#ypq>Q+y8gD#H@L zp6}K=D=v5r9i;zSJieeHL&ITDj=Jx&bxP%QD2~euXveb@yUkeQ-0y62IPAPm5P-GEpoDhU5$9ZinO`hd*EW%Q)zNX?%dy|6V$T?pYVD@oY)UxJ z>}E^KPw!WYMD9qLw~7N_jFCfWw%O5vfWsur@w^NBc)O^XZ?Vzs0BQU!7hpev<*ZUX5KD`AvjPQ&l=jGkHOr;g< zBS@SGV*gQF%)@yb>QrF=2UmG{NQ~gCA6>45Yeneyr5g9W3k;VG;o9F5+KPqf`Mb{8 zJ58}b7 zI|c4aZEZ~E@o96G75{3zX{!X2F~QgIJe7{O-DQKqvjbslaiJM88q5RVv)0H6)f%#; zl>Lgp`=xI_Z@P%?8e3J@E6H72ha!fb?N9q7#~|EJ#D=MmqDqf7UK*EiJkQe$iv4EY zNTTzv{BfVAr?!%8uR6!e&80@y*~MR@l_kP@&*QN)3@zU5tRxSHpN%`-uSu##{V#U& zO&+pma}6yYSJz1Pi*e%Pdm#iW5=2PpeCja=2Tfxo&OpP3yB9S* z&7C>!=Tt0eJ?G^Wa0x&2ToX&{YZLj$Gnr7k2c_ToA?YSS6;Ufo2n1{_FQs8k9yM~n z(U3G33V#>e6u zZ)6fZiYxucWSFg((9Gj74_y)?iC!IxV}nUg^5q^9N8|uf_T2v%)~Xt-D2qpn$Ya}+ z={>x5caZ6JjMn+y7cz<@o=G^7Oed>!d*Gf0vmMQz&B@&#Q1#9kHCCzK07eQ5Vil(f zz+jmjK9zzqiz7VAa>>>!ojPj!yF}ggyzOyxoMDr!)8#(aFvCYv)BRTdliU|Wp;%>7 zua2=HR)1|dt!O7>G;#tCgW830_j*~Ee;yj2CYsc?85$QzClU?@`()V711kH^%E{d7 zy7d6T?W`!}a2Us?@qzN*>v_vG9XC_Jn-Xz!?I4EVdhq69L6%*!Ts6_y5Xx?`RDQll z665vtBqzXFT!S?o0BA{&)FUygMx&F`7q2 zX)^o}#Msd)Xc#O1EqvvOV{Up@yt1N_uc(MYHRSlF@mEe;+zWB3A|vniT$3lZ?CQ;q z!*Ct-Re!(5{&?+V+`&*xa--QQQlQnDW=`O+Lhun`=|Mma;vKC~o7)Av@da}k766Wc z|3bb~b#+GFB)gV-RglKxdRGhgID?Ki{JSxC3xcZslc8k{o_*U=*f|PEpJQe!ltzm< zmTNNy;?K{i^)0Bm)k1rlXU+4uA0$EY-io#%X6sjpEkYP?|GyQI7=GjKD#k>1P1B?; zmv7ypNfwzF|JMBD}8^BmmghVlm~Ul7?$wt^ygzMYjE zjZx&l#Z#)v07`JITl=bm^0)y~aAXRhKu8kSVE+&dn^)mi5K{&owR3n)qa%H8K+_nn zt46_P6(J)%HunpI3XBOB6*uBM8ohY_a5H+`oS6wP96~N__q;A|v=f}t&Y24-vROP?t`!tg@%vPCa$jqg z<*4&ZaMfClLOjl~S}a>u3}*9&;b4P7L&fGp{KavIFs~Df_EdYrb8n?xK07-l$>it< zs>hM}Nu+!Wa76IgkSQ(f^wVTQn=E%{rn;#SA?5AsACm+=aegJ4d4=kg47Fr)5V~wW0w{T!FMdYKyhJ51}W7E+p31=wB>e^ z)t7=oExQUkwG2sccg4Ols=v-C&}rN|05X5~-1DtX-*H**b?Mdpe$Bn`q__S>mZC+B z$L-wsFbe4`j-l&WXRbgllSxS;9?fdtpK)RtkgLu4qo+{-zcc^FJS{@fpI`5ZttQi| z8|;lb9E~T5ZPp^mx#gVy~MsI18!@-8>czy1x0MU{}2WX6?hc@ zB5*g<^$~93fnQA9l7HJ<7XF0HqD16(&9Pj{bCFWkEx;~N=0b6KJXijk(yCCxd2$h% zC6->Cx2PB;ES%M)EN(@3dkd*4v`Uq4n8oK6Y`&RCceC?dtLKp*Vf6O`=Kf{3%VJQM zL+r=OLQa+XcovgvP9`Q32OHwj(?Vj~fsl&rY>13V_YUl`P#e=%9+rAoaiXh=Fa z60>;NtHKhp(?y=McE{aet6_9?&lQ=+-nhRz5kB7}cexcN*bK=zo7b@=3pS)6 zgKT}u_Hf&xE07+m6=Ka-S*782sxx9)O*S2cdC86he5xRfR!9t^3(DKWnV}Js2AT_k zK+pHrd#FiazUfRhTXw|#^)VrR@rQ7Rzdk3X`GLEch;{oJImz!?9ZtWlIdK9nqZ9oU zFje4LdVLO9|5id5OnYH`fL4WKiA*zM)XHL+ViaZ@ksz3_BN1Zjnz-lU!30B3BkM_~ zL$u=!zH1we>biw1JS_t6gB;HF`_C5&X(B*>Ih(}UOfSx+5MzRVkYB_XiWD5=l=5ec z@*+L%;jyZpD7V`23)8Qf&#l_4%v!a7}$E zbDnJ8A9*?vLklwHUHK(@49D<~Yd`Z)FIA{032&_|mSSM%3w+KM8wPLtYWaiRi(E%`mCoUk+lVK?6USJYbzAX0Zho1M+^wqL~E|&YtTPV?o8?@C{%fvP#7M z(%vt#gnxTr%wU=^@&))SN2tZ;DbM7uZq9m`1XxX$3p&(4 zXJ9K|Lv@RDrcDk3tV?BUpfVgf2ns@A%mGi(cyxTIOd>Ds$IFse!ru=iz+&{VZLl>} z={4<6*(*gv2(c*9{L8FY(=w0)Y^mz+6P>!oAKW%c<{cqy>*nDC8e+U}p;LStsU_Bk z%{Q}ekBwjF12KGaUne9L1oNjpINtrd%-1OXv@hb|WU=PvXvU=oykz6}mKV#tv9x@v zM6M7KBv^kBob^JQnXSe}#+KLqayz!dKUa2!!Kb-#AGs<6Mf3z2hWs;vmWDTp^pooR zdb_Zn`n7^e%A;sV&0#VO<^}s%D#IZp z=&K<%3)HH<-S~W4nAg@4f-x}u^KU-=dcSFbfF00NES9RXHER|K&7Epf3%S{(<$BrZ zg=52%?)lj!d1?Sd`l?)LG86)5P-%S&9zJ0D@zL*K-zR@UXw9Y5#tNC8U?iqxdJowW zTJd-!mn}S8kbs7c|Lig7xH(mB+TTabQ&t2`xe94Ey4|Cz*V=2x8i|b8G|miUG-^Je z5ZC}#T6z!I!1k_jqqn-(gwGQ_evB?$H|h4ZQ9~*T#xtX=JaH+2We@|>#KrlDvpSw) zdAVIQUvG(cPdAC`JqG$QC&CfmwC5X4T|P@~tX6$_L`y2dZWX}iwm$7sZRSkNIO1EF zWYM5uiv$zU-z*^;4G7v`^W_rui5 z7%-Q_J?E)x*@MtN3_w^pKZyDu5=hdZHc6zHxmPR`tR>7w+-W-s3Hs52f0#-aA%7b$ zQ_4S9Nb}w}LO~f{ozgX5@f8iLQkk_x)T-PLNoziCIFvjR01CUty@fmg5J$M`&#@%3 zdn;CF-yI6oD2_&BfjKfRq+B+e47 zh39x6P;@DC4y3P){O%jT{ntxP@Yns0f`AEwB z>c{>n4h-ibOeRJ|Y&~kggLFH87`6ZekVS1IGKG8WS2GP4%p<|d6ijBsW3v1>@?J9> z=7GEQ&ZF1D^#o{cLo?6FbrMVE)t=Ysq>PZ6?~<*0!ASNHVPB-sZ;u~FV=daAk(wYp zO1*a$pFp30O+V08rufNQHZWxv9Ah@2se<~HV$+e2ho@wXbAyx97U$_X-YZ!CFOE{c zlxET+-pJCdTe@JVB4r(Irqp`K6nG_qa$SZ#>h<`ykeh{muo9HrVK9T%wNd-V8L~jn zg-?`Tk@RXd^=a8K8d`D3t`+>)aX)12wMIrtrk$+ao&!3yL1*X=8qTQhoZRFVs;DZfs)+1(Rz3iea*1uOJ>kTPIqec^j39<& zEl&7jV$-wD*+;I)9;->worFXa;bOS~=u)r?j&SLv^?lOyh+GQ$mN3xrtQ+qgnm~DZ z9Q928mH}#E++oSjj<`$AY%)0g;@D>%kmENU_bzIbhB_=;NORS8h~a?6^M|wkpSf_M zF%$TDW2_wBWpyE0wmzD3b*fNC{Jw+Rc>V0a1^&&PpfrYON7{$Iy*&us%3|N7u$Od| zjA|TK^(eJlQ6tor-m)_T1{K=h5Z1zNC-0>mY?M}eh7yQzSIZM}F9aMRCi))7m}OUq zaT(b~hg|wX*TLolOr)aL!MC#Y1@ZzW;2}v|Xyu=ih87J#XT+&dI;m*7^slYkoQX6R z-kP!^bI3j9Jtp|b$om2b9@kUK|MpjyzpxnlhpH%IW^yg|>V#Y$F z+R355j@fI2Z@D|G;und#v)zsN@vlLWp)2MrfgMC2DSk|1h4#eLJ7^Gl3exaDNTVI9 zU*5-89Apv8cp6n8s8pNCRQFLt05=S($y3vwNKZ^@t%Q@!q_%(hzUR>kdTTKK$z261 zd1wJPeF=Bo^Utm@tNi#EZAINd3oP)!k|jQ@HKGKLWhwGbKNb}YD`s5aLUmxcxju5I z8Tp&E(0T;&fU;0oTyMDOPH+` z054gjD=p<`bdcFX@Ft*XFRS42M<=jXgV8ID%`8xHmRHNI7GaQ8wW6m z5I`D*!yPRBWMeRwyRF$Tt&?=e!Gw$gI1?(cv9ZxlZK;led~llc%SCBaL49O%2+NGa z2)YKD9agImO>#?go@a3lZFv`I5fSQFEVMr3sgP|)*y3EXbIfvLGa84Lc4lJ`sB^dthMeO6#l%BD>EGYo9oJ8A5np&^rdgzNXAU zAa9t#i)RC~=1r`SjliQV4Oa(!4-;8nP5=rUytC&{_+bs$oqskW-jg5_90Bg>b|zvA zhvj&7(^8SX^Ekuv>U0wVK2~4=wL~)o^opq?4ayDRgIe@;bNRC27#=25wh)I|!8VVH zoxALYtjmv%3q>pc+z4-NuVo+Xj{1<}6-xqV1u7w0*9bOwe^pEaZzxV7JR33Ru{CY;xzs)E;-X0^0N2?Nk{0sOlRclaSWGh`0*S~ zMC-AjWj=bz^@=>R9m%k}-}p`a&2)Fr`{1;)K6v9oq3BfYU=urA*cRNl&4B5}7TG!a z(_2n&WnQiRmFtCyU&UT;w!%iC1K;c)`;Dz|`brU%l8`}Bp zaeqlUyq7vY5=H0KSbWFjU8P7x4G*}+d{>XtwXPP!Lq&*)bPMN%!a}w3C#p(x`4*@t zdM6~%)nqI7DUqrnv1NJIakt$kGisvV8ZL!S%iDRJ1o_~hp!~6 zbpp~D!;iRhvdY>Z+YG7JP*GRwlnCC_>PgSKvDRa+ zr?4s($0V5qGb!q*v+7p-ySHm1SjD=WoWAET0jYcKkG;%bXr)cP9R>^p-H~o)J4tGUBJ3{I7{${M06r+znm>J zPMiHD<@ibd^?k)*DQLC#!;&~sV6n@lws|fYxH^GZUYRmg3pMJ;XyQt<8kHi5UVvDN z1KTbb$`;E)#2o4yznvR4U5%^OKXlSBfs&*@THMr9IweET22Z;+LzZX`%r4hI%Lb2X ztVCbPn=#GwH09TL_OVn>p_^GfV&N)J|V4#`XLx zoWsJXjIW%V;^EIqTvQx+0saiERnRYb?zun|?+r2}Md5D#sKWet-AU)&80y~qJHoV| zn=svguOpGqRDV-Da#-pezCQDQRy`4@grbJEEswtA&MJPrmz@bxiqUjv73j6rz=ZJL zvtfw5LtCDGr(Gml0O_bfg$cZ_?%uf1tub~Vz%CQJ60@X}8x|Jz_>;%7dLz=82&W9W zIdaW$PD1N&JmU?nynxEyS!`(X%WJaFu7 zUguI#6`BUBn-rNKh4t=)lp=P}NY4IOJ|_^D5KN8rVe2U{QU3BYb$EBq@zea+3!;M8 zaGm;GLCtVh(Kjuz!+hD89u4Ikd8lc9o=ET~lla;KEadlO)$hNQ(DJG+!8L2&1Y4fU z$Wy4YeL`YU0+H<4Nh@r5mpUGv`E=rC`L18vCk{5X?oqrd-)@`!oQ~5A8gIhGT3*K4 zG?#(}evKO2a{e^W-}{%_ z%Bj7ovur;rD2f&Fv{^;wXZNw-(AJoyN#NeBHX@qledhV9zyNSo3{Yu06%N4@GrUYI zcCP0;S>AnBtZnd$K}O~!|W)hIQ^-*6WdwUjtJvE~CiI0JRal zZ$_!RP2ul}DsMNGY}|7QZYTMC6Le7;gaR_X_=s@)s(k1}cq6+&nr3Zi2@MhyOJn&m zRmI)$Fb*b|CqaL&Q^S#)fmd65Q#JXuHZCXCSZqt03+DYCMxNv0Pe}<}kKtlo+wBhx zG9=xX%mH#Q-dEmyNE*LSO+}a9^V^NA*cS=5=S0ySIm8nf%dvf_i*#su)#!F`>W!|2u4SKrPp-4>1Lk#U6H13 z>o*qzBW=-_-$ydQPv1V<>uOo$-V#_2-AR3%{K)TmRB+bKQDwYrif~5VpAFOXnR@?K zLYF=lTE)hCrq#5*d5|Y81nr4S7=lZE3J?Io?Ay zK8608U3%4CMq)Z(HW_=p%X~`7CV?CgNeX@c1MN}?q$2a_(Bi|P<2>UG=cr8}H8i8X zZ)@Hll>1;?Yqs71KU#8SIXa1?YQ^eDd)U3b`ptNXNkh1UIb-)1(1Cbo6x~6~QL^e_ zLjQWi4o7y^P!!KszV1Vekuo^RxVI819Nk3hj`}t&`_rIk3FY`=(MeXOG_(wUTmiLr zs7MLebFd_zyjrK`ewl)0O+c=zS)0m58TZv@w-j&B_ILeh$yEL5+nb3m6Kl)fHoEz` zcvKzv!7sug8yWA`6&US5!x%u3!i$Xj@0bG3UhccGf8r7CN+Q7AdgqfBnO9YEB604u z8PkHhV=dQTn3oXRGzR+GrWqRAWek;c+jf^jp#=-o09xP_Tme4ls zJ7QU|<1CBm%L7e&*ztgLJnkPc4HPqv$iYl;^ZLg|f@~x9;q0%g&zlC{Js&nhjn5>5 zQt`?LQ!vZ|N{*#JiotU3!`31FnV@m4-gT2&eWagi)$gNo*$D08^Ik7Rh8ITfq$Lz&ugp?Z9ZYj9k=yL$V+pO0JIE6e;S2}y${!YX!uw8`O z^9mA}4xXPf542sRGL;@0*(b60njCk!@<273NB^+e*VAF6s#H6GIQUEqf;XTB4(a;g zkCs2LzebAtfGOU;w56hXf#!I&V8#e`ov%n>EZ>4;+`>;=zJEK$6`nPTuy`;Dc53OC zW?A;Rofbdoc{e!Gv3jA}Geu*ps^XNby4wNSEXkl^YkDiP=nr~hWLyD`AP29?Qw8$w?LyG0sJY?SMAV zh-Q;2sdDBO&cFqkc`6}`g5d|{bHX|c`R6W0KDYf%3U=BhJ!zU&$LE_jX>gdP3xIHgUlLnrp)blRGFfAa+x>G?;i%3Fr-@a0i~&4V;6{F|5WItKhQs@BVubxQ#Y)~U^b2BkT4iPOd1 zj4TPd`TEQeY9z?=(rzA+osuFSq9(lqU@CnxZNTX0y5qtj7@BIoOK-GESL)V&`;;X2 zN4Ua({yQD>aTi?3N>OQc;mRI;RKLeJ8L!!TH|O3QwDCv zS+guXom^qZ=5bCrJ(b9?G14se(Z-W<`*`o9Z=vtjl{w1JfN>%HVz~I^Np0uc4m_C1 z!ypAKO!^J+&^0s+Rh2Cym@O_QEs&Zjz!{e>Z(c=Lfg5MoUrXtNcoo0a?mIM;fR{6* zxrqbs%CUT=zB69y&tCfBk-f-^Gy&}77+iPiQhPub!f91)8zq}=qjeQmHb)*Wy|ejE ze^p0bOJZJ{_$_B#sDLY~ph!X0(D*w4d^>povNWMYwC(pTzdlFO;UoFivhgy1TXQ-isigGn*89p}$JgMJHtHzBYzOf--%o~u#M9atM>qgvuJKuXtX?U=6;I7^)GqQ7m6rLrX+_Vf z&0quo1FdRlwk1wd7u1yf_Tgl$&1Aq=guiM{G;-zT9RM)ukPfApUZHsGG zxM?SF2T!iv`<%}Bqcfbm9F7gwH6}vid8L*5^p78pR!0UUHqIyYZ^hRIcXCbS2dcR5a)r`2d+6u2zS;E}v2d}uzFB#OogUl*Kp?$7trJORCH0@ip z@bJA#vDxP{v7fnmhxmS`HI}USKQK&W5je~=^N9!yjr~$iU(Jh!h1dR|!mWCd@A3gP z()~+S_UT8wsnIznoQJgNsM@d}%bBo)M;uuWlJC_Y>X!imEo&Qy`aqGHZSx#PArhVzktxN3%snj0jC#lyZZkVB4b=hV658tX? zjy+0=!C!%(ubZ5$@`O|ydX!f6MFw2=<8suNss(<}_$N1Dk@3Jn`SxXE`NZM8yZ6de zMLCrYK=r4cV#B?w?FA~GqpQgjY+_ZTt44sNK5#gx>U=P&qIbC}?2o!y$#u}4enqiom@ryBx~l9?wfVwnV^>hKXy-9x zU)?l0C|$b2?GwlOd2zhbuP=SoA=J5l4o;~gQ0Z(x*8wfkO zXYq+GeGf3n7|GNUPU%3OWw_-j;NP7LPD3X3gVdSEx?a8samsyNuU6A_+I_s2ZeX71 z{-jbj8NpeqTQMCk9<2Q|&M#QOd_;J@N}#~HpeOjeo6aE1KX8D28%v-hDFTY?$yW9dGk#>D~NVV2C-%rVjFK^GH zB1G;6JDo}5p=Me}j)Q$n-AveocloOPQrEfuEZ=WulShZLQ@=#o+#;KO7yMxff2Yd9 zFU4fCylbcgBIvh#_^`!yKN&jb%hTj_)MqLxJmj_6nfuK8X}w^XnnI+KsayK%ImK)t zvV#?UF84=^*M(@1>U`m0EVz|pTHwj7;{f&R=LbUEhY_&AZ?{=rUec>B*u127AyE-^ zcQ{t1`N$G7_ z#x$x2K$seYxVzXh@N~DKQfqGpx^S*++7;or$Rdvvx(aGqbEA(zG%D}4`k5xi$2t2i ztg>a)A2>gcWnRbI69~JbBZQOBbO*ZQ(_L(!PGM_rI74#E0 zuzg7{%%I{mlw1^Vcs{_!jG|wGBCs9EZ>IN|U{R4wJ#~oU%*Mu?#U0olyM@!j9X~-= z)-lW^1Vzf zfB;7bENrKQ%dx6fk-f|xm=pf_t-(VdG>zuncg{52+L!|Q&o+da1Vn;;E16BlybY%G z&f^uAraMD5xja{{xWZ|@XZB=3yIGvqX*(nDUqMNn`S#Q~E^I9F!pHf8E`PNDqlGqmXrIeV zD$FqZ@DABOILCB|qh+jKel6msB6|G0od1uuVP~w>F4JzJ-HUfR+CT)_SJn0!f3t&3 zGHYn2Gru7`g>zuK_kzT~HVFR(_bxxj<4c>*qJPEOgG1Z7j#I<}-4ZHH>MZV|QEvt> ze2R3w{Fsu%h<1=TQ2zV8&j8o2$-)y3Ln$xJvntGY1p1uKES;yj&qqu=Gk31O7@H;)qq8FXOBFf>nN`FN$+-)!pp_F8$S>15jrQ;%^AeHt*+@Yho+?%V$ zbWV=HfVGjqI+3SgdPX#(w7Qi9 zLjUiA|9eqTM2hWHW0(r#@g2+v{|knh5fBUO?1&prIp+M{Kj`gBz#`E8o^coV-#G6A z=vC_Vsic1jQbHATu*TByDgKML{@d8~&IaiSgqU%iZv>^ECPgF{Yb-X0;(rRD-)StF z`Box}@;f}A<9((+W2Bnz_j%s28KV>st@rPPga17EyD$Ltq>9%#9<93g9)8bn5&LUp zQ3($LaV;ff-17fQ13XFqyGD1`^SOqBLIPe_xfT~@7$&b*Db$*2}=v6p&;E@()`9`m;)Ow;Ut*^h#JB_ZQD*J=ETm#n%H(GwryK?zH|Qn{^zcHZ?Dz8cJHdE zs`gX6S9k5+kqUC+h;VptARr)!k`f|HARu5Of7>}QP=Bv;tC(CMAPC}?!omuY!omOr zCwntX8&ePviO3XnXbt62tQ>76NsB-j3E0j^r6OtAd{LBm+GQ9?K>k2HipV)I8m?Mb zq$jL8iu&>tZbYjtO|66oW%3tbmlN&rh4pE+V zQq&c6Bne|=mrO__Noh`_2p9lDps-_b^Xx>!4Fuu|;I@4!Z>|R{Dpa>ow{~TJ)f7;n zjJ<#W98t_+_TPCT{6Rq&cce`rK~Q}2HoeRORU%6TYyiQqLiDP;^xuJsy9nQ_RaVG{ zoB^BQAQ?k@qxB$v?83a%NciDzEw+M|RY_5#LH>{k6O3TrK%j^V@z65bhoK2`Z^z$2 z$}jSBu!eDZc2pWxR*O>XE7a-y9M634Z`$*h)~hz64kIM^mO#&8YNyJC5nlU$t>TgBq z#|*-Xgl~z&+oBNi)CdY|5Mv|bbAvG-_JR)gi{cIl@vQF~3G*~cz z;W~x$TOo@8ypC-^##2rxc@?UG2FuYX%*G_j!}OC4A5TUaLDr9v7Cur=vQ;lvWi}M-pwF5{C1Ga-5&F7P>YCbj)xeVy-yYwaR-bDI1&sb zeO>?=_yov`!206aJiPxe^FC1I5dka|Fzg>@BV?lA$pV)k6c9c`Bw+UY{Yc6+NvK0! z<@>cB79dT^&EQpuIJcPxJOOa~eOquTX(k+6EYE~i16v|T{W{J&3RAun#=^3VVud)n zrY8uRX#ElS0}@6YGpOvn;Ew)0czVG*4#U0S6_uS$a(2;w=0sQ+z87;65y~BMHHasvxk0DyIl+LCP`p#d4VT^6n zb%iZT3S%%*OoKbt^0rjA(}q~4^4;h0TuU)KT~1-+RA5aB9@%frx>M{#YpoV(S+G+j-AX_YD6R+CC z4N%*Ej6rbhKNmH-L*j;|Kw=y3FzbbWBdP1bT%Q$z=TaLRAXNr}R}K?;fcm2#^!0e4 zz@rJ$rbD&U2c2m`nFVngkWfP&7*J?Hm-m>}BA$bJ_xk;TKnh0RMreUq?R9m)uFkQ$ zMz{}THvkbtK@$?kiC{JgTqd20;NA^}AT^Zuh89;udLn^EDu^*cu+LpYp!q|EL_2|N z-+Uj%35+w&1<;%jE`fZD_7Y%3jrd()Qi0nA;WW5@hWZ<7c9dEEiv_b*5Kx?MM#}|x zH6llVv0!ON?jCnF4pau-*eEp}{xI0FR)ZdKe86OxrxKx}$Epsh67q9ey-uzY+dB^3 z5o)SWcN;EtAjyF*CvLhwZAbMP*n!F)sy|4)>-%gDmTe&AK>3W?5+WHw-zOtPlOI$Y z>=5sO$0xfH!Y)FZAlXRe)nCe-k}jJit0T59u`bRdcMfnveUl_lWFF1H5Qw6cHEqWB%?_0ucvRZ3cVTxwk1x*%1_D+pXo=#J* z_J^r6-UX_YwUh7@_3 z?kRrkcNsQ%mP$4rqvg?obT=6wYg%hiYp!STi($wL%p=TBL@^njm=5mEqD7HnZNi_j z35(nr*FxkW`aPySf<4tC*`X&{2Xv~WNJ>^&wu~&c6GBU-S$}eWla-MVva9rh61kF_ zk_Or43_X?$c2@Rirlg;?Ox%`>)>Ge**{0d_t^MXZhJy@IEl8R)tQ{wIkyA;cC&x@x z>*eZR>17$n7%)?{8P@2bE6=MEE3q^$8rtk-e?QhuHR@S!SZ$aa8?yGA#maV05^6_P z#Z`^CbzW$$HM>2!(YQrl{5;QD#b0s0h`u6Zi7mw5X)@FHs$INCt zJ5-71>^5PpF2AI+bW!cTalbLt&fsM2=zVgzKjmKI)_o}W1oM=BHFJJrRC%Ydvn*?D z@5#bL}4Nt@47PFdh*lrgY`-xCdHs6b1v4G7f;vnF zo1mCbL2BS(k+a2gr6x3POPkSl9IE+fC3eND+s?kKvuK^{&ns$^X+cbmN5 zw%<&XPg9}HMfD@&oBQmbN|K7Bl`|d<1E;OH*4KXR=ozKE{7se;*TIm=+b>b&X?fO+ zRPKurm+X^{6X;pk6PlCuIsRKC&)*%N2zFw!V#K-q`qTcDFj$qC_b}ig6`}Gh;4JFq ze3O5_S&|mW;LubfyaovzQ=UcLOdb!p(^xt*b$m7Sgr67FX2kR zkK?(drHiv){9ev(-%J$i37tgvR5x`DK-kaIFp#3IFp=TG;Va;`CS`Iw^CW5{lw2%R z=PHXEaxlWNzc}!7Cv!KrhMlJRIFXO)kLUM=oEj`6g zM_m7vP~vsJvUfuV&%@g$Og%cbD)Q>&%8oi(i-qb1uZn1O_o|HA5=RDW+m+R&vyvKa zedZ>kJFio(!Plv=<4*T--eFUzq#fztq`$9}pV8IJcah$F;Ra!B!NIk{YG+|+&U&F*zl)yuj3 zmb35lcA6cvE~U(|;wE%`UC+2?rJAmvCgR3+xV-l4z6%FF>sYiMyVl(#9u)_7dw#mr zPF7Ui)IS{@x@|qC#yS#;*FflUI)1-D&9Gj##;zIGxoSyp*;|~XVdu7owd3u~_I?}8 z?&Ah`$6hB}r)#hA?%oYN310Q*{Iu3DRX<7y&qrqDmGW?Dj^27WcYnDeZkHySBUb0B z^H6%4|2Wynxz2gyr~I1vka@MqYrdE7|sdMYc z`EINdFMVyxZe|8Hn_k6iU3gvHeV&IWBg;dX`H}lpzVAQ(I&hvp@(%V44pz#EDP4s# zaLCKZ0O?qV1>wcKBwPi}lT*vRQwb`YE}@0^L|4m&RNaN_nKA%L!~#J2QTTrG`Rk@|LJBV1^i3J z#hRB?LskJGZ0}?W_zwIAWFqB*0{{R#P9|ntN+M$a1^;`;OKRcb;=sko=wb8>PrGO;kSurU19U~u-db20Q_uyZE+w~_z0BVy`o>}2WSVrg#&_{XlHk-e)6 zFDdCij{f)Y?>J38EdR%oo%4SU>+b*=|B)~<1DP2AUoaO-v;Pn5AIZOA{~Fi7-SPZm zj7!1N!_-Do#M0K(&iQX>d@Rf?JpXd@e@Xr)(EmVc{11|ygXuq!{~`GgiYMC4y4SN>yLIe=AK^au02Ss^$ zRh=r_p%TterUy%<$-m|;IYUb!|1tBA_P^~0mNS6_MdWdcERX?k#t20e3~y*OU3j#~ z8~zL#Dn({*5zm_W+09bSYj>>c7LSldP1$>Ev}*qko*x8C0LAhWX_TN#T@GVrslktT zB|d|ylQd{QNzrkZltrV5o~7V)|JqZoSIy^CfKXy8nTF17tYE<8NJY97FI|PL)mIf77Oc)6&9Zu#2Lq>v#%RypK5wuA4bx%#MJ` zh|DfRn=rTC(7Q`?d`98^%K0Go zu1Vrbz@8>RF9Fh&xrdDcH91?KyzBCzSg+Gdh>-rrT77;M~Gce@8413ylpX`}-_yz3Td(F&&m7DJ!!NdvGD6 zi42y?^~MPJ;;yuJW&xd0)fJ@5qcGKLrLlk+O2y0|4AOt+F4%(|V5ME`=QelnDUSDKVvOIJ_&Jyswp>%HEYIp{mYVw^| zhk~wMWL@HOMa@GLVdvxiMENo1_yA5$4t7jUTLca^?tFKSrNlSc#U86#?l6H>MCY^X zB;Y(yP{wKVysR#*i8f*cR!Y{%uyAN?9D}C{kJ3W2jxb7yj}Jz-QbT0 zv;Thb{Phs1krZXip^3yp^DGHIOax9#OPGjA; zF|cS4thf(A#o5`}9ZXN94HfJ5u`wk3dQC>@=o3d!{39)K=r0XcsF5)HZY`nEq)KnZ zd9g3V+27Tpn;zMR4dJv@%-k6>E2YLE+vNTH_-}xbkEB|RA zMVW@Pr=ZV`&YEaW=rq@JO}Wgy5qGEhfycM;CoBh0a_1m(W%D{tOsKC#75njv6z~~A z_c>nGO9CBRER|SA%{~4BHW+~Y3gQhr90U0~8Z=L>qqghMx(vzZeU@r_>pQ1%!wJgC z7^>^{lRSho(ieco=gVl#?Maj_8oV9!pdh|ew80 zdo)7g*=uv!&dmk+@)mxQE{$T*mLvk|ZFEfN8v57>8NH?}l{YOz%iQusVh%1@brVH%lF@*tQ>;=s$(suBzJ zy6Jc56)EK`>dY>Sq=Dbol$R(gs5&-Y>iqPZ^gBIsgASB&z7gm!YrV&|aG0m!?Wp>L z=ebQxK4|Rkh4r6xeMT#}s^kps8x+fg9>xRF5Vhe7nOJIRVOpB5L}q|^j&FNG9%Mw= z<~{LrVJ=Ss?%(-ng|R;XOX``hXcsA{+7k_Ifd^HUHor5}b&HDE!XC;HG{nP5Y@L8G zUWdP_5i@}@+`RAWUw=5N5o%WDpA4s1&%X|t^ZSoWbK=V3O8dF_BG+OH=IU7}^zmNX zB$cOMtu~6=Ayth*AQEs@&H3IrpWpxNjs<;BJc*3u^L}yDO!WYRn|wh#ILqhaiws0_ zOd&s>T7MqpX|+0#^Zd9(MMFm|;E>s$jVEhlq)|nCBuFM3#Z5#AHL*i36#gjE9mhFY zY^x*S%K_3YUiBF1=@*X|er@vUv3%CHLCD&*RM)^y@9JjU~>y@-u zW5S;+^)j9lH9~=JHz2+JJR`71T<_zdBQew^-DJzz0X45>?1*|l1I@t7`h~NJUvUo+ zdnOHuU^D_6CmDu#G@wcfTKHUg^hsuS6ul6$?)!Lk58e>pC~Ri!S==1dVUZD&V=4(U znyoT@uGgR}5txbht~L1POl(rqUJi|S_V!1eX!t|+_;YTJS3|FP(%{pomoj*gZlezX zYZ3m`?TXSr=;m?kssT=ILXA?)*1*&Bz(F3c^t_CqA5`!M`oi2J%YwQlV;zVrjx&o5 zhx9p;yi=|OMkC;RycOHYHlvV%!Qk+neebGU+BsRFu})fC9_^9*4g=Y=!=gxRa+5;u z`#-#)qWD`%{9hcJiU7d3rlFQrA{R2|Mr=bNrY8BrLuoQb^@XQp>@&1d`V@ZVqH; zn@z%!K$0nJDfoIVfs2_sZY=y0wq=x+{R3|PqLAADw<71`%O%S_D!@=wj4sSu!pM#9Rpda$`W^xjwEotuc2 zURe=?I|L&zdg0-zTX;CPpW{Jr2yg+?j|3@in_rTY{H}=io(2M_Nr%Z>OCtlVnIj$ZvATZ*$bvkY9 zX%bSm@mdT)R3OUJsm-CdZpV^&lvu|qGb*8-@W$($AUq)>l9BGnG|x`Y2={Xt!eafhDu6n z^ArxN)+o^ZHR&>AOQg|>-C07C9aZ$@-A~rrA|V2{DVb%1a&;F%+Tf3xrMh zxU?W#ZK;-gc1hWN`sCjWe-+y4>4FZ!h;FnCD2NnxhsSGctuma_u4zf9mGENiNfo;f zKPGECS_Cr5a${G@_(BYukbyeW6V# zmO4@s8 zo{lcJXow;tSa|K+>6`X-T%d)E`Y0rKOT|h$@lv9uMEAa*pS!Z;IYuCyY%07Y87D$N zu_3-+z;`vQ#w*VvB;5%(1ki#_YVJTVvM!eE8kt7z>)^1N?@N_LSG;>$a9iRLQR{V; z=_@7>$WJCtt6e6L;d)xJIHgkI2V~{NDw5m|jNl0Sgu({FpYB#c?>GF0Hg%{7yPc_( zL&HKVgNYM5ezw_km(kOy*VgiAktoV7wUM7rpqH0_@!nFKZ51VN!6R~NYmtZzN@6n~ zM$KqFYPpAfR1<+4@0BcrK%cX29*`EsshSv`+DAgz#8J0jeeRQneVF6hC|!N0vXRr<8n85?^ZKBA(bqUAZb?0evy z!pha<*64sLBXx2QjLm($DPmp8B}$+O{B+I;|2%^g68>Q=@`pg{mOJpa9^@VE=(*Pq zB%~RAe*vRg0*zr>Lt=_VeieQVS?H?iS&ao@_x-{fX*9Ujjra?i<-A-W!fQW(Np_Uu zR|KM}`b2ZrW)2$OaVcBQ=WAra?#l<0{HBI9EGGU`6NbZ)=q(ns#E(*f*^K_}z+3aq(&17+}A`OEQ zeGZyYBBiS1NMgtps)K4F%u+D!39>)BB6+L5wwi*!fB^Doc-+@ z16P2>-=UZm9?dIgOvXkj^vRr8+)>NXn>U+%E}_{(VcB{c_i4MIs@O@6r$bl8pO4l* zjVZiqGSv4V6+W_1qMiTod@t7ZmT&(sTb8qo+xXo(uvUwV@Td6b@BUqKmT!46TNd+A zQGwz6ombf7*!W1JTVahUnPE=~S#Ww*)?swaHxFO7DLglKVkd+kLa;gFy`y+I=zzEl z7Nwm90zT%4A|J$pqi^wU;|HC^=4+H@_Pt$lVo#QIY55zZ1Y?7QU&n#s`&GZ9P27YM zzl9$spKJYCVu8(Wj+^C^1J4OL>dqn~2Ck9C2d_|B9t7rn+5w{$eCaC`axysZ#UwXO z-x5?{K^4gtY}N{6!(K1u%y6yCD)&W*97{r=8Fp@>S;U5{6=df`ZYBc zLyRcA)Tnq1P0T+l*eM7BU4FYI(iqH*CjCIqy*Ja_{v34L9n?vo1AFy{1keqw(L49p zWPJTsF()VZ^Ca%UU4jOgad7`uoHS2B7I*+QV+<IZS3-L!Sd;n3t~GOF*`##G?W==ExzO6-aUkr1r`6ulaj zXG4fZ{zr$$NGRa`Edn~d2h}#l15wH$HcRkD!RQ7!7*#qeSrEL&R8B$OP+p^Hap0d z#7%~xJ@gU!ZaHHv`5J0SxJ|0M!DFDNv`tmA^Ax6sQ%;m@_dX(WIh+Lj__j`3N;8xM zX9Rx>b7q{3$Ik)U6W1RP^SF-m@pN)P4$*lXy14-3DZ;>>8u-K*Q zy_<=<9WN1qg>>K6k>M*3Sa>x=UZ@&%|0B4q(fC-yh}db^q3lgVybXOJUuS}1!adC5 ze3MP**TcWIjLRg-hRsO>Er&Hil4mC(%>NygqVID~$pNALwS{)KwLmh5MtNWyJ^tKR z#fOp9&=N!4R2vV9l3YOycs_+iXKu=)%xRcr`ZZe|XP{f=%CYZmx z0ER>;n-XaML2jLUlWb>ev`?hb)O}Y0iB@4^+?17o^zgFSuR+7vD~JMp1-WEt>s5UZ zd$00fAQ4*vQhA__R4NHrjkw6uj*Gqob#O*9W+7hak!J`SU}vY{1@B1+YR{nFC6}#p zD@D;i0dZuddf?TBtf!<<-z8Do=1_r#7r0LJmZgSJgo4wMOOie?Q66Bjfkt!F-1c}b zB(ecF?|E;PEb2lyf_kJ=cIJw960p@@Tcm2MeFgi zp#vT%1FLyF>fvo25ujFph)>E};v`<0aE?B7GUtXk(=S=9=_mn~t$@qjeVr4$L%M8X z9!%zT$h(V#N}c0c51Pwx)VB8;EBRzWTPEgGvE6&yGy{EAGd;}TFuUDun_;}IaKrGs z?Z!f+;h7$XJO>;{wLj+@Xav`=cBa9dwM9=-7!OujEl39?2E!bvB=LNhgRlQ=dI49W zyL>ThS>SB@+MGJ*L2rn{WlKpemzc-+GVs~=9#*al-0dZ`a=r=R4+$T|J?J~^7KIpR z;vekg&(j8U!3DNVHa*-$0cFk8eNcwxuS`29jcfZt7*UXoe>Y&4?1t4t{~Cfvtw%(k z1h*wC=68#P5WOMwberGIHY%3y2NVyi{gOpL;P=0f)G?gE=s&1xNgxjdyc; zS_b84x~%F`^tpLVhP>^ag|Gy@Q5Q{$gPS1!R!xUx38df1ze3q!R`aY&hz||=uKhUX zNUy@U$*qMd|JtaET>D;Qi$`i5S0tT&0>ejz?N)xocmjeXrT<$ap=_H5XMtIDb?7qu zVKIxItogQ^KCB)rwp5MQTw0+tDler`6W7?lP=O3t2>w{;CN3}bp%5HT{8*E}5aH)F zK5J3?db4Twd)r6Evys3_>=+w!@DSqD30F*~&WIYi{h^a%u^PR`bCScu(@nDX(0!^q zJ3$B-%UGDyYLv~?DNiSU3#++YHY^MqGlN68&FvB0donPyBD2F|4#kvZmyviP5&dN4 z{u@-M!Pq@lpn><;=#y`Oi1OnR44y+M%BgkV98_=ajT$icx)y@MKNxmT3&#+KKM4g8`lQHlnlJyCF90zGE;#tE95HZ`xnv@#$CK4f=tkr6$g zuY~}aX?VF(Uoawnm%5Gi%X@V(^gildI8%SpaHGeKm3CKxQeCIJ1kb1eBgn%>79?nX zQR&BCG4gUXDYQ(6w#0I1*V~oy-0pcrLI+wM=A5!zk6ung`blyfzU5z-QnLjy;IW5j ztjfk_jU+R)BaM9dX;MXU80;aK(|6aI8&l~CK@PC<^XcpS}n91d%-B-ve^ z8mWye&5u&EzsN-shUXl98&&M>QZ~UKPkP}yhWW(zg^M>d}}3C z{C&Oa(9w^JH+Hz&;tf2r_NkkhtIf2+LoITv(utR(c2J~f2?n1bgNka`;2a?&CE)Nt zaIzIP8xs_h>ek;=XniUVjKU!mdclSu-C=CeaMPG$k_=NK!p~y?R3x@%JdASQQs3(e z<*^os@rlFi5(RUd6k>XtjBk=l%JEy0ao|AEOVXdFJ=jsvltoX4nU42PH4(cBvHv(W zMG;QdkW@KlBG+PZtdHeVtaNu37+x^cq{B)O01LOo8;DnA`CCX+JDLUm9x-OtXW0P0AzxTosggy-BaGhlnm@cZ0`9I-X5U zjTj)5PjJi!-a)$;lKlA+FldTFN>W29b#VXXmWL#XT9uV0ACP{6+*xaWh074Ur!~IW zPi4Z4>$$0s$7bg0Gn%x zLJ|J#IqFYLL`KZ#RgBOVB!eohYFyB`_}!bVH#5rVH{4y48uLyf7^y9lO|)pxc#ju~ zhJRGsZjWO|DD0z$Rw@Ma^JuymB7kk*gDJvu72tiBPe;+^EG;?E*Lv2&Y`OGJ=(5-2 zYiBCIo@Vz3+TX5dVDJhC)B%Jv?YLXlU?k!FaG#4c-Zu&4MMbX zE5MQSB4ON=0m;z8STvKKuIKyfm8k#i6kqn91=kzFkX`9-$*1N9II1Tn z7$-af96Qi-dQr1~j;Z^%tLe46md*DE4KW*KqRG-MUeewD@h52USrQNm*ve9WDUvWl zWXqqvx237!@kv2A-PB5)@f)z_gUON>pzeA*R&`QuHcN~Vjcch2pOg=i_I-H`9N#x{ z7$Y+eOR-4?e!4w?zzLLtier{~3{2AUDM#oI0&uA0~{XBTOb z1Z<;`02Ot?QEvJ_*y`}EipD*dOH78O4bu&6L>O--1zX5bunEmX9YS3m=Tfi(Jk!Cn zl}UmQJF`}mkTle1Ya9#jC;CI9*KR+U!=f-83+Bqts0IUrChtGbg;rp|kb3rIo@50l_BzTVp~^Zkt?AyI+7wFyM&VfjTADsh8J!f`qopZ_stdSMTrZ zmkB9ADcQk1HE=_TLoO~9`sJ5oFg=^yZzkY^ouMi%^)Bkhz}67O&c4ug-(~b*zN$*u z#A+t}{w%AUC(|vD!+y)eilA8)%2p=tKRH*Ls|jnP#h`-ZgsxwI*mmN0x-jE(%@R|E=v`AS6tw@ zWrf(wE|;U>kH|FQG@C?O?^p>s`XL>el^4!HngSTZdv5n-{+=e3R*SSJODe}EU7n=H z2TS5L3A}*J_(0J!nLt;-ng8Y~VZGNID7^=t6J~5SI~;stTIhg~Z=<G z#?^#Mk`FaU;cyRM>GEyE@UYYw<$iA@5367Lz2~L%F$4#K^?^1we`DDtGBd-Dh*&DY zAdSeWXF9XgyaJ~uFA_dR(3ukPfP-;_K-ciVgkRYZF_#EeM2zFKFU6Ze8pi!Fl_OxA zxcNuCv{&$5n@{*TNFC%UT7gjTvXYL<{$Lk&WauqF0HgoUQ_h=76Hhx#8%u!3_R~>m zHI$$6!H=En{R90)WAJU#8vRApYUum{-3Q;RcK|=JoO)%XB1hKEN|Jho=u>NU_`yx? zB5bm~$u4j3zFgLy)!+^1EAQ^)$L#(*^!~yfTKos$sVi8AU)BA+!8h9&4U;v5i^8a5 z?0#(mP$8Z>wSvBy*{Nj6E^#Se?Y>2;>)#RV$l?T`FMv+%U;rW&-(TN0?rw%|GD2HR z7$bDiBKQHRIQB=pr`G!Qe>`lhZJ;a(f05} z`kywTUbzL}zwxzRFm8F{Vl?>f|E}>%qVnIUBpui*TJ^uervMlD6BE5fH61*Tdu&qh zAiB}`gUO%3<;7wZ%+ujf47RuB9Alq?aosC&Kp2nZGVzkd^G%V$Qeg3sd9qGs=Dt(o zu9|RDI=j4UZ|pM)#Cy9vg{2l036tmrztqU%Ig^X~0c}1veDvoq=z`AYkhib<^Teg;KEB`iD8~}fZk@?De$t-5abK%rT z#0QMEK)A)U+|9rfF=+C$w`9Lx96dy-PKzBdueTsgs^GQpcoq2XWwzdua@m|22(N#C znG@XwRXg;MA?K=$(in`Rr6Tp=x35~i?*m89B{;yT_*1 zAP(6~$eh@$mG|@c#QF_z&N}O8RnALU#>k52$A7k2RBFAt8=M6@SpBiF(KKLuyBcgf zh#VaRM4xl-A7#HTUFb3MPO&~}pb=ph^1UwqbQ(78oQIfXsYlv3B9N6!>b0Lr)>CLw zhtE6{{v%mLz(ygTw+o zt-(p(VNCl{An?_zHEaI{CMe?Dbjbm8jf$1_wv|bt-Fp!M8E8lu=41f2Q);SR6bSC9 zBB7u(QP( z-spsJ7MKU5eG??i%?*TXFlNP_Ev(X+tEr0ddIB_+tQ+FxZT|U63rf0M_^}cC8qr;~ zPC5NqE9bQhfTFrA-hS?ag}g#0>c)E<&>G+4pjjn~S{C;Ht$gCcWc=&BwGy6+@kSUbZivJ1G=$9AQ0S4(?-j03(0dH{wEJ z0CD+uA^7MIefmU+KPAoX(JAIv1g6+;#By?J#oK<3VR9*fsLtg_N7=UZ$OOYT!CGZM zCTSy#E_1r1b`3WB@gX>{uWpDLljRr+ij2pHZg0zgPK>AQcvh&L?KoDb_A;8(-Ga%p z#CzFfAMF?66mF+N86dz-riflGhP7XEPK&HHFC%GE4^@D$hXJ0^B*i&LS~do5c`rdm z8@_>_+>b^jJG@2N`g*ybY?aSPkf}~Riw#bc88 z+u*_?*Sbm#E`j>2r;_Iuf}M)F!5 zC}^|dUXJ~7&@b|zR@#l7af#3?7Y|XQws2qtd@CfjeK)7bTWLuYy^L7J2@o9pVhHN`H!bTr>Y zOlZYqGY246ikfxPZ_#S^q>P5XGr*$bL~0SEh+B|+m%JGeCosv_`dirF$Kd2<=M?X; zQm~4%UGSD`JfuAAZ7kRM)SGoThN5ZN*B-)_N80{q@YPTB={m_f?Dk6$3@o<%;=j%_2C+~UwLhiv=c5__LCddL1t zw+cyrLD^Mro)uAKDj6~pgBb&CO{@z4ZLCA~je;-<@}|efb#u*~VhnryalCj2v?sf? zvb2v7ibpWC!E~$<6Uk=lyXW#BDBmFZ7o$(C$mn}@F3dC$=rM74_wmuB^jd;|^^n6q z);n_0qFn-cK7wWaXdtoh4;0k22i#xpwaFh9{&S2`=I?u9d!?8TZcj_&`*Xxt6|#^GW$2sV`Y0 zAXk?;gn7E&SC^a*GFHxt^OGP8@dm3EQGW2onmftNz-JGee>J`wQ}Ju6pJr$E-Mlpc z@)jbwAtG$I8MIa8Lt0lXNx*>+`OY{mk>w!Ftc;?|8tPu7xNc$LH)xAB3<{v>GZ<6G( zA(+WC#03c-?G^QO=7|@93%mN$Y(7qaVh)uIGw7zjIWG^qSQh#8Ro65+-f1=;*$*k) zwo5y0StiYChF-fTcMvLU4(WVjLN+Sgi({E>p>OpGa3VWB6JG!U^+t$A#*F$dp;5V%}*@oMx2wwNgT45wt=Vmsj>h+W;5FUkl zM-T1XVseNoA`0(Ezllq2$xW(agnbzuqP0FWh|Xr08r?y<=EL|q z&JX0eB|;@&e~2OYaZ!0V=8)U`8<2`d*(yVI&V&-G_kJ0qkS}(i#VqO7OovcA*GOfb zJ^JoJjcOY^SQNNhdwRVW7Z3c&-*Y-U+Zu|gdESga)dE>t>feN^V3=S zF);zVK#)OhpojqFfZ*4l;vFZnQZd7_gG%`#_(UDg9F|?*Wm}HR5ZLVa(2SvmtcZhw zOq*}SSagy%TP&2fz)gw)e#2>}q)H3VW^=2IPJ=v`alEpPlw1Uq8#~fvc3uRsagR8u ze2FZ(QWllqZ(;#)drMX**izaa31;|IPggD;!y=P|c+a!K44DuT*wQ)>0X5;DN{XNB zKd_DR=X>h2cySI^U8!-~$kQvCKxps^W3iG$079b)5l|$i^*f_bPDKtag1_}GBgY}Q zuZU}eE5G{+7l;I0i=@nx%A;j*XXc<-9)Ndipp`?&p+QCv6GHi7gS2|?g#{Yt;RjGd zIE0I?X$CulPUaWVSdrw(g+o1_fuj1|ZqKKToyZZ;=ShZhWYK4Ro_plWqJzzOT%2*< z(l5_`)TQ5zxaxwPiAT>stV%_KJpsTWxa4~+Z^QSJA!@NHwO3UPiRD6n;74`eFOzX` z9D3A8e#r$NZ%2&w>`DT#%khVvxU@PKTlUcBmC2~nocRDepmoq+=Z4E}5=rQOfQWKF zYVZ_mPu@SM^etKE4+MF2*^qKe@X_uP^lVHsC^O4k0aE%OwYo0bO6u*{tuwyh>n6+X z{Nn`4juz8yV{xQy6^xO}yG~pLVM^D9R}=9E;YvkRhp52wfg?z8i&BdRE3d>MJDFjP4;fa}vu=tH?lY zVX<1!H9lg)ww?e6S$!Vwx8hkKo7SecO;$(Xi#0CR*5H}@=sE**%5%yA^YkPa;UO!? z`e|C)xx(jHh{r6v4icIuKR>(P$u={6`0x=R?DA)$3Y6H3plDSGQm$MBTW(v1x~+6_ zyWX2@Q6#@6W3gsgXo1Ax*BPE=j5pr`2g&8klIIb{PDw&%%4;Yu+6{tVB)H0!PztGGk_X`MSqG!B9Q>sl=4HIK?c| z5+D8u(h~7bDKJi9_byIdrP_S^m>-0bCLGqRn9pEuir=Y4(_q2PH5HmD%OM-*R#4XREm}Bt0tO7#3+OlcK=4qfZ)^A11JjLWS36m(*HCe&VpI@W z%!duXgErTr3b&<~+iwdm86c-<7%np*gI||Ow;A*Sb*DHC(Yb;@#`(?j`W>Dwp|gug zHnhj^>7H?DEj$n~g zO=I`2fOHXgmgKJJKh-?tHOZO@QAE;*5RwxQ;H43nNE>2iU*(&vI2eVszV93RXlSD8 zy3udC6?Fb0p9S5M+TKY6B&&v>!VqQDJgV0zO>(gTI`xW$I#rx}?Byd@eSAg(8GG zJ;fuoAAEKFq*_@Y{h)F7YML>1S2_VC z>M4)xRKv7TD${R(7gB%z$f)lV!=SmTXV}vv58F%!j;53K2~PY%x5lK>R8%{fB!obf zj^<|#v(D!zf_LgEFgrELc2e5i9Rb307#Ttv^;W+Vxo0Sz#M&&S)kG-UOpw${_f1Vg zS%ggKC^<>_t+dGdii3>Ga^x%IOb^)hsFze-9``1_VoMw9=bNk4ZlDyBHvMt1N@zl) z9=5`ltPierc2r{HvZ#?`I5=JYT@TJ;J2W~(ZUe1tZV^jINLq(3+vg~(6-TMCRfyjB z*55lt#Z=a>p>{dtCm~fPXLo0^LK{=TBlEl0J=8GUR1MzlQFJu9E^t~)q9ZoRz#jqf zEN-c`Wp!M>8uCk(c)9swX2d)Ho3!cCR^HOx@w2{&Sh$k_j&CZxSj41*h;W-g(HQKY zV~~05L~}B=R=&<<4-L)byhqT@cTt2uR+rca5;SxYj+c~pCnYxl^GeyIFe!Pf(@&KX z5V8gyeK0hpsMO_hf5;W=6d#w;(HWbAiQw;lM%gW9-KgTM0>4>-_1-2Zw=mA*j z!!+x&WSLklPZdhaG$CBHMuz8W+E6P6pw7JINF)2|eWE*n&%0${iiQhfYTkGofg!|C zmb(ni!L9)_|682%dx@geRBAZDZO=s=f7#f2#4Ug$%x%z#xuHIe(rC&SOc@qJZyGGR zRf=H9vl+GJ9aQK1W{T}FNrc80Pc%^bC$tb9=7rdYbat~J3&Eh%$+E6!kN;3PLD=PTa`y8p4A7A0teT%et=qP9@H}v?FhpO?@`1&XW#=uF z&ebu_;H5AkGh@SI((=?M=n@DUH$zWO1o#PIKXF(FzsNekGDT27BXstTD#s^_mU}Z5 zG|}i=UWVnRU`3D`zxNh;UM`0chi3Ud%n;}-kDYOjpP&-R8W%McZWg}(; z3LKC7hS^TOJ68Ya^jD(~A?jkk(-}?!O7zV~4G+uAdE`6U2}q%K%tR|q za_iqaElh|(oaC@X8%Q-TN{Vo^lXR(q0*xL(&h>(ajyrD3?+|mmb87UlvGG+%z;k|M zxudHI>G1S;cNbgKl1oNkP(k@-j9)1R^Q;j2o|D|q<9bymCL70MM!`)y(ZmHZ@zrIh zq9V9HTyplh`7aj<&8FjmD;)VCk4D$&VR=rZ`3{ttt#ZS>lWn)G$b(-&s*^Z@Y-jLO znoO_>g2zF)1={xd)^D^{d68t%JSO+E(p*qNnH#XKR@n434*4-{i38WzJ5316WFSlo z5hKuj-(o>Cy}Fa?@Jr6(Q6 z&}kJHk!Ugv5fza{R!F7QTXb~4_S9VFtdXw}+s`Y=5Eb6DP-M%g?SuK++|ocf9r}eA zfWV&Keo9!HbagNY*Z%A~xI5})E|v;9JHPBX#oi*(gaFnnEWur09O*rf95Cqv1Ht$2 zIpnSE@3b#5$N4Ru8?y;*jmyInla(~2tKLMge4uOo;|%rBdY9f4e{{eABHS|d6ylP& zQq@xn##Ga}+YOIHm&x_LziWsEs&H2{PCuk^`1q^7 zjEOE{`4_-!2Zd(D-q$BnM=UcBuwWuDZ+EcmA+?ZZLNoKX3Vh9HdzfjFIM8+>^4m+v_|fNhU;JJ+?mD8rA+!t{ zG;yHy_j@}51K2spJv)5sFYj%63%GSdv0RwPtB%PUMtmTX6Vx;q6UPXrZ_j>2E?^M1 zp)*kNRS{df6>WUXb-6=99PRa94cwj#D9)7|vyVWI79Wb5I8gy#i;bD8I+t$+50_Vb z+6}_WS_6E4CC?z~vs8caDm8=LiE4AI#l!kg1@6#$!;fg0uMu`(W$jWa{-6pUv!5KJKnwNU>-o;n>Z5n zHqZdNqvGZ4Cpx2pBCq#RmhEbhZu$g%Onjdk$p_!cPS%3E$uHDXxKTJRfn?y%QMQXC zAIT~&t765OqoSS-KT4V-G_~3~GMBqx1!!Z4ka{gTqlAJs9H7w7knD{$H z*4@Y-xjO!%GiaXRU*_hHI#Aa9vT?XcsF2#=kz);%o$oyk8tuoFF@}Qim~b=9%$U!X zgW~h05O)jQ+fu|~xr_{;_X}0e{Z*`>o>=p#wxGKQ#QT6@%8KlXKxVs5(R!kxmM1>G z{WiCnU?%%9AlCrKDq@ywY$~-KchW!fR^y9#JFGw1bN@(ZHcM=6dn(fp!{5xkJP{tj z_D2D-WNXsL`QS*OS`bfU%QnwH%4oEYu|8*+2@Russ;*NDt|Gz%bp(R7QITZi3h3e? z-tf?dp?{g?{TUTmh2J|~tUey?zV4E)!p5c$4dw(|Lb)EE&&*i20qR_419%oUf|S4b7Ie76V~>_#xa`?)T_8h?Y2>}y zsfiL?Yfbd^;`H1EWWYVs4tsAPhOeb1XG)v;Tc=silix00O`LYkNBnAFsEmu2oWlDZ zv4xPzaeTdgp;OL0MADx#AFfVbnyeDRl&6Teeryh7VB~s@Nx)*I-%Dq zkOKXzOTTQ;zl;G!aeD?{5Y{2`6V&_V57oWH8%79AZG1H3>@A3N!VT%Ny>`eu*V;Yb zXqn|N;h<1KZEzGqDUR{Z`lY_1_-Mc34QUfEjs~)KXCBmTKJ|JvY#FUm*xN2Yqc?=u z@wi`@qYqEFDdLEdrz6(|s})5q?vL!i18m{Xglh+VxG}+p9Z?vIN0g8p+h9c`17CSv zV_!8tM+QkLH(3S>p!ksXc9$up6T7zo+E|7M$%@t}YAXd+V7SM756iM)H6CoT#9^6p zta0dfhLHu_n6ggl0Wz z=t=z+_;ORSgy2AUE|a)7cLgTSrvfc0w0N8|$-T=5#1#_%7 z6T)fT5O^`$<#aC%9%sa*CGlZDb+qEF)2Q*i2!MeI~Vy@4;VW$ZhzMz_GhdnRmbMIcg5?h=o~h zSFn_zlh8Mhg^o|>HO3D@q`WAl)|LH^CCCFIb=V?SdDVNX)u!yEIIdEjebnh`{4>lOe2F$VyV-j> z3EkvAWbgx##vNL&NQila8_gU&i>0%g1->9{b>(!;K!Qp?5U*FlSzS``CP{8qytEMi zAWUo1h32YzZ_d!4y~PqfP+$bxg9LM;&oh(cfPDW|#jV zIgbXg(@20bRCH+Nch4U)@yp3Jk7YfPz;c3aF(N!FJCQ?LcwlQc`M#C*I2hX+Lr0a< zVBSc8<2E6N8nkQ1gXj%si{6m={g6B8g3W7!&DByK2(ZN!Id8s-U#)N*D_DjL>B5g9 z2JLQu;x!l}UJa;41%^jh@5gj7i8y)K7d$_fh0y>NLkTT~sLh0M2@upOaAI6lB_tsa zU~b^`)|ZW`yu>lBjBjm5NT9sHBoPF?eE#9UTvU4gX%R_^-#-7(UJRN0vz{;7fe8ID1IHv%7fv;9koBSiCQEu}+6B z@V=a3s|4o;26%UG2#T;u&{;J=9Q-*uU}sPR+-@Ia^2S%MbIL{5Yj7~k=Zh%bH+(fc zUe|>tbGWn@#lKh5Aa2FDS>74L;eMF_5-KSs4PfmN1|T+SoBW}Q5W4ava;Hl;~H^;)T$8P@g#i9x#bOE~0Nd^A79b&_6It ztAkZ`qIVcQM(D$w_j0Ed5|7F~#>*|2MiHPpbx-zl7`Ex;J{z!9r#6-GCQS}bOnnRK zD*AUYVc%kB?biGFiL0G~iYlbDgww;2pG2l?;;+c=kU2$S`=y1&OLOXUeSl1r1amK> zI*DR90y%qI0t*R`X62N*T|!%aJ(4hXpt6mEuewSL^u5`f%ZV z5CO2J#mL}DqOh`Y@Tjb`g}U@YuktHAzsBR53a40q?L3mD^B>O9$7t*IZM~&P(67CauuMm@40T(J5b4;v}&mk`yb}8_LEN=rNkz;#x`K`yC7)kF}n|i*1 zShzzNP6#(xRW)g!U(w}TcH)T`Yg;}ClypYw{*wSt@=zJ^Db7@b&5Ou>O(s|qT|_Z` zw@o-o?nK6CGjCKRGhgvvKU9xVM-*YjaV*DtqfpnLFmPVs8%uQABM)m{f3{QZnrg#` z9rkpjU;b=DEGF{wG9o#&vS$frU@3(I#nsf`vI#`#Y0yvxAV-j6gh1FA5_qz?554_M44?LW^EF=B~_Ce)UNVO$w(Wy1qgUI$C*Z3Kx zQl(?VNWp{)?TQ!kcpMU7(>J9Z)rAi&R19k{1lN&N=j=NnHh^(Y4H>`146=9P991%; z%PD-YA6ZkP0swS7I?y9SrfN}0)9;og3sGsXgBwslfiZLL-s+aH%~)-{`7YBaAYt$# zW3j?NKYaTnG#j8+uuzBv>G=|?W#g|1>UtVyrsHCDQ@^~Ws?>t zI&DJmBptVRZXpQ+_C5I}KdNbzy0T-EmHG1OgZv2HZ_KYxP~5_ljDbKLVro+luN~&$ z#VFVLdwf9Zr-#mugjxjRE-ypGTKb99S9=gZG#|)*d#-dx*ql0kltehEVJl`R4~1^s zs2j*SJB|kv-ChAKA-qe^$;8b7i(RTI->eBG$`|pwe)pm9w;8xHg1xB=>wd^*gyC>6 zT^|{2leukY2M6aM@EuPj;;FRkQKIb45Bz$+<}7cMTqDQ*Yj! zcWH1SBNhB~l~;sKYyLgy#$8M!%B@H##JrK1%r%c@qHTpuHaCStB{-?xnDS)?)7xj4C?qcP0(PwcSYw1v;38%!YYUIf)NrFXzHpJSxg~dVE(ZYh7?dVc~((D`@=peeqf5#g4+PU%5osfEf9_MDGbxK zu+U*!XmXF2*I2x2VRC+B?qv2xs}Y>QV8fbgqeu3hD+@e)U@TMn2m8aIgAS<&yg?%P z2xCPoDRb9`5gp4wm>{x@?(xt3-kS+6K_%o!TwF(>B&chWaHkZ65Eke1!}%+mt72;e|(D!K)syL_cXAHhLp=8s459I7?3)+?LX zX|{vM`RNj*lWct&YotK^$sR_uF%Fs`@}1tK?YZN=*V?t0I|riqcdGw@uzJ9Qfho|R zs2K< z1KS4MliU8oe0m}I2f$)_yTU1=QWHU0v}e&U&pF8UmZewdwohn*b5s&jU`3uNJB!3L z_2E(#WANxE@)dLSmNDH~^UcD?1Q+oezb4NJNeDZ2Y5qSzGIdP*7~qT%SmPkoHV6Ew zD4N4~Wp#YaT^fqKh7Yf`(H|p}2^3&5#A&1Gm!?6bTh&IMhek|`h`8efD{;jWtL&s%MntCMNT>$bOC5C zYW(YB|BI0}#Q|Y%H4F4e`kISZuEy#Z=`Oqk@*f)4KTq}$pn+CZwQT!iu-+j{a%jT{ z6dA+(=cW4v`$xinCRN4JDT2bK^PvT3BbXkI%5MBUxNDEzP(<{`Oe(WjT9{^EF3wog zZ|>`3MW5taA*%XB7<0P%Q<@>hz&X2^P*#ry#_Wlun}x{7YR1J8UG)95<`*Dj-UlFq zS5jwx#27Vg=k#m1#gs3LASdQ3=GIxg-b=(`!XUHg&-|Rv5#Z!`tZzmxbl!u@E4`mf zYP$9V5LM9rs?~j7WBMy&^MN}D5W`hT-wkgDucUz6cJ2=7h^gLuY<^n4`dGS74$dR! zKYe-2kgLyF&AJA=tiCU^$VMy5LvH>&X=uzyE*T1P`j}VSpFmQ3a5@ro3s{Z42H+i9 zyv_OmcsiZcFU@}FlIzrSZ@XYeUDH;<+dZ)i&sv;(Ozys3omBN(@j10QvjnbQPyePk zJAiI9T>0GdHjALHV-aWFn&6yiaTo}8J)XZf{yWs_|37qkWS)$Ru0AN$Q8SZ>CBM?` zKUT7L(C;Cn(I&mUae%(LPl+S+*HX&F z4GqJ;rhR(xJXfOqI}Cx%zGvj?3$fSgBSg z0z3p`bV`n`jIzFD811P%R>NQ_?jeT{Q{<@)b@Ug`XXZn#xAK6LuOv@SneMuv>4j=k z-{OfsYA6u20V6@M=ZpVxU<@1x=6c72ky=!VX`V7!bcc9`X{Pd@l_wA9LOLWs7=auS zP{G92)xFAWKP06wNjfG^rIQrkq zp@w+Ebr$Wj_Cd6*N8EI8@CLy0& z-F8*3y#jEg^gm%{sFqipt0&DDsByMlM}_$9AOLQEZN0gj@w+f=UO$t!no=4M?J+=n zX%S12J}f~a_q0cXjP4AA?Q4Gx>x2r&CWRMgL>C zb=9GNrH&RL#<=9Himv7s4NCd!ZCUTk?S6?zbUJGssVe7glvkS7RW|(kNr#oS6Qny$mjKE<0iU@t zoyvv4{Z@wR(zr!hzk2_e zZJMpO3mxP&qi^~T=g(H0^w5Iu*Hm4IyR`c2J=*|EfMNMVXNLi;N3<;=x zLjwW}d(&zrv{UN6mtQ$~HB1E=Ir(TY(Au*E;KRru;DY)%1%{o_o9H)LW6~fWtLFTT znliu-nQ~>*vZ_O<^>D`r|D7Grut5(H-CLCZuoQ;>NC`a;^7zBpeSVkTzr1k5fY!G7 zsR3Z(MZ*b;Mc&}@)TAQM=$yRPKCntJ;qqy9L%}G|B*0C=kBR1VK9VbP0BIG%_z_oM z)FPBV*CGEyHS|zkn0u~z%HLmemS~T#6gCqsbF5Fx=il-{-VL*K3VG6FGaibXlCr0) zh-Y*-OAQ?Sz;7Xtxhd4$b8mWFif3bU98m@keYQ9-3Q#Q0eX&OtE|D>$WZ)w(8RrmI zUfYMwo?s^=SP&dnkuLn`B7wYqxrrHupvJj0m&S9@+bUzh|IB0^#V}? zOzzT+l1AiTv3vmyB9mUdX@V8F$Kxjjh1gP+9>Z`#j9?y@P7DRb`0f5^LXxxe6Dhvm z$Ry~GHU(rPBzm~MKGF_>-(aCZ;`>9Z{@Yfvo(3hFiS@OG2HuV_MUk2Khdny>~JNM zg}878o5NG=Ipup8{LdH7CK+Tnp1S*@PYMx-$%6{RSJQ>|=|5ZTcLiTx_G1U9r{!FP z*<&&?GJ^Ew8*J89L*Q`8qp{h_D`8V|{=LVvfiP#R1QZnFrE{2+ihZ85q;uFCwMRPw zaU?loI&&rfbQw()BV`v!%my0)B(*?r$zIo8Qg2U}N+DLtl^XS;x?Y!T$>ZfJ6@_B4_^x0zC@3pb5A9#7_%8}(P*M78 zW!h#74tU%aB3II-#C(@kEKbr&?HThkwo`q~onvPu`E=1?~d4qLd*9ee)%9R5}E<5t}u24N<*R<({*WC8FnxnP6t884`N?*HUTS`u?!k zoQTfi;l#9-%FE0&YH0|`QQ2m0ms`)hg4b|e=w*hS+yNj-)n_V_h9nv`iEo^(&DKE1pH0*vMxh=O}G_pWhx}v zD!J1TCezta?Ck8`-!v0hEjcO$EDz97N8iVvM|+Bi<_a`8AG)*;#6_z*c^)$Q$%2ICMiAI(8C0yCy@6oK%1xPtWivwJS8{hwSm86q- zj?*=dv^ebRdps0UQ<+R^HQOfpV?upD`+igKeZ3S|@_3#Jatc9wUS7eg*R-=B@|PI> zO8!zkxT1}boo9mI#Oqf>RdpJdl#LxW3N zsmx`p=rcs;y3N}XU2eIm^O>Y3dJX|YB6pRIk`>HpP0ZGV`x$T8`juW$=>7g=X(Y=r zHF^`2z;V_-VR(?CcTea1gp$+}Jn>RcJuaD0X9^`|F5X zp1(;!#Y}gAnTai?JBwKb-}@ks*~jdy*5e-ibSBUHw9TU!dQp+5sN>>{Scsb=IkXCk z7~l4h3!r(&hLW7eM)O>{j zt22NS5nNIjlqul18oTYhNR`PZFaQRvTuJis@=^-x?d@HpR;}xJ-T6EgO5j5o3Xi9l zL`x&k%F3-RFCTYsbX3kaRI(zYmhc7Z_QP7{3Lp;6Vgq+^qM@NN7VD8lBT)pP{$lcG ziSrs{l^9^6%TjZ2s6~Fh&EWSfmY6YkP&%#%Crrs`r?{NvoXGI~`uZyWprz=)UH|W5 zM0*93kOGqYj8Kr8SEZ7Zn~jd)SZw1*QU0k%W3k1;-w=ox9)<7S`fxc9DU1M(vjE)F znhG|%>9z@tR{~)vd*s>MtvxY6uJ$K&-4+YsXK9GZ$I-N2Zqo2&g^A1$WswyJwbhXdQrC8p-CRO(M@qgb&a5 zWi<-WpZ0Xph+nq2SPWH&sXEUa(ya~S5Lmt*dcnFfNu}(-q2cG>RQ4q20>4hrFN@|F zt83q~HcCP4pWGc|f_}%wrnV5pq){?^5-qv>cI6D_P0LCQZHQEWSA+H|gOq_qf)tG{ z1GlyZLKN>gaYJ95UakR@%LLC~J}&E}?(FDm0I8ns$MVq|$PZ;O8U#eh1r-(-k7d|( zl|iM?$ZLN<_8rA=U&Te^aFjEC5K)}XNiig!SGCI$$$2q;PxHP@7j?T`>mEvT^sO~o zCBMt@eHM15sYyykj71*iZJ~URTxxcDHkL#7n;#_3q;optQzP`(YRB@vm0qlNiowzA zTyOil%M`H~4Z(W69;OxnL+na1{KZ2XYyLO9ct>y$=(zES&X7oO%&#hxhCR$y(qk=> zVw7L|Cga(_LDo$rLq*M{EsA0ia|kpwyUhsH3oK$e2%Szdv%b8o6}uR$WhI_)FDJ#Y z<^n7w<0^Cgr?Spj1vB?sYd(DAPrdU;Qf6kwEsu8@i}|)9T1`fTjdEfM-gs&X#ksMM zqT(W>`s~2Rsh9D-cME$SaabAmLq11}f%M88-2!Fs>HApS-4{{=!5yXQ*wm*}%4K+K za)Q4fu#u6G4;GholPjv)B=ZXj8teD6-CMjyc6tMg%%-#NCbqxnz4yFme6tY= zkpwUWtbvM$F0HC6GT{753J~<{CT!A8xn@rlfxI-@vg(o1J_T>Xl05Q6nw+c!G zqjBBywA}8)iLBsaY!sNlCO^eGRSeqXBSSdAv?t=twobYfS4?OLq$Ga!H_3Cq01Jyl zMa1Iyc?|v&_fiaAP}MZ$1$=>5E$4;IVFrr0je+-F-L~_SKJ9&ddale0H;P>F%)bsP z%ATyw$ZAz2!{^)ciOb`q7ZR0dtigHx)csdBLk&kNwcqXF-6=CfAE9}wssi(&uM{Z< zszl>k%W8hN0)6X&rk2@%55*@E$<6U=+IqhWFgX+yIz~N%geMmB4T+T zZ_|bg-UMnT47=oUy>|uG9ee)jCmEHM`mPNXCGSWK28i=={#C!+^>`97a~$ z<7_Wk7k(9#k2paFzmKO?vz%m#oL`FJ{o>-aH%cY4Dg!e~R7wZwR#gfLZEn}}n{6&i z07+7M)5&x)I0sZ_US8c-C4Vgx;o(>UwGBMai?v267arHIh6dI&E~jF}FWbfPj z!0dJRH~sU5Q*0Kdp&t^7=*afh69-YM6exG_f0OlFW*Bqbwopk-OiYBz-dtNRmu~9} z52=d~(qZ$7*w|zedR6#bX*HUzev;10M_q2@{p8#ekiiuf@+8x5d~t>iT1omuksY`|c733=|0~ zGRyr~g#ss3KN9Rdd3(Y1IQ(Kl#xtd?b+g_S-jKr>g>iBn{X-Hfb({iWWU}un?h9`^ z3RA7i(C^u(;>q9H-jJjkEqD-u;hVS~LJ)`4S*AAFA3|Tp#G=RBNh@oMH7^%FNH3DD zlfjX|D<_k}*21_#7}i5H7nmFJSP!`jh9n|^8qC#a)4XZAJUr{uR!a%NVl|u?Mhxuo zxTrQh5>KLHUo1z;Znve4@AG2N`uVhO^8NK$t|UJpveM<2e;+}t9%1`6Ncs9u;312e7p(VsiR^J( zgypzisx{R{zb2yI_v_h4TiMloegCqE>s)xX)~z6vb)$+sC|;}yMR%R{Mb}($;w!B!oz5yjh`!Tctv6L9 zl?sRl^3AlEFXk$-xJJ9^-Q5LL#B2VJTWhj87e?*6c$xd%e4&%3dQVWec^5-ALVS}Ii}61_DZZp7~KaVsaBAJ>c+7@5$2 zOgh)XF+tkLGvQraI3Nn2Z6SI_Qans;c+vcsez+&G$&H+8X0q9Y~g!s%)lrHCGCXWW#0J4KWECjv65V7K4AVFa!h7-bpjITdEd zs&ggp&CCx)2#2>a+=bp1O+Q}vKB`)s6qUBH$qay4X>kHN-@W_ti9jX zji`*A5AiJ#*JQm)Od=NJe7?nps6okb<73Tz!`pG}m<1;82S$wsY(uGyp)6eaa6T{N z^WhLH{XO20tD;@5P)QVq%qIBQY2-`QSYS2Yk1}M1p`vB6RarLi{nB5*6)6BieI#qO zaq&i5@SXPtHHv>m1PA6v|52qv|ppxlv@CSh(f!&=JYRMKj(g4f7iUMOU( zJ_*e_If+ls?fX8bSA%={*T?(o(e`zOu@hG~Qg*Yu-6(4tUztgBtl!sH9S3iBLoEi( zW?#&&#)G0BJKGhc=F-pI5fRyL7&6Uw3tEhWXmQY(FyEpC+ori z?meJAzLc=ZcAIUD>)k?lYjM(~Ezy2_PdhW$Q9&JBo(2zC$RWpCy7!O)Y3TV-&;d}V zRqa;^+*d9A-YE=vS05hMoSn%qx8U(C)+>z1(_phKE@#TeRu4;Bc3d#2pA`O!7FQds zvQewAE%0aI2%_Ue8k-vs-*G_Dar|h+en@;Ztje)a%T-L#G$nANp;McgXav{n9p^Vb z-v;xp%aaXS-VtB7N7knWy>0|=kJX3i71fF*+uzAtcGIqIHhh$k!9AKYJhJf4<-EC< zKmlTa63a$FZaY{CTA_~RXmuW6K&+Kk@H_u9bTP@OJYW7#uO|Qo^b1*6WXHeetAH$C=G3k%A}nbA%+1PI4F^_Gj& zZV+vagiUdbhOh;T`n&!o0g0}4K4o$Gtpa`KEY2PVoIHjQdD70ac{FzGO*YK-JNz8D z1WV+9q-=~w|^eFz&|JcV>A;&AjmEF%k{BQ z*iT?jfXJS6AzEA7jX;5oP-!fI^zyTL3qZz~;d#S5wc<@^-A`t=b%Dw-|9y@W(2?XL1(r_L1=ZtuB_PyDkG^>s0@JN|7g(m)mEBTTR8 ztHi~Hb>41BCeGajYS_cRZ}6n`neSCw6jmW;76f}y|B-r%*SCGQI~y8EPwS22^6fk~ zg#fCs|Ez*-w>fr11mh`nU2O9RjL`6$ZlUQ4AJ04Fs&6dmcVy#Q;sHZ+KHHhFTDl)z&stDCr*zy~YYf$%O0q>wO!C7~oJwu)@ zc!R-hDhSm_cX_*m9=qv~P7W&0cT2gcF-`0a;kE_pXywO^=6OEVS)YqR477^1>hDri zs}YM>Q>X6u;=|6ewbp10dgozP@eDqtx2ed7YmuJfLC_qTsA%+MTF!SnpIB!w2Tqk+ zrGlqQk5mci)HjYnhQG13wsdO*x4wKTe%%i%%vJhN`(rPM&yOr4V_g}t8LTJp&gD|c zv!}QxrOAzk>#zJA02Q?+G8n)V{t+XW#yogk7{!1ioxBy~{X~ES0-=fp757g8#CU+O zV}e2<>l`zV$b`uLlE2SWD1d>0tnf1_Az|+$xCY^HmycL9&EPjr$hnqUy0->n0vtgU zgpmFSFen7)vE|E8B2%QQ@GCCT1!!O#rXTPrlwph;*B`I-0_Wnf)SOQiVZh7T!Dw~J{>jwA zHg-~V#;43&=`IV6EKm#X;yO}ubL?Z1mt0()2c@ppBBMWS2;w)KsDjTiN}$vc*|Zxf zW!K5-kLj0MBn|3JriorHH)a2VG#VWxzENNAZBiv7hiaAtC_~HSAV}S zZ4@DI^QgADJhV=}JcNYka_*9O998)&9ADr_oUE%E!o-KeyezqgZuXbK^q=jPZs>(t zdnSs&vIztlkw*}^noj)Q-2)}!&nFvr5XcpFw%C=5IX4VnD0aay%k%%u%!j|t5O`)g zfPJ^a^Bc8xdn#DuM=!d;AT|elchE2B+u$8OW1$NN_)1~Sx>%sd8yUeFk;1=skhOMT zp4mMc6^utkS1W&!{g-f*19Au(l5rRQ)WGJVk#mC!TW_}Gdn}tZc%mlO&*}lIzJZgR zb30kf^lL^GO~Xb+Dib=ss?!mB(XG6KEg0UoH0`|pTSm{?;a9tN<3n$i=E-|K6Gy=y zLu{zm2>@=fi@`$7!=L2B4^X%&5g3B5r6jsNgu-!~*D(Ow;B$27V zD3o%t60EuhSZ|u6TM?3`(J`MZF{m=;pT}>~U^4ZuwD>gF*d*e7za7G~XIhH}hDDDX z_IZuOjVJA27sI4n@^#=EUPQ{J-<_j*OYL9ZZ7?i;RkSf5r1?smE&XK9ZGQSurc!1$ zj9&L~8-F)(5zKs%Ea!6e<5CrdkFJ2hoNRjg2E}4=0OJZ`Gv_xiX<1X-%1gHxFZ|1t zb4-N2k|$=Gp;lOBZK%9JGg8x~RCwPdQ95T2dkhJ|03--{Ize1kDA}DsIgD`JPy>Dq zYwtB=!Scl0-ej!RE==t1qbl#yDg(p-Y5>{rnUz#KI-`2R|9 z$a#)i^Cqfn(#N81NsP+@gC!MgRJ`nxXXas$>X{c_NM-SVC^nt&x+vF*xl=9NaF00_ ztC|LVyZXOBMSlL`vTyhe9o@zD(Hp@(7zc~KBtvTOlMxG-Ht$Z$oS=-%%<&Oqip#Hq zT%Wd@j!0FyW`$R4tN=%IfyZNMi#eKgd%9+H< z{=7TLp=iyG-cp#W|7MaR=ly~#Ln%;59%p-9ljazcuEr^T_FrgMle@e%-(OIlhPx_};uUZd&Dl(!7Kd3q_gj zXNmytJ%+1)5{ufnrj#l3{(`3aKZ8Hp#sk1}M)9MiqtjM)gQB5Enq%68yyZjNy|+Z0 zN}J_ZK3t=F^)oc3Twv@F+Fz=+m#)un+;(_3 z&(vdz685=jcT5&w!#=b=MWl)SP z;jtTAMq*?s+l+0zs3) z`<(A*ZjC+}*PP_3yPYFG7}xDiC~0{hr@Ol0M(%chsVk(mkKB_+fBep;U<#UACE6EE z^Zu1T(^rt59GF2hlitmhfo(HnKv&1Cc8AX1KkjE8m+3=0^dhBnG|R_RO;jnSYZtfg_tBf`%)uTU;Tnp6u9Ug|nTZgx{5p3V9oXCTGNp%_=YHcTdOs+Fm3k z_cb|fO^)|lX=#dL>@BX8=CzLa+x6rjM=Sg0*^JU#`zDnPXYjb^p9N;xZA5qW*EgC@ zbE+;#M)fO+A0@&03Y0t66aqZ=bSEZtg!qvYqyOS3DHHgoBexHszExXvmFKBfHN29W z03mO}3d$Ga`e@?t@9T15qZZ;9JPlAfiT28CHxk>3&wgKIHAZ*ZFB4Y39m;AIYry%h zFy>5WeMY*Qq_Q#|^QDBeeOwB1RPK7_0Jc*u(Wbb zhiEfa(CjlbHWxbK5bgV>jG7@q$vSscOND+sPd$U5Mhr-jK-GC6oN7#u;c#;Qd`2WI zs}%m)?3sr-#=mq_$fA3k{W>ZHs9R`HWQ#edJ@Re?T?&#nxh?)RVC{1$*T>+3XKUd{ z7)phoE4w|$47RSGBpz!;+v!EuW;arvC^v+UJSu2ppCg_f2Ym=Y+Gx&7e|;6Z;&j_^ zDg!On?d4A{8L1fYDy4XRoMd33BrLync38XK9aaB~t4vMGU_Rc7mWCRQO!LU+>I<31 z`RPz@aA3OpF47O74r5oreZ8%h#o!D8(YP@6{HN+rx{g*&y}Vk?3@izOc3u2tzrAZk z*X)KgQXONz(atz9BIUvAC0FJ2?rQRuL7^cOK8kYDc~{tH{&OxFy)lE&k-j(lA7ca9 zo~2P9df=Pfp3HrCo)+g@U_h+NyHT9DkjZaa?$PaJwT;X)^la9!KJQ-GJKGGueZvR$ zi(dlqlS2TrNxmOxLMOpA#za}{Rz8OV-`4|SzEIBs!=5LJ#s&xP9+B!H=pSwk&>gJ#VVd1h~ zGCyVD1A|*yiQePpjv_1&E=tld&w`=)yBo1%Y#BeWne)!s^1{+E>s7%Fv47wBV zvo&50V;9X!*!VpxISpO1g)J4x6~+<5j6+(r2HBgG^RBkzER6G4$@5J0u_D-H!G=}R zDl(+{r-aSCHLiLkuTr6HZUC-fP!X`uLA+ve4N_lHb7~rzw(`tToE-Da+)(^o^6aej z=@XDb@7wDPxApTwI9es8F23r>Ub1dt4S8yI2`Y&&+xYzK>&`A4=`+|FoA!w4uAGM` zZSYv9D{T<$GdqRal$xB1to$<4(x57!;Vthz`i;;oH@?lOM?S_rrA{Y?GG^3aX+ctz z;OiYWy9u#xG#vGFB^Qq(u{BDg8#lUrnu=qE%VF5u-#LakxRm1b?<_^10*l#;vSyl+ zfrM12K#{A#f+*qy9ayIB@!xTYlgd7xS9J z66jl;V2GF+twb?_G*S2PlKzMO5cC)Iih8S@MqKj<8gKOmE&n3EjISn)mNS6m3Z81$ z$)zADkA zjmzEr@EfI9npx17O&+IhCz$qgEhi4z>740t+mnutC6%3ip1+{>2!oaE!B~_S27KHq zck$dqAu=xq$AOxo80cB^je^LHTDxp^IEAtpfvIsZOgp}_OKKQ8Mq`)~YE1M%*k%w6 zyVTKk`%gRou6gi?NEmmH>|)a1kF0`uaJ76Ga45Dn zz_IKBnP<9!8_^N*%H)rZw1wWWINgAzY_42K%JH=unbm@2*o}#|3edmzmvn^Tks+aY zNrV(K%#E<)x7|r~c8OVsfg2&b@g6;JpiVnrgqmy=V4K zQX9g|t;{^<0*#O{HcfW8hfQ&!nm)B_f{$?{7)7ohJ}{1Ct_XR|%Ptb>KCfMnYDGmw zp|#}&7UJKf3^wEG=-<+M-$k zR*{0%|N2}8BqGRlytxT}?843WMhbynCA1O+k^sn5*HlLws^cz?=U*T5AO$-wcj zS^!YjcJ{82!#9?y?f2(JV8iWit6T>@RS((uuH9Zb1nK>bQ&;8I#tt8>6{Sn3=JacG z#b>}kuFLV><-f(REAP1UgU=cz*|-;P=+oG<1g$TBwIIX$AU}FyS#xXLRF;na1u#(*m%i!`|wj2 z+$r3w`95Jk8jl^gwGe&f_JiYWI6}zR=UT541?Lfcfa1h~uD|a#{F`K^6540t^Aga< zCmr`{6dtnmP3XzFY%|l7A?iO*NsEdC;R9QvSUg$cxVb?6O>1NGlm!mPq@;=6>g0~2 zJWyjv?;rx`#j+EwuC9?Bptm+&P1JTHpe~JS$8z=qy??o@e}$`+SUkl6ER1VBN9Uq? z0Tc^$G;rJ>S9p#q`6V44k?%zP~ zSw5>Ul$Y}ir+B=A-|R%qDXhTZZQ*^_CAu&;3r9*n}5X1BF8!UW1yizDh*#`hZpKwq`5q3y#$8N`BpJ( zA<#hJW$IeuIDWCmzs(rT$0>E7Byw7Wf6RwQM=T^t_&WgD%PC>n3Q-97GE4cry#3RY zMclTbkQ<>uN?mk1ct(bwl*2MdR7b#+Qnj4GX9+alc8xvOt}=-*&Ohuskhx)1jIUfHLd zVqNWa$sHn4o)oY+CVBS7Rz;QqXdpVuwWznwr$J&%eSeFy)v&uNQdFaOO??Crso)?pKA+viifo#rV=%O^b#)YOQ}gT2ULo=6$^V; z{sTVSLr@$tSPwRL9;NrL0$?(73!UrVr;$h7h3i*8y6<4OB3%ZLU%Yu=(x#@)(ID&M z3hyE4NoEmi?3VVwOojq#Exz;o!QFKABLglkBM-fGgfv}me;+}A$QG=Dg;j3ahHp@p zdKDMzlCEJj6F@Duh2j@WZgGM*OOzh#=j;ie+uv-^ za<8x@<#JiIlvOQ*AzQH%Fpq77voY{LaS8|yWw5UQ+&k}-+I*#T zs0IR2=b^|u1g{mq&C1?Jk+yI`Bx$w3(36hsQkC%jk^Ms$ENYY!NffFoKbq$*X~~<- zBIw1}vN{=L_tU$lezM#%7U`@R`EN_2Q{_t6r?cXa?1g*6;dF@a9fiqCG>5xw1hB>K+SLStZ>U&`B5R2C` zfg4TpV)1)P8pby^VuQWK+H?>SGitFSPTJgyKyVFC5}%X#pjJ9Pl+jotEH((auThMy ydPF3#Uy0Q`YClVSkk4!cHseOy;SWao!Rxm?>;!4Hg#%1`_ - Added search object functionality. | `Issue #2186 `_ - Added LDAP authentication support. | `Issue #5184 `_ - Added support for parameter toast_tuple_target and parallel_workers of the table. | `Issue #5264 `_ - Added support of Packages, Sequences and Synonyms to the Schema Diff. diff --git a/docs/en_US/search_objects.rst b/docs/en_US/search_objects.rst new file mode 100644 index 000000000..885e1d756 --- /dev/null +++ b/docs/en_US/search_objects.rst @@ -0,0 +1,34 @@ +.. _search_objects: + +*********************** +`Search objects`:index: +*********************** + +.. image:: images/search_objects.png + :alt: Search objects dialog + :align: center + +With this dialog, you can search for almost any kind of objects in a +database. + +You can access it by right clicking a database or any of its child nodes +and select "Search objects". You can also access it by hitting the +shortcut (default ALT+SHIFT+S). + +The minimum pattern length are 3 characters. The search performed is +non-casesensitive and will find all objets whose name contains the pattern. +You can only search for object names. + +The result is presented in the grid with object name, object type and +the object tree path in the :ref:`browser `. You can double +click on a result row to select the object in the +:ref:`browser `. If the object is greyed out, this means that you +have not enabled those object types in the :ref:`preferences `, +so you can't double click on it. + +You can filter based on a particular object type by selecting one from the +object type dropdown. If the search button is hit when one of the object type +is selected then only those types will be fetch from the database. +An object type will not be visible in the dropdown if the database server +does not support it or if it is not enabled from the +:ref:`preferences `. \ No newline at end of file diff --git a/docs/en_US/toolbar.rst b/docs/en_US/toolbar.rst index 12dc8621a..f4c685f24 100644 --- a/docs/en_US/toolbar.rst +++ b/docs/en_US/toolbar.rst @@ -18,4 +18,6 @@ the selected browser node. * Use the :ref:`View Data ` button to view/edit the data stored in a selected table. * Use the :ref:`Filtered Rows ` button to access the Data Filter popup - to apply a filter to a set of data for viewing/editing. \ No newline at end of file + to apply a filter to a set of data for viewing/editing. +* Use the :ref:`Search objects ` button to access the search objects + dialog. It helps you search any database object. \ No newline at end of file diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 09f472795..5f57f9fa1 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -249,6 +249,21 @@ def register_browser_preferences(self): fields=fields ) + self.preference.register( + 'keyboard_shortcuts', + 'sub_menu_search_objects', + gettext('Search objects'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': True, + 'control': False, + 'key': {'key_code': 83, 'char': 's'} + }, + category_label=gettext('Keyboard shortcuts'), + fields=fields + ) + self.preference.register( 'keyboard_shortcuts', 'sub_menu_create', diff --git a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js index 7724ef4c4..b2127c4b0 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js +++ b/web/pgadmin/browser/server_groups/servers/databases/extensions/static/js/extension.js @@ -24,7 +24,7 @@ define('pgadmin.node.extension', [ pgAdmin.Browser.Nodes['coll-extension'] = pgAdmin.Browser.Collection.extend({ node: 'extension', - label: gettext('Extension'), + label: gettext('Extensions'), type: 'coll-extension', columns: ['name', 'owner', 'comment'], }); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/templates/packages/ppas/12_plus/nodes.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/templates/packages/ppas/12_plus/nodes.sql new file mode 100644 index 000000000..8b11b594a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/templates/packages/ppas/12_plus/nodes.sql @@ -0,0 +1,11 @@ +SELECT + nsp.oid, nspname AS name +FROM + pg_namespace nsp +WHERE nspparent = {{scid}}::oid +{% if pkgid %} +AND nsp.oid = {{pkgid}}::oid +{% endif %} +AND nspobjecttype = 0 +AND nspcompoundtrigger = false +ORDER BY nspname; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py index 2984a58e4..4b0a0918c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/__init__.py @@ -54,8 +54,8 @@ class IndexConstraintModule(ConstraintTypeModule): initialized. """ - NODE_TYPE = 'Index constraint' - COLLECTION_LABEL = _('index_constraint') + NODE_TYPE = 'index_constraint' + COLLECTION_LABEL = _('Index constraint') def __init__(self, *args, **kwargs): """ diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py index e455b8adf..9ffbe742c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py @@ -29,8 +29,11 @@ from pgadmin.tools.schema_diff.compare import SchemaDiffObjectCompare def backend_supported(module, manager, **kwargs): - if 'tid' in kwargs and CollectionNodeModule.BackendSupported( - module, manager, **kwargs): + + if CollectionNodeModule.BackendSupported(module, manager, **kwargs): + if 'tid' not in kwargs: + return True + conn = manager.connection(did=kwargs['did']) template_path = 'partitions/sql/{0}/#{0}#{1}#'.format( diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/tests/test_backend_supported.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/tests/test_backend_supported.py index bf92e5f01..1de4de825 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/tests/test_backend_supported.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/tests/test_backend_supported.py @@ -21,19 +21,19 @@ else: class TestBackendSupport(BaseTestGenerator): scenarios = [ - ('when tid is not present in arguments, should return None and no ' - 'query should be done', + ('when tid is not present in arguments, but server version' + 'is supported then return True', dict( manager=dict( - server_type="", - version="" + server_type="pg", + version="100000" ), input_arguments=dict(did=432), collection_node_active=True, connection_execution_return_value=[], - expected_return_value=None, + expected_return_value=True, expect_error_response=False, expected_number_calls_on_render_template=0 )), diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/pg/macros/catalogs.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/pg/macros/catalogs.sql index 5f9bf9532..f1645d070 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/pg/macros/catalogs.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/pg/macros/catalogs.sql @@ -9,6 +9,9 @@ (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = {{ tbl }}.oid LIMIT 1)) {%- endmacro %} +{% macro IS_CATALOG_SCHEMA(schema_col_name) -%} + {{ schema_col_name }} IN ('pg_catalog', 'pgagent', 'information_schema') +{%- endmacro %} {% macro LABELS(tbl, _) -%} CASE {{ tbl }}.nspname WHEN 'pg_catalog' THEN '{{ _( 'PostgreSQL Catalog' ) }} (pg_catalog)' @@ -17,9 +20,24 @@ ELSE {{ tbl }}.nspname END AS name {%- endmacro %} +{% macro LABELS_SCHEMACOL(schema_col_name, _) -%} + CASE {{ schema_col_name }} + WHEN 'pg_catalog' THEN '{{ _( 'PostgreSQL Catalog' ) }} (pg_catalog)' + WHEN 'pgagent' THEN '{{ _( 'pgAgent Job Scheduler' ) }} (pgagent)' + WHEN 'information_schema' THEN '{{ _( 'ANSI' ) }} (information_schema)' + ELSE {{ schema_col_name }} + END +{%- endmacro %} {% macro DB_SUPPORT(tbl) -%} CASE WHEN {{ tbl }}.nspname = ANY('{information_schema}') THEN false ELSE true END {%- endmacro %} +{% macro DB_SUPPORT_SCHEMACOL(schema_col_name) -%} + CASE + WHEN {{ schema_col_name }} = ANY('{information_schema}') + THEN false + ELSE true END +{%- endmacro %} + diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/ppas/macros/catalogs.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/ppas/macros/catalogs.sql index 37fb594ed..b9fc276ef 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/ppas/macros/catalogs.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/templates/catalog/ppas/macros/catalogs.sql @@ -13,6 +13,9 @@ (SELECT 1 FROM pg_proc WHERE pronamespace = {{ tbl }}.oid and proname = 'run_job' LIMIT 1)) {%- endmacro %} +{% macro IS_CATALOG_SCHEMA(schema_col_name) -%} + {{ schema_col_name }} IN ('pg_catalog', 'pgagent', 'information_schema', 'dbo', 'sys', 'dbms_job_procedure') +{%- endmacro %} {% macro LABELS(tbl, _) -%} CASE {{ tbl }}.nspname WHEN 'pg_catalog' THEN '{{ _( 'PostgreSQL Catalog' ) }} (pg_catalog)' @@ -23,9 +26,25 @@ ELSE {{ tbl }}.nspname END AS name {%- endmacro %} -{% macro DB_SUPPORT(tbl) -%} +{% macro LABELS_SCHEMACOL(schema_col_name, _) -%} + CASE {{ schema_col_name }} + WHEN 'pg_catalog' THEN '{{ _( 'PostgreSQL Catalog' ) }} (pg_catalog)' + WHEN 'pgagent' THEN '{{ _( 'pgAgent Job Scheduler' ) }} (pgagent)' + WHEN 'information_schema' THEN '{{ _( 'ANSI' ) }} (information_schema)' + WHEN 'dbo' THEN 'Redmond (dbo)' + WHEN 'sys' THEN 'Redwood (sys)' + ELSE {{ schema_col_name }} + END +{%- endmacro %} +{% macro DB_SUPPORT(tbl, schema_col_name) -%} CASE WHEN {{ tbl }}.nspname = ANY('{information_schema,sys,dbo}') THEN false ELSE true END {%- endmacro %} +{% macro DB_SUPPORT_SCHEMACOL(schema_col_name) -%} + CASE + WHEN {{ schema_col_name }} = ANY('{information_schema,sys,dbo}') + THEN false + ELSE true END +{%- endmacro %} diff --git a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js index 47500caf7..c7bb247ec 100644 --- a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js +++ b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js @@ -18,6 +18,7 @@ define('pgadmin.node.role', [ pgAdmin.Browser.Nodes['coll-role'] = pgAdmin.Browser.Collection.extend({ node: 'role', + label: gettext('Login/Group Roles'), type: 'coll-role', columns: [ 'rolname', 'rolvaliduntil', 'rolconnlimit', 'rolcanlogin', diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js index 2ec4fe1b5..a3c9ad96e 100644 --- a/web/pgadmin/browser/static/js/collection.js +++ b/web/pgadmin/browser/static/js/collection.js @@ -51,14 +51,23 @@ define([ }]); // show query tool only in context menu of supported nodes. - if (pgAdmin.DataGrid && pgAdmin.unsupported_nodes) { - if (_.indexOf(pgAdmin.unsupported_nodes, this.type) == -1) { + + if (pgAdmin.unsupported_nodes && _.indexOf(pgAdmin.unsupported_nodes, this.type) == -1) { + if ((this.type == 'database' && this.allowConn) || this.type != 'database') { pgAdmin.Browser.add_menus([{ - name: 'show_query_tool', node: this.type, module: this, + name: 'show_query_tool', node: this.type, module: pgAdmin.DataGrid, applies: ['context'], callback: 'show_query_tool', priority: 998, label: gettext('Query Tool...'), icon: 'pg-font-icon icon-query-tool', }]); + + // show search objects same as query tool + pgAdmin.Browser.add_menus([{ + name: 'search_objects', node: this.type, module: pgAdmin.SearchObjects, + applies: ['context'], callback: 'show_search_objects', + priority: 997, label: gettext('Search Objects...'), + icon: 'fa fa-search', + }]); } } }, diff --git a/web/pgadmin/browser/static/js/keyboard.js b/web/pgadmin/browser/static/js/keyboard.js index 5cd00e6a3..8705e14be 100644 --- a/web/pgadmin/browser/static/js/keyboard.js +++ b/web/pgadmin/browser/static/js/keyboard.js @@ -34,6 +34,7 @@ _.extend(pgBrowser.keyboardNavigation, { 'tabbed_panel_forward': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'tabbed_panel_forward').value), 'sub_menu_query_tool': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_query_tool').value), 'sub_menu_view_data': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_view_data').value), + 'sub_menu_search_objects': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_search_objects').value), 'sub_menu_properties': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_properties').value), 'sub_menu_create': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_create').value), 'sub_menu_delete': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'sub_menu_delete').value), @@ -55,6 +56,7 @@ _.extend(pgBrowser.keyboardNavigation, { 'bindLeftTree': {'shortcuts': this.keyboardShortcut.left_tree_shortcut}, // Main menu, 'bindSubMenuQueryTool': {'shortcuts': this.keyboardShortcut.sub_menu_query_tool}, // Sub menu - Open Query Tool, 'bindSubMenuViewData': {'shortcuts': this.keyboardShortcut.sub_menu_view_data}, // Sub menu - Open View Data, + 'bindSubMenuSearchObjects': {'shortcuts': this.keyboardShortcut.sub_menu_search_objects}, // Sub menu - Open search objects, 'bindSubMenuProperties': {'shortcuts': this.keyboardShortcut.sub_menu_properties}, // Sub menu - Edit Properties, 'bindSubMenuCreate': {'shortcuts': this.keyboardShortcut.sub_menu_create}, // Sub menu - Create Object, 'bindSubMenuDelete': {'shortcuts': this.keyboardShortcut.sub_menu_delete}, // Sub menu - Delete object, @@ -261,6 +263,15 @@ _.extend(pgBrowser.keyboardNavigation, { // Call data grid method to render view data pgAdmin.DataGrid.show_data_grid({'mnuid': 1}, tree.i); }, + bindSubMenuSearchObjects: function() { + const tree = this.getTreeDetails(); + + if (!tree.d) + return; + + // Call data grid method to render view data + pgAdmin.SearchObjects.show_search_objects('', tree.i); + }, bindSubMenuProperties: function() { const tree = this.getTreeDetails(); diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index d14dcc5bb..df4657b6b 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -177,6 +177,14 @@ define('pgadmin.browser.node', [ // Show query tool only in context menu of supported nodes. if (_.indexOf(pgAdmin.unsupported_nodes, self.type) == -1) { + let enable = function(itemData) { + if (itemData._type == 'database' && itemData.allowConn) + return true; + else if (itemData._type != 'database') + return true; + else + return false; + }; pgAdmin.Browser.add_menus([{ name: 'show_query_tool', node: self.type, @@ -186,14 +194,15 @@ define('pgadmin.browser.node', [ priority: 998, label: gettext('Query Tool...'), icon: 'pg-font-icon icon-query-tool', - enable: function(itemData) { - if (itemData._type == 'database' && itemData.allowConn) - return true; - else if (itemData._type != 'database') - return true; - else - return false; - }, + enable: enable, + }]); + + // show search objects same as query tool + pgAdmin.Browser.add_menus([{ + name: 'search_objects', node: self.type, module: pgAdmin.SearchObjects, + applies: ['context'], callback: 'show_search_objects', + priority: 997, label: gettext('Search Objects...'), + icon: 'fa fa-search', enable: enable, }]); } diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js index 955fe6f32..6eb1f39f4 100644 --- a/web/pgadmin/browser/static/js/toolbar.js +++ b/web/pgadmin/browser/static/js/toolbar.js @@ -46,6 +46,16 @@ let _defaultToolBarButtons = [ parentClass: 'pg-toolbar-btn btn-secondary', enabled: false, }, + { + label: gettext('Search objects'), + ariaLabel: gettext('Search objects'), + btnClass: 'fa fa-search', + text: '', + toggled: false, + toggleClass: '', + parentClass: 'pg-toolbar-btn btn-secondary', + enabled: false, + }, ]; // Place holder for non default tool bar buttons. @@ -92,6 +102,8 @@ export function initializeToolbar(panel, wcDocker) { pgAdmin.DataGrid.show_data_grid({mnuid: 3}, pgAdmin.Browser.tree.selected()); else if ('name' in data && data.name === gettext('Filtered Rows')) pgAdmin.DataGrid.show_filtered_row({mnuid: 4}, pgAdmin.Browser.tree.selected()); + else if ('name' in data && data.name === gettext('Search objects')) + pgAdmin.SearchObjects.show_search_objects('', pgAdmin.Browser.tree.selected()); }); } diff --git a/web/pgadmin/browser/templates/browser/index.html b/web/pgadmin/browser/templates/browser/index.html index b389b9574..f8b3d5764 100644 --- a/web/pgadmin/browser/templates/browser/index.html +++ b/web/pgadmin/browser/templates/browser/index.html @@ -11,7 +11,7 @@ {% block init_script %} try { require( -['sources/generated/app.bundle', 'sources/generated/codemirror', 'sources/generated/browser_nodes'], +['sources/generated/app.bundle', 'sources/generated/codemirror', 'sources/generated/browser_nodes', 'sources/generated/slickgrid'], function() { }, function() { diff --git a/web/pgadmin/static/bundle/slickgrid.js b/web/pgadmin/static/bundle/slickgrid.js index 4b0ab410b..96ad3c330 100644 --- a/web/pgadmin/static/bundle/slickgrid.js +++ b/web/pgadmin/static/bundle/slickgrid.js @@ -8,7 +8,6 @@ ////////////////////////////////////////////////////////////// import 'slickgrid/lib/jquery.event.drag-2.3.0'; -import 'slickgrid/lib/jquery-ui-1.11.3'; import 'slickgrid/slick.core'; import 'slickgrid/slick.grid'; import 'slickgrid/slick.dataview'; @@ -21,5 +20,6 @@ import 'slickgrid/plugins/slick.cellrangeselector'; import 'slickgrid/plugins/slick.checkboxselectcolumn'; import 'slickgrid/plugins/slick.rowselectionmodel'; import 'sources/slickgrid/custom_header_buttons'; +import 'sources/slickgrid/plugins/slick.autocolumnsize'; export default window.Slick; diff --git a/web/pgadmin/static/css/style.css b/web/pgadmin/static/css/style.css index 05709ef58..7ab5ced97 100644 --- a/web/pgadmin/static/css/style.css +++ b/web/pgadmin/static/css/style.css @@ -5,18 +5,17 @@ @import '~tempusdominus-bootstrap-4/build/css/tempusdominus-bootstrap-4.css'; @import '~bootstrap4-toggle/css/bootstrap4-toggle.css'; @import '~backgrid-filter/backgrid-filter.css'; -@import '~slickgrid/css/select2.css'; @import '~jquery-contextmenu/dist/jquery.contextMenu.css'; @import '~webcabin-docker/Build/wcDocker.css'; @import '~acitree/css/aciTree.css'; @import '~leaflet/dist/leaflet.css'; +@import '../../../node_modules/select2/dist/css/select2.css'; @import '~codemirror/lib/codemirror.css'; @import '~codemirror/addon/dialog/dialog.css'; @import '~codemirror/addon/scroll/simplescrollbars.css'; @import '~slickgrid/slick.grid.css'; -@import '~slickgrid/slick-default-theme.css'; @import '~slickgrid/css/smoothness/jquery-ui-1.11.3.custom.css'; @import '../vendor/backgrid/backgrid.css'; diff --git a/web/pgadmin/static/js/alertify.pgadmin.defaults.js b/web/pgadmin/static/js/alertify.pgadmin.defaults.js index 84dfc12fe..daa60f696 100644 --- a/web/pgadmin/static/js/alertify.pgadmin.defaults.js +++ b/web/pgadmin/static/js/alertify.pgadmin.defaults.js @@ -271,7 +271,8 @@ define([ let container = $(self.elements.footer); commonUtils.findAndSetFocus(container.find('button:not([disabled]):last')); } - }); }); + }); + }); this.set('onresize', alertifyDialogStartResizing.bind(this, true)); this.set('onresized', alertifyDialogResized.bind(this, true)); this.set('onmaximized', alertifyDialogResized); diff --git a/web/pgadmin/static/js/alertify/dialog.js b/web/pgadmin/static/js/alertify/dialog.js index 6f4933720..8e5bdb738 100644 --- a/web/pgadmin/static/js/alertify/dialog.js +++ b/web/pgadmin/static/js/alertify/dialog.js @@ -80,6 +80,39 @@ export class Dialog { return serverInformation; } + retrieveAncestorOfTypeDatabase(item) { + let databaseInfo = null; + let aciTreeItem = item || this.pgBrowser.treeMenu.selected(); + let treeNode = this.pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem); + + if (treeNode) { + if(treeNode.getData()._type === 'database') { + databaseInfo = treeNode.getData(); + } else { + let nodeData = null; + treeNode.ancestorNode( + (node) => { + nodeData = node.getData(); + if(nodeData._type === 'database') { + databaseInfo = nodeData; + return true; + } + return false; + } + ); + } + } + + if (databaseInfo === null) { + this.alertify.alert( + gettext(this.errorAlertTitle), + gettext('Please select a database or its child node from the browser.') + ); + } + + return databaseInfo; + } + hasBinariesConfiguration(serverInformation) { const module = 'paths'; let preference_name = 'pg_bin_dir'; diff --git a/web/pgadmin/static/js/alertify/dialog_factory.js b/web/pgadmin/static/js/alertify/dialog_factory.js index cb0ae1552..760fde679 100644 --- a/web/pgadmin/static/js/alertify/dialog_factory.js +++ b/web/pgadmin/static/js/alertify/dialog_factory.js @@ -9,6 +9,7 @@ import * as BackupDialog from '../../../tools/backup/static/js/backup_dialog_wrapper'; import {RestoreDialogWrapper} from '../../../tools/restore/static/js/restore_dialog_wrapper'; +import SearchObjectsDialogWrapper from '../../../tools/search_objects/static/js/search_objects_dialog_wrapper'; export class DialogFactory { constructor(pgBrowser, $, @@ -25,6 +26,8 @@ export class DialogFactory { create(dialogTitle, typeOfDialog) { if (typeOfDialog === 'restore') { return this.createRestoreDialog(dialogTitle, typeOfDialog); + } else if (typeOfDialog === 'search_objects') { + return this.createSearchObjectsDialog(dialogTitle, typeOfDialog); } else { return this.createBackupDialog(dialogTitle, typeOfDialog); } @@ -49,4 +52,14 @@ export class DialogFactory { this.dialogModel, this.backform); } + + createSearchObjectsDialog(dialogTitle, typeOfDialog) { + return new SearchObjectsDialogWrapper( + this.dialogContainerSelector, dialogTitle, typeOfDialog, + this.jquery, + this.pgBrowser, + this.alertify, + this.dialogModel, + this.backform); + } } diff --git a/web/pgadmin/static/js/alertify/dialog_wrapper.js b/web/pgadmin/static/js/alertify/dialog_wrapper.js index e4c275f3a..32d9a7a0b 100644 --- a/web/pgadmin/static/js/alertify/dialog_wrapper.js +++ b/web/pgadmin/static/js/alertify/dialog_wrapper.js @@ -58,7 +58,11 @@ export class DialogWrapper { let backform_tab = $(alertifyDialog.elements.body).find('.backform-tab'); backform_tab.attr('tabindex', -1); this.pgBrowser.keyboardNavigation.getDialogTabNavigator($(alertifyDialog.elements.dialog)); - const container = backform_tab.find('.tab-content:first > .tab-pane.active:first'); + let container = backform_tab.find('.tab-content:first > .tab-pane.active:first'); + + if(container.length === 0 && alertifyDialog.elements.content.innerHTML) { + container = $(alertifyDialog.elements.content); + } commonUtils.findAndSetFocus(container); } diff --git a/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js b/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js index 40e537e1b..85b339139 100644 --- a/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js +++ b/web/pgadmin/static/js/slickgrid/plugins/slick.autocolumnsize.js @@ -98,7 +98,7 @@ function getTemplateWidth(rowEl, template) { var cell = $(rowEl.find('.slick-cell')); cell.append(template); - $(cell).find('*').css('position', 'relative'); + cell.find('*').css('position', 'relative'); return cell.outerWidth() + 1; } @@ -128,7 +128,7 @@ 'text-overflow': 'initial', 'white-space': 'nowrap', }); - var gridCanvas = $container.find('.grid-canvas'); + var gridCanvas = $container.find('.grid-canvas').first(); $(gridCanvas).append(rowEl); return rowEl; } diff --git a/web/pgadmin/static/js/tree/tree.js b/web/pgadmin/static/js/tree/tree.js index 57b6207c8..984d247d3 100644 --- a/web/pgadmin/static/js/tree/tree.js +++ b/web/pgadmin/static/js/tree/tree.js @@ -50,17 +50,50 @@ export class TreeNode { } reload(tree) { - this.unload(tree); - tree.aciTreeApi.setInode(this.domNode); - tree.aciTreeApi.deselect(this.domNode); - setTimeout(() => { - tree.selectNode(this.domNode); - }, 0); + return new Promise((resolve)=>{ + this.unload(tree) + .then(()=>{ + tree.aciTreeApi.setInode(this.domNode); + tree.aciTreeApi.deselect(this.domNode); + setTimeout(() => { + tree.selectNode(this.domNode); + }, 0); + resolve(); + }); + }); } unload(tree) { - this.children = []; - tree.aciTreeApi.unload(this.domNode); + return new Promise((resolve, reject)=>{ + this.children = []; + tree.aciTreeApi.unload(this.domNode, { + success: ()=>{ + resolve(true); + }, + fail: ()=>{ + reject(); + }, + }); + }); + } + + open(tree, suppressNoDom) { + return new Promise((resolve, reject)=>{ + if(suppressNoDom && (this.domNode == null || typeof(this.domNode) === 'undefined')) { + resolve(true); + } else if(tree.aciTreeApi.isOpen(this.domNode)) { + resolve(true); + } else { + tree.aciTreeApi.open(this.domNode, { + success: ()=>{ + resolve(true); + }, + fail: ()=>{ + reject(true); + }, + }); + } + }); } /* @@ -202,6 +235,47 @@ export class Tree { return findInTree(this.rootNode, path.join('.')); } + findNodeWithToggle(path) { + let tree = this; + path = path.join('.'); + + let onCorrectPath = function(matchPath) { + return (matchPath !== undefined && path !== undefined + && (path.startsWith(matchPath + '.') || path === matchPath)); + }; + + return (function findInNode(currentNode) { + return new Promise((resolve, reject)=>{ + if (path === null || path === undefined || path.length === 0) { + resolve(null); + } + /* No point in checking the children if + * the path for currentNode itself is not matching + */ + if (currentNode.path !== undefined && !onCorrectPath(currentNode.path)) { + reject(null); + } else if (currentNode.path === path) { + resolve(currentNode); + } else { + currentNode.open(tree, true) + .then(()=>{ + for (let i = 0, length = currentNode.children.length; i < length; i++) { + let childNode = currentNode.children[i]; + if(onCorrectPath(childNode.path)) { + resolve(findInNode(childNode)); + return; + } + } + reject(null); + }) + .catch(()=>{ + reject(null); + }); + } + }); + })(this.rootNode); + } + findNodeByDomElement(domElement) { const path = this.translateTreeNodeIdFromACITree(domElement); if(!path || !path[0]) { @@ -215,8 +289,19 @@ export class Tree { return this.aciTreeApi.selected(); } - selectNode(aciTreeIdentifier) { + /* scrollIntoView will scroll only to top and bottom + * Logic can be added for scroll to middle + */ + scrollTo(domElement) { + domElement.scrollIntoView(); + } + + selectNode(aciTreeIdentifier, scrollOnSelect) { this.aciTreeApi.select(aciTreeIdentifier); + + if(scrollOnSelect) { + this.scrollTo(aciTreeIdentifier[0]); + } } createOrUpdateNode(id, data, parent, domNode) { @@ -227,6 +312,7 @@ export class Tree { const oldNode = this.findNode(oldNodePath); if (oldNode !== null) { oldNode.data = data; + oldNode.domNode = domNode; return oldNode; } @@ -238,6 +324,18 @@ export class Tree { return node; } + unloadNode(id, data, domNode, parentPath) { + let oldNodePath = [id]; + const parent = this.findNode(parentPath); + if(parent !== null && parent !== undefined) { + oldNodePath = [parent.path, id]; + } + const oldNode = this.findNode(oldNodePath); + if(oldNode) { + oldNode.children = []; + } + } + /** * Given the JQuery object that contains the ACI Tree * this method is responsible for registering this tree class @@ -252,16 +350,20 @@ export class Tree { $treeJQuery.on('acitree', function (event, api, item, eventName) { if (api.isItem(item)) { /* If the id of node is changed, the path should also be changed */ - if (eventName === 'added' || eventName === 'idset') { + if (['added', 'idset', 'beforeunload'].indexOf(eventName) != -1) { const id = api.getId(item); const data = api.itemData(item); - - if(eventName === 'added') { - this.prepareDraggable(data, item); - } - const parentId = this.translateTreeNodeIdFromACITree(api.parent(item)); - this.addNewNode(id, data, item, parentId); + + if(eventName === 'beforeunload') { + this.unloadNode(id, data, item, parentId); + } else { + if(eventName === 'added') { + this.prepareDraggable(data, item); + } + + this.addNewNode(id, data, item, parentId); + } if(data.errmsg) { Alertify.error(data.errmsg); } diff --git a/web/pgadmin/static/js/utils.js b/web/pgadmin/static/js/utils.js index 86dae698e..7bdddba85 100644 --- a/web/pgadmin/static/js/utils.js +++ b/web/pgadmin/static/js/utils.js @@ -32,11 +32,12 @@ export function findAndSetFocus(container) { * browser. For eg, in safari focus() works only when element has * tabindex="0", whereas in Chrome it works in any case */ + if (first_el.length == 0) { first_el = container .find(` - .pgadmin-controls:first input:enabled, .pgadmin-controls:first .btn:not(.toggle), + .pgadmin-controls:first, .ajs-commands:first, .CodeMirror-scroll`) .find('*[tabindex]:not([tabindex="-1"])'); diff --git a/web/pgadmin/static/scss/_alert.scss b/web/pgadmin/static/scss/_alert.scss index 3f2e561e3..0e7e234d1 100644 --- a/web/pgadmin/static/scss/_alert.scss +++ b/web/pgadmin/static/scss/_alert.scss @@ -119,21 +119,18 @@ } .success-in-footer { - border-radius: 5px; - border: 1px solid transparent; - - .alert-text { - border-color: $color-success-light; - } + border-radius: $border-radius; + border: 1px solid $color-success-light; + background: $color-success-light; } .info-in-footer { + border-radius: $border-radius; border: 1px solid $color-primary; - border-radius: 4px; - height: 35px; + background: $color-primary-light; - .alert-text { - border: none; + .fa { + font-size: 1rem; } } } diff --git a/web/pgadmin/static/scss/_webcabin.pgadmin.scss b/web/pgadmin/static/scss/_webcabin.pgadmin.scss index 4846a8031..ca806785a 100644 --- a/web/pgadmin/static/scss/_webcabin.pgadmin.scss +++ b/web/pgadmin/static/scss/_webcabin.pgadmin.scss @@ -166,7 +166,7 @@ .wcTabIcon { background-position: center; - padding: 0px 10px; + padding: 0rem 0.75rem; &.fa, &.pg-font-icon{ padding: 0rem 0.25rem 0rem 0rem diff --git a/web/pgadmin/tools/search_objects/__init__.py b/web/pgadmin/tools/search_objects/__init__.py new file mode 100644 index 000000000..e8bd59141 --- /dev/null +++ b/web/pgadmin/tools/search_objects/__init__.py @@ -0,0 +1,87 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +"""Implements Search Object feature""" + +from flask import request +from flask_babelex import gettext +from flask_security import login_required + +from pgadmin.utils import PgAdminModule +from pgadmin.utils.ajax import make_json_response, bad_request,\ + internal_server_error +from pgadmin.utils.preferences import Preferences +from pgadmin.tools.search_objects.utils import SearchObjectsHelper + +MODULE_NAME = 'search_objects' + + +class SearchObjectsModule(PgAdminModule): + LABEL = gettext('Search objects') + + def get_exposed_url_endpoints(self): + """ + Returns: + list: URL endpoints for search_object module + """ + return ['search_objects.search', 'search_objects.types'] + + def show_system_objects(self): + """ + return system preference objects + """ + return self.pref_show_system_objects.get() + + def register_preferences(self): + """ + Get show_system_objects preference + """ + browser_preference = Preferences.module('browser') + self.pref_show_system_objects =\ + browser_preference.preference('show_system_objects') + + +# Create blueprint for BackupModule class +blueprint = SearchObjectsModule( + MODULE_NAME, __name__, static_url_path='' +) + + +@blueprint.route("/", endpoint='index') +@login_required +def index(): + return bad_request(errormsg=_("This URL cannot be called directly.")) + + +@blueprint.route("types//", endpoint='types') +@login_required +def types(sid, did): + so_obj = SearchObjectsHelper(sid, did, blueprint.show_system_objects()) + return make_json_response(data=so_obj.get_supported_types()) + + +@blueprint.route("search//", endpoint='search') +@login_required +def search(sid, did): + """ + URL args: + text : search text + type : type of object to be searched. + """ + text = request.args.get('text', None) + obj_type = request.args.get('type', None) + + so_obj = SearchObjectsHelper(sid, did, blueprint.show_system_objects()) + + status, res = so_obj.search(text, obj_type) + + if not status: + return internal_server_error(errormsg=res) + + return make_json_response(data=res) diff --git a/web/pgadmin/tools/search_objects/static/js/search_objects.js b/web/pgadmin/tools/search_objects/static/js/search_objects.js new file mode 100644 index 000000000..98a415e94 --- /dev/null +++ b/web/pgadmin/tools/search_objects/static/js/search_objects.js @@ -0,0 +1,90 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +define([ + 'sources/gettext', 'sources/url_for', 'jquery', 'underscore', 'pgadmin.alertifyjs', + 'sources/pgadmin', 'sources/csrf', 'pgadmin.browser.toolbar', + 'pgadmin.search_objects/search_objects_dialog', +], function( + gettext, url_for, $, _, alertify, pgAdmin, csrfToken, toolBar, SearchObjectsDialog +) { + + var pgBrowser = pgAdmin.Browser; + if (pgAdmin.SearchObjects) + return pgAdmin.SearchObjects; + + pgAdmin.SearchObjects = { + init: function() { + if (this.initialized) + return; + + this.initialized = true; + csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + + // Define the nodes on which the menus to be appear + var menus = [{ + name: 'search_objects', + module: this, + applies: ['tools'], + callback: 'show_search_objects', + enable: this.search_objects_enabled, + priority: 1, + label: gettext('Search objects'), + }, { + name: 'search_objects', + module: this, + applies: ['context'], + callback: 'show_search_objects', + enable: this.search_objects_enabled, + priority: 1, + label: gettext('Search objects'), + }]; + + pgBrowser.add_menus(menus); + return this; + }, + + search_objects_enabled: function(obj) { + /* Same as query tool */ + var isEnabled = (() => { + if (!_.isUndefined(obj) && !_.isNull(obj)) { + if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) { + if (obj._type == 'database' && obj.allowConn) { + return true; + } else if (obj._type != 'database') { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + })(); + + toolBar.enable(gettext('Search objects'), isEnabled); + return isEnabled; + }, + + // Callback to show the dialog + show_search_objects: function(action, item) { + let dialog = new SearchObjectsDialog.default( + pgBrowser, + $, + alertify, + {}, + ); + dialog.draw(action, item, {}, pgBrowser.stdW.md, pgBrowser.stdH.lg); + }, + }; + + return pgAdmin.SearchObjects; +}); diff --git a/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js new file mode 100644 index 000000000..4482f7eb4 --- /dev/null +++ b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import {Dialog} from 'sources/alertify/dialog'; +import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title'; + +export default class SearchObjectsDialog extends Dialog { + constructor(pgBrowser, $, alertify, BackupModel, backform = null) { + super(gettext('Search Objects Error'), + '

', + pgBrowser, $, alertify, BackupModel, backform + ); + } + + dialogName() { + return 'search_objects'; + } + + draw(action, aciTreeItem, params, width=0, height=0) { + let dbInfo = this.retrieveAncestorOfTypeDatabase(aciTreeItem); + if (!dbInfo) { + return; + } + + let dialogTitle = getPanelTitle(this.pgBrowser, aciTreeItem); + dialogTitle = gettext('Search Objects - ') + dialogTitle; + const dialog = this.createOrGetDialog( + gettext('Search Objects...'), + 'search_objects' + ); + dialog(dialogTitle).resizeTo(width, height); + } +} diff --git a/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js new file mode 100644 index 000000000..e489f246a --- /dev/null +++ b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js @@ -0,0 +1,649 @@ +import {getTreeNodeHierarchyFromElement} from 'sources/tree/pgadmin_tree_node'; +import axios from 'axios/index'; +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import 'select2'; +import {DialogWrapper} from 'sources/alertify/dialog_wrapper'; +import Slick from 'sources/../bundle/slickgrid'; +import pgAdmin from 'sources/pgadmin'; + + +export default class SearchObjectsDialogWrapper extends DialogWrapper { + constructor(dialogContainerSelector, dialogTitle, typeOfDialog, + jquery, pgBrowser, alertify, dialogModel, backform) { + super(dialogContainerSelector, dialogTitle, jquery, + pgBrowser, alertify, dialogModel, backform); + + this.grid = null; + this.dataview = null; + this.gridContainer = null; + } + + showMessage(text, is_error, call_after_show=()=>{}) { + if(text == '' || text == null) { + this.statusBar.classList.add('d-none'); + } else { + if(is_error) { + this.statusBar.innerHTML = ` + + `; + + this.statusBar.querySelector('.close-error').addEventListener('click', ()=>{ + this.showMessage(null); + }); + } else { + this.statusBar.innerHTML = ` + + `; + } + this.statusBar.classList.remove('d-none'); + call_after_show(this.statusBar); + } + } + + createDialogDOM(dialogContainer) { + dialogContainer.innerHTML = ` +
+
+
+
+
+
+ +
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `; + + return dialogContainer; + } + + updateDimOfSearchResult() { + let dim = this.searchResultContainer.getBoundingClientRect(); + this.searchResult.style.height = dim.height + 'px'; + this.searchResult.style.width = dim.width + 'px'; + } + + setLoading(text) { + if(text != null) { + this.loader.classList.remove('d-none'); + this.loader.querySelector('.pg-sp-text').innerHTML = text; + } else { + this.loader.classList.add('d-none'); + } + } + + searchBtnEnabled(enabled) { + if(typeof(enabled) != 'undefined') { + this.searchBtn.disabled = !enabled; + } else { + return !this.searchBtn.disabled; + } + } + + searchBoxVal(val) { + if(typeof(val) != 'undefined') { + this.searchBox.value = val; + } else { + return this.searchBox.value.trim(); + } + } + + typesVal(val) { + if(typeof(val) != 'undefined') { + this.typesSelect.value = val; + } else { + return this.typesSelect.value; + } + } + + setTypes(data, enabled=true) { + this.jquery(this.typesSelect).empty().select2({ + data: data, + }); + + this.typesSelect.disabled = !enabled; + } + + setResultCount(count) { + if(count != 0 && !count) { + count = gettext('Unknown'); + } + this.searchResultCount.innerHTML = count + ' ' + + (count===1 ? gettext('match found.'): gettext('matches found.')); + } + + showOtherInfo(rowno) { + let rowData = this.dataview.getItem(rowno); + rowData.name += ` (${rowData.other_info})`; + rowData.other_info = null; + this.dataview.updateItem(rowData.id, rowData); + } + + setGridData(data) { + this.dataview.setItems(data); + } + + prepareGrid() { + this.dataview = new Slick.Data.DataView(); + + this.dataview.getItemMetadata = (row)=>{ + let rowData = this.dataview.getItem(row); + if(!rowData.show_node){ + return { + cssClasses: 'object-muted', + }; + } + return null; + }; + + this.dataview.setFilter((item, args)=>{ + return !(args && args.type != 'all' && item.type != args.type); + }); + + /* jquery required for select2 */ + this.jquery(this.typesSelect).on('change', ()=>{ + this.dataview.setFilterArgs({ type: this.typesVal() }); + this.dataview.refresh(); + }); + + this.dataview.onRowCountChanged.subscribe((e, args) => { + this.grid.updateRowCount(); + this.grid.render(); + this.setResultCount(args.current); + }); + + this.dataview.onRowsChanged.subscribe((e, args) => { + this.grid.invalidateRows(args.rows); + this.grid.render(); + }); + + this.grid = new Slick.Grid( + this.searchResult, + this.dataview, + [ + { id: 'name', name: gettext('Object name'), field: 'name', sortable: true, + formatter: (row, cell, value, columnDef, dataContext) => { + let ret_el = `${value}`; + + if(dataContext.other_info != null && dataContext.other_info != '') { + ret_el += ' (...)'; + } + + return ret_el; + }, + width: 50, + }, + { id: 'type', name: gettext('Type'), field: 'type_label', sortable: true, width: 35 }, + { id: 'path', name: gettext('Browser path'), field: 'path', sortable: false }, + ], + { + enableCellNavigation: true, + enableColumnReorder: false, + multiColumnSort: true, + explicitInitialization: true, + } + ); + + this.grid.registerPlugin(new Slick.AutoColumnSize()); + + this.grid.setSelectionModel(new Slick.RowSelectionModel({selectActiveRow: true})); + + this.grid.onKeyDown.subscribe((event) => { + let activeRow = this.grid.getActiveCell(); + if(activeRow && !event.ctrlKey && !event.altKey && !event.metaKey && event.keyCode == 9) { + event.preventDefault(); + event.stopImmediatePropagation(); + + if(event.shiftKey) { + this.prevToGrid.focus(); + } else { + this.nextToGrid.focus(); + } + } + }); + + this.grid.onClick.subscribe((event, args) => { + if(event.target.classList.contains('object-other-info')) { + this.showOtherInfo(args.row); + } + }); + + this.grid.onDblClick.subscribe((event, args) => { + let rowData = this.dataview.getItem(args.row); + let treeMenu = this.pgBrowser.treeMenu; + + if(!rowData.show_node) { + this.showMessage( + gettext('%s objects are disabled in the browser.', rowData.type_label) + ' ' + + gettext('You can enable them in the') + ' ' + gettext('preferences dialog') + '.', + true, + (statusBar)=>{ + statusBar.querySelector('.pref-dialog-link').addEventListener('click', ()=>{ + if(pgAdmin.Preferences) { + pgAdmin.Preferences.show(); + } + }); + } + ); + return false; + } + this.showMessage(gettext('Locating...')); + treeMenu.findNodeWithToggle(rowData.id_path) + .then((treeItem)=>{ + treeMenu.selectNode(treeItem.domNode, true); + this.showMessage(null); + }) + .catch((args)=>{ + this.showMessage(gettext('Unable to locate this object in the browser.'), true); + console.warn(args); + }); + }); + + this.grid.onSort.subscribe((event, args) => { + let cols = args.sortCols; + + this.dataview.sort(function (dataRow1, dataRow2) { + for (var i = 0, l = cols.length; i < l; i++) { + var field = cols[i].sortCol.field; + var sign = cols[i].sortAsc ? 1 : -1; + var value1 = dataRow1[field], value2 = dataRow2[field]; + var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign; + if (result != 0) { + return result; + } + } + return false; + }, true); + }); + } + + onDialogResize() { + this.updateDimOfSearchResult(); + + if(this.grid) { + this.grid.resizeCanvas(); + this.grid.autosizeColumns(); + } + } + + onDialogShow() { + this.focusOnDialog(this); + + setTimeout(()=>{ + if(!this.grid) { + this.prepareGrid(); + } + this.updateDimOfSearchResult(); + this.grid.init(); + this.setGridData([]); + this.onDialogResize(); + }, 500); + } + + getBaseUrl(endpoint) { + return url_for('search_objects.'+endpoint, { + sid: this.treeInfo.server._id, + did: this.treeInfo.database._id, + }); + } + + getCollNode(node_type) { + if('coll-'+node_type in this.pgBrowser.Nodes) { + return this.pgBrowser.Nodes['coll-'+node_type]; + } else if(node_type in this.pgBrowser.Nodes && + typeof(this.pgBrowser.Nodes[node_type].collection_type) === 'string') { + return this.pgBrowser.Nodes[this.pgBrowser.Nodes[node_type].collection_type]; + } + + return null; + } + + getSelectedNode() { + const tree = this.pgBrowser.treeMenu; + const selectedNode = tree.selected(); + if (selectedNode) { + return tree.findNodeByDomElement(selectedNode); + } else { + return undefined; + } + } + + finaliseData(datum) { + datum.icon = 'icon-' + datum.type; + /* finalise path */ + [datum.path, datum.id_path] = this.translateSearchObjectsPath(datum.path, datum.catalog_level); + /* id is required by slickgrid dataview */ + datum.id = datum.id_path; + return datum; + } + + /* This function will translate the path given by search objects API into two parts + * 1. The display path on the UI + * 2. The tree search path to locate the object on the tree. + * + * Sample path returned by search objects API + * :schema.11:/pg_catalog/:table.2604:/pg_attrdef + * + * Sample path required by tree locator + * Normal object - server_group/1.server/3.coll-database/3.database/13258.coll-schema/13258.schema/2200.coll-table/2200.table/41773 + * pg_catalog schema - server_group/1.server/3.coll-database/3.database/13258.coll-catalog/13258.catalog/11.coll-table/11.table/2600 + * Information Schema, dbo, sys - server_group/1.server/3.coll-database/3.database/13258.coll-catalog/13258.catalog/12967.coll-catalog_object/12967.catalog_object/13204 + * + * Column catalog_level has values as + * N - Not a catalog schema + * D - Catalog schema with DB support - pg_catalog + * O - Catalog schema with object support only - info schema, dbo, sys + */ + translateSearchObjectsPath(path, catalog_level) { + if (path === null) { + return path; + } + + catalog_level = catalog_level || 'N'; + + /* path required by tree locator */ + /* the path received from the backend is after the DB node, initial path setup */ + let id_path = [ + this.treeInfo.server_group.id, + this.treeInfo.server.id, + this.getCollNode('database').type + '/' + this.treeInfo.server._id, + this.treeInfo.database.id, + ]; + + let prev_node_id = this.treeInfo.database._id; + + /* add the slash to match regex, remove it from display path later */ + path = '/' + path; + /* the below regex will match all /:server_group.1:/ */ + let new_path = path.replace(/\/:[a-zA-Z_]+\.[0-9]+:\//g, (token)=>{ + let orig_token = token; + /* remove the slash and colon */ + token = token.slice(2, -2); + let [node_type, node_oid, others] = token.split('.'); + if(typeof(others) !== 'undefined') { + return token; + } + + /* schema type is "catalog" for catalog schemas */ + node_type = (['D', 'O'].indexOf(catalog_level) != -1 && node_type == 'schema') ? 'catalog' : node_type; + + /* catalog like info schema will only have views and tables AKA catalog_object except for pg_catalog */ + node_type = (catalog_level === 'O' && ['view', 'table'].indexOf(node_type) != -1) ? 'catalog_object' : node_type; + + /* If collection node present then add it */ + let coll_node = this.getCollNode(node_type); + if(coll_node) { + /* Add coll node to the path */ + if(prev_node_id != null) id_path.push(`${coll_node.type}/${prev_node_id}`); + + /* Add the node to the path */ + id_path.push(`${node_type}/${node_oid}`); + + /* This will be needed for coll node */ + prev_node_id = node_oid; + + /* This will be displayed in the grid */ + return `/${coll_node.label}/`; + } else if(node_type in this.pgBrowser.Nodes) { + /* Add the node to the path */ + id_path.push(`${node_type}/${node_oid}`); + + /* This will be need for coll node id path */ + prev_node_id = node_oid; + + /* Remove the token and replace with slash. This will be displayed in the grid */ + return '/'; + } + prev_node_id = null; + return orig_token; + }); + + /* Remove the slash we had added */ + new_path = new_path.substring(1); + return [new_path, id_path]; + } + + prepareDialog() { + this.showMessage(null); + this.setResultCount(0); + if(this.grid) { + this.grid.destroy(); + this.grid = null; + } + + /* Load types */ + this.setTypes([{ + id: -1, + text: gettext('Loading...'), + value: null, + }], false); + + axios.get( + this.getBaseUrl('types') + ).then((res)=>{ + let types = [{ + id: 'all', + text: 'All types', + }]; + + for (const key of Object.keys(res.data.data).sort()) { + types.push({ + id: key, + text: res.data.data[key], + }); + } + this.setTypes(types); + }).catch(()=>{ + this.setTypes([{ + id: -1, + text: gettext('Failed'), + value: null, + }], false); + }); + } + + main(title) { + this.set('title', title); + } + + setup() { + return { + buttons: [{ + text: '', + key: 112, + className: 'btn btn-secondary pull-left fa fa-question pg-alertify-icon-button', + attrs: { + name: 'dialog_help', + type: 'button', + label: gettext('Help'), + 'aria-label': gettext('Help'), + url: url_for('help.static', { + 'filename': 'search_objects.html', + }), + }, + }, { + text: gettext('Close'), + key: 27, + className: 'btn btn-secondary fa fa-lg fa-times pg-alertify-button', + 'data-btn-name': 'cancel', + }], + // Set options for dialog + options: { + title: this.dialogTitle, + //disable both padding and overflow control. + padding: !1, + overflow: !1, + model: 0, + resizable: true, + maximizable: true, + pinnable: false, + closableByDimmer: false, + modal: false, + }, + }; + } + + build() { + let tmpEle = document.createElement('div'); + tmpEle.innerHTML = this.dialogContainerSelector; + let dialogContainer = tmpEle.firstChild; + + // Append the container + this.elements.content.innerHTML = ''; + this.elements.content.appendChild(dialogContainer); + + this.createDialogDOM(dialogContainer); + this.alertify.pgDialogBuild.apply(this); + + this.loader = dialogContainer.getElementsByClassName('pg-sp-container')[0]; + + this.searchBox = dialogContainer.querySelector('#txtGridSearch'); + this.searchBtn = dialogContainer.querySelector('.btn-search'); + this.typesSelect = dialogContainer.querySelector('.node-types'); + this.searchResultContainer = dialogContainer.querySelector('.search-result-container'); + this.searchResult = dialogContainer.querySelector('.search-result'); + this.searchResultCount = dialogContainer.querySelector('.search-result-count'); + this.statusBar = dialogContainer.querySelector('.pg-prop-status-bar'); + + /* These two values are required to come out of grid when tab is + * pressed in the grid. Slickgrid does not allow any way to come out + */ + this.nextToGrid = this.elements.footer.querySelector('.ajs-button'); + this.prevToGrid = this.typesSelect; + + /* init select2 */ + this.setTypes([{ + id: -1, + text: gettext('Loading...'), + value: null, + }], false); + + /* on search box change */ + this.searchBox.addEventListener('input', ()=>{ + if(this.searchBoxVal().length >= 3) { + this.searchBtnEnabled(true); + } else { + this.searchBtnEnabled(false); + } + }); + + /* on enter key press */ + this.searchBox.addEventListener('keypress', (e)=>{ + if(e.keyCode == 13) { + e.stopPropagation(); + if(this.searchBtnEnabled()) { + this.searchBtn.dispatchEvent(new Event('click')); + } + } + }); + + /* on search button click */ + this.searchBtn.addEventListener('click', ()=>{ + this.searchBtnEnabled(false); + this.setGridData([]); + this.showMessage(null); + + this.setLoading(gettext('Searching....')); + axios.get(this.getBaseUrl('search'), { + params: { + text: this.searchBoxVal(), + type: this.typesVal(), + }, + }).then((res)=>{ + let grid_data = res.data.data.map((row)=>{ + return this.finaliseData(row); + }); + + this.setGridData(grid_data); + }).catch((error)=>{ + let errmsg = ''; + + if (error.response) { + errmsg = error.response.statusText; + } else if (error.request) { + errmsg = gettext('No response received'); + } else { + errmsg = error.message; + } + this.showMessage(gettext('An unexpected occurred: %s', errmsg), true); + console.warn(error); + }).finally(()=>{ + this.setLoading(null); + this.searchBtnEnabled(true); + }); + }); + + this.set({ + 'onresized': this.onDialogResize.bind(this), + 'onmaximized': this.onDialogResize.bind(this), + 'onrestored': this.onDialogResize.bind(this), + 'onshow': this.onDialogShow.bind(this), + }); + } + + prepare() { + let selectedTreeNode = this.getSelectedNode(); + if (!this.getSelectedNodeData(selectedTreeNode)) { + return; + } + + this.treeInfo = getTreeNodeHierarchyFromElement(this.pgBrowser, selectedTreeNode); + this.prepareDialog(); + this.focusOnDialog(this); + } + + callback(event) { + if (this.wasHelpButtonPressed(event)) { + event.cancel = true; + this.pgBrowser.showHelp( + event.button.element.name, + event.button.element.getAttribute('url'), + null, + null, + ); + return; + } + } +} diff --git a/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss b/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss new file mode 100644 index 000000000..86f3eb8a7 --- /dev/null +++ b/web/pgadmin/tools/search_objects/static/scss/_search_objects.scss @@ -0,0 +1,122 @@ +.search_objects_dialog { + height: 100%; + + .object-other-info { + &:hover { + font-weight: bold; + } + } + + .pref-dialog-link { + color: $color-fg !important; + text-decoration: underline !important; + cursor: pointer; + } + + .search-result-container { + width: 100%; + height: 100%; + min-height: 0; + } + + .node-types ~ .select2-container { + min-width: 100%; + } + + .search-result-count { + border-top: $panel-border; + } + + .ui-widget { + font-family: $font-family-primary; + font-size: $font-size-base; + + .slick-header.ui-state-default { + border: $table-border-width solid $table-border-color; + .slick-header-columns { + background: $table-bg; + color: $color-fg; + border-bottom: $panel-border; + + .slick-header-column-sorted { + font-style: unset; + } + + .ui-state-default { + background: $table-bg !important; + color: $color-fg !important; + padding: $table-header-cell-padding $table-cell-padding; + border-right: $table-border-width solid $table-border-color; + + .slick-column-name { + font-weight: bold; + } + + .slick-sort-indicator { + float: unset; + } + } + + .slick-header-sortable { + cursor: pointer !important; + + .slick-sort-indicator-asc { + background: none; + border-top: none; + border-right: 0.25rem solid transparent; + border-bottom: 0.25rem solid $color-fg; + border-left: 0.25rem solid transparent; + } + + .slick-sort-indicator-desc { + background: none; + border-top: 0.25rem solid $color-fg; + border-right: 0.25rem solid transparent; + border-bottom: none; + border-left: 0.25rem solid transparent; + } + } + } + } + .ui-widget-content { + color: $color-fg; + &.slick-row { + &.object-muted { + &.active, &.active:hover, &:hover, & { + .slick-cell { + color: $text-muted !important; + cursor: default !important; + } + } + } + + &.active, &.active:hover { + .slick-cell { + border-top: $table-border-width solid transparent !important; + background-color: $tree-bg-selected !important; + color: $tree-fg-selected !important; + } + } + + &:hover { + cursor: pointer; + .slick-cell { + border-top: $table-border-width solid transparent !important; + border-bottom: $table-border-width solid transparent !important; + background-color: $tree-bg-hover !important; + color: $tree-fg-hover !important; + cursor: pointer !important; + } + } + } + } + } + + + .pg-prop-status-bar { + position: absolute; + bottom: 0; + right: 0; + left: 0; + } +} diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/10_plus/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/10_plus/search.sql new file mode 100644 index 000000000..c6afef675 --- /dev/null +++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/10_plus/search.sql @@ -0,0 +1,435 @@ +{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %} +{% set all_obj = false %} +{% if obj_type == 'all' or obj_type is none %} +{% set all_obj = true %} +{% endif %} +SELECT obj_type, obj_name, + REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path, + schema_name, show_node, other_info, + CASE + WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN + CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END + ELSE 'N' + END AS catalog_level +FROM ( +{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %} + SELECT + CASE + WHEN c.relkind = 'S' THEN 'sequence' + WHEN c.relkind = 'v' THEN 'view' + WHEN c.relkind = 'm' THEN 'mview' + ELSE 'should not happen' + END::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || + CASE + WHEN c.relkind = 'S' THEN ':sequence.' + WHEN c.relkind = 'v' THEN ':view.' + WHEN c.relkind = 'm' THEN ':mview.' + ELSE 'should not happen' + END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name, + CASE + WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }} + WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }} + WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }} + ELSE False + END AS show_node, NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + {% if all_obj %} + WHERE c.relkind in ('S','v','m') + {% elif obj_type == 'sequence' %} + WHERE c.relkind = 'S' + {% elif obj_type == 'view' %} + WHERE c.relkind = 'v' + {% elif obj_type == 'mview' %} + WHERE c.relkind = 'm' + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['table', 'partition'] %} + SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || ( + WITH RECURSIVE table_path_data as ( + select c.oid as oid, 0 as height, + CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) obj_path, n.nspname AS schema_name, + CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }} + ELSE {{ show_node_prefs['table'] }} END AS show_node, + NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind in ('p','r') + {% if obj_type == 'table' %} + AND NOT c.relispartition + {% elif obj_type == 'partition' %} + AND c.relispartition + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['index'] %} + SELECT 'index'::text AS obj_type, cls.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info + FROM pg_index idx + JOIN pg_class cls ON cls.oid=indexrelid + JOIN pg_class tab ON tab.oid=indrelid + JOIN pg_namespace n ON n.oid=tab.relnamespace + LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') + LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) + LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid + LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) + WHERE contype IS NULL +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger_function', 'function'] %} + SELECT + CASE + WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function' + ELSE 'function' END::text AS obj_type, p.proname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || case when t.typname = 'trigger' then ':trigger_function.' else ':function.' end || p.oid ||':/' || p.proname AS obj_path, n.nspname AS schema_name, + CASE WHEN t.typname IN ('trigger', 'event_trigger') THEN {{ show_node_prefs['trigger_function'] }} ELSE {{ show_node_prefs['function'] }} END AS show_node, + pg_catalog.pg_get_function_identity_arguments(p.oid) AS other_info + from pg_proc p + left join pg_namespace n on p.pronamespace = n.oid + left join pg_type t on p.prorettype = t.oid + WHERE ({{ CATALOGS.DB_SUPPORT('n') }}) +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['event_trigger'] %} + select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['schema'] %} + select 'schema'::text AS obj_type, n.nspname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name, + {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n + where {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['column'] %} + select 'column'::text AS obj_type, a.attname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname || '/' || + case + WHEN t.relkind in ('r', 'p') THEN ':table.' + WHEN t.relkind = 'v' THEN ':view.' + WHEN t.relkind = 'm' THEN ':mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info + from pg_attribute a + inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','p','v','m') + left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0 + and not t.relispartition +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %} + SELECT + CASE + WHEN c.contype = 'c' THEN 'check_constraint' + WHEN c.contype = 'f' THEN 'foreign_key' + WHEN c.contype = 'p' THEN 'primary_key' + WHEN c.contype = 'u' THEN 'unique_constraint' + WHEN c.contype = 'x' THEN 'exclusion_constraint' + END::text AS obj_type, + case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name, + ':schema.'||n.oid||':/' || n.nspname||'/'|| + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) || + CASE + WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid + WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid + WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid + WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid + WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid + END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info + from pg_constraint c + left join pg_class t on c.conrelid = t.oid + left join pg_class tf on c.confrelid = tf.oid + left join pg_namespace n on t.relnamespace = n.oid + where c.contypid = 0 + {% if obj_type == 'check_constraint' %} + AND c.contype = 'c' + {% elif obj_type == 'foreign_key' %} + AND c.contype = 'f' + {% elif obj_type == 'primary_key' %} + AND c.contype = 'p' + {% elif obj_type == 'unique_constraint' %} + AND c.contype = 'u' + {% elif obj_type == 'exclusion_constraint' %} + AND c.contype = 'x' + {% else %} + AND c.contype IN ('c', 'f', 'p', 'u', 'x') + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['rule'] %} + select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' || + case + when t.relkind = 'v' then ':view.' + when t.relkind = 'm' then ':mview.' + WHEN t.relkind in ('r', 'p') THEN + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) + end + ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info + from pg_rewrite r + left join pg_class t on r.ev_class = t.oid + left join pg_namespace n on t.relnamespace = n.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger'] %} + select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' || + case + when t.relkind = 'v' then ':view.' + when t.relkind = 'm' then ':mview.' + WHEN t.relkind in ('r', 'p') THEN + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) + end || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info + from pg_trigger tr + left join pg_class t on tr.tgrelid = t.oid + left join pg_namespace n on t.relnamespace = n.oid + where tr.tgisinternal = false + and {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['type'] %} + SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || + '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info + FROM pg_type t + LEFT OUTER JOIN pg_type e ON e.oid=t.typelem + LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' + LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid + WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' + {% if not show_system_objects %} + AND ct.oid is NULL + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['cast'] %} + SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name, + ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info + FROM pg_cast ca + JOIN pg_type st ON st.oid=castsource + JOIN pg_type tt ON tt.oid=casttarget + {% if not show_system_objects %} + WHERE ca.oid > {{last_system_oid}}::OID + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['language'] %} + SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info + FROM pg_language lan + WHERE lanispl IS TRUE +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_configuration'] %} + SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info + FROM pg_ts_config cfg + left join pg_namespace n on cfg.cfgnamespace = n.oid + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_dictionary'] %} + SELECT 'fts_dictionary' AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info + FROM pg_ts_dict dict + left join pg_namespace ns on dict.dictnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_parser'] %} + SELECT 'fts_parser' AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info + FROM pg_ts_parser prs + left join pg_namespace ns on prs.prsnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_template'] %} + SELECT 'fts_template' AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info + FROM pg_ts_template tmpl + left join pg_namespace ns on tmpl.tmplnamespace = ns.oid + AND {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain'] %} + select 'domain' AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info + from pg_type t + inner join pg_namespace n on t.typnamespace = n.oid + where t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain_constraints'] %} + SELECT 'domain_constraints' AS obj_type, + c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info + FROM pg_constraint c JOIN pg_type t + ON t.oid=contypid JOIN pg_namespace n + ON n.oid=t.typnamespace + WHERE t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_data_wrapper'] %} + select 'foreign_data_wrapper' AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info + from pg_foreign_data_wrapper +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_server'] %} + select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info + from pg_foreign_server sr + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['user_mapping'] %} + select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info + from pg_user_mapping um + inner join pg_roles ro on um.umuser = ro.oid + inner join pg_foreign_server sr on um.umserver = sr.oid + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_table'] %} + select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info + from pg_foreign_table ft + inner join pg_class c on ft.ftrelid = c.oid + inner join pg_namespace ns on c.relnamespace = ns.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['extension'] %} + select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info + FROM pg_extension x + JOIN pg_namespace n on x.extnamespace=n.oid + join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['collation'] %} + SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info + FROM pg_collation c + JOIN pg_namespace n ON n.oid=c.collnamespace + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} + +) sn +where lower(sn.obj_name) like '%{{ search_text }}%' +{% if not show_system_objects %} +AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }}) +AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%') +{% endif %} +ORDER BY 1, 2, 3 diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/11_plus/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/11_plus/search.sql new file mode 100644 index 000000000..e9be02279 --- /dev/null +++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/11_plus/search.sql @@ -0,0 +1,452 @@ +{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %} +{% set all_obj = false %} +{% if obj_type == 'all' or obj_type is none %} +{% set all_obj = true %} +{% endif %} +SELECT obj_type, obj_name, + REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path, + schema_name, show_node, other_info, + CASE + WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN + CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END + ELSE 'N' + END AS catalog_level +FROM ( +{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %} + SELECT + CASE + WHEN c.relkind = 'S' THEN 'sequence' + WHEN c.relkind = 'v' THEN 'view' + WHEN c.relkind = 'm' THEN 'mview' + ELSE 'should not happen' + END::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || + CASE + WHEN c.relkind = 'S' THEN ':sequence.' + WHEN c.relkind = 'v' THEN ':view.' + WHEN c.relkind = 'm' THEN ':mview.' + ELSE 'should not happen' + END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name, + CASE + WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }} + WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }} + WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }} + ELSE False + END AS show_node, NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + {% if all_obj %} + WHERE c.relkind in ('S','v','m') + {% elif obj_type == 'sequence' %} + WHERE c.relkind = 'S' + {% elif obj_type == 'view' %} + WHERE c.relkind = 'v' + {% elif obj_type == 'mview' %} + WHERE c.relkind = 'm' + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['table', 'partition'] %} + SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || ( + WITH RECURSIVE table_path_data as ( + select c.oid as oid, 0 as height, + CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) obj_path, n.nspname AS schema_name, + CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }} + ELSE {{ show_node_prefs['table'] }} END AS show_node, + NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind in ('p','r') + {% if obj_type == 'table' %} + AND NOT c.relispartition + {% elif obj_type == 'partition' %} + AND c.relispartition + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['index'] %} + SELECT 'index'::text AS obj_type, cls.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info + FROM pg_index idx + JOIN pg_class cls ON cls.oid=indexrelid + JOIN pg_class tab ON tab.oid=indrelid + JOIN pg_namespace n ON n.oid=tab.relnamespace + LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') + LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) + LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid + LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) + WHERE contype IS NULL +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure'] %} + SELECT + CASE + WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function' + WHEN p.prokind = 'p' THEN 'procedure' + ELSE 'function' + END::text AS obj_type, p.proname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || + CASE + WHEN t.typname IN ('trigger', 'event_trigger') THEN ':trigger_function.' + WHEN p.prokind = 'p' THEN ':procedure.' + ELSE ':function.' + END || p.oid ||':/' || p.proname AS obj_path, n.nspname AS schema_name, + CASE + WHEN t.typname IN ('trigger', 'event_trigger') THEN {{ show_node_prefs['trigger_function'] }} + WHEN p.prokind = 'p' THEN {{ show_node_prefs['procedure'] }} + ELSE {{ show_node_prefs['function'] }} + END AS show_node, + pg_catalog.pg_get_function_identity_arguments(p.oid) AS other_info + from pg_proc p join pg_namespace n + on p.pronamespace = n.oid join pg_type t + on p.prorettype = t.oid join pg_language lng + ON lng.oid=p.prolang + WHERE p.prokind IN ('f', 'w', 'p') + AND CASE + WHEN t.typname IN ('trigger', 'event_trigger') THEN lng.lanname NOT IN ('edbspl', 'sql', 'internal') + ELSE true + END + AND ({{ CATALOGS.DB_SUPPORT('n') }}) +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['event_trigger'] %} + select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['schema'] %} + select 'schema'::text AS obj_type, n.nspname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name, + {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n + where {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['column'] %} + select 'column'::text AS obj_type, a.attname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname || '/' || + case + WHEN t.relkind in ('r', 'p') THEN ':table.' + WHEN t.relkind = 'v' THEN ':view.' + WHEN t.relkind = 'm' THEN ':mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info + from pg_attribute a + inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','p','v','m') + left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0 + and not t.relispartition +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %} + SELECT + CASE + WHEN c.contype = 'c' THEN 'check_constraint' + WHEN c.contype = 'f' THEN 'foreign_key' + WHEN c.contype = 'p' THEN 'primary_key' + WHEN c.contype = 'u' THEN 'unique_constraint' + WHEN c.contype = 'x' THEN 'exclusion_constraint' + END::text AS obj_type, + case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name, + ':schema.'||n.oid||':/' || n.nspname||'/'|| + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) || + CASE + WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid + WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid + WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid + WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid + WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid + END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info + from pg_constraint c + left join pg_class t on c.conrelid = t.oid + left join pg_class tf on c.confrelid = tf.oid + left join pg_namespace n on t.relnamespace = n.oid + where c.contypid = 0 + {% if obj_type == 'check_constraint' %} + AND c.contype = 'c' + {% elif obj_type == 'foreign_key' %} + AND c.contype = 'f' + {% elif obj_type == 'primary_key' %} + AND c.contype = 'p' + {% elif obj_type == 'unique_constraint' %} + AND c.contype = 'u' + {% elif obj_type == 'exclusion_constraint' %} + AND c.contype = 'x' + {% else %} + AND c.contype IN ('c', 'f', 'p', 'u', 'x') + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['rule'] %} + select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' || + case + when t.relkind = 'v' then ':view.' + when t.relkind = 'm' then ':mview.' + WHEN t.relkind in ('r', 'p') THEN + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) + end + ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info + from pg_rewrite r + left join pg_class t on r.ev_class = t.oid + left join pg_namespace n on t.relnamespace = n.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger'] %} + select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' || + case + when t.relkind = 'v' then ':view.' + when t.relkind = 'm' then ':mview.' + WHEN t.relkind in ('r', 'p') THEN + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) + end || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info + from pg_trigger tr + left join pg_class t on tr.tgrelid = t.oid + left join pg_namespace n on t.relnamespace = n.oid + where tr.tgisinternal = false + and {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['type'] %} + SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || + '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info + FROM pg_type t + LEFT OUTER JOIN pg_type e ON e.oid=t.typelem + LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' + LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid + WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' + {% if not show_system_objects %} + AND ct.oid is NULL + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['cast'] %} + SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name, + ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info + FROM pg_cast ca + JOIN pg_type st ON st.oid=castsource + JOIN pg_type tt ON tt.oid=casttarget + {% if not show_system_objects %} + WHERE ca.oid > {{last_system_oid}}::OID + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['language'] %} + SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info + FROM pg_language lan + WHERE lanispl IS TRUE +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_configuration'] %} + SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info + FROM pg_ts_config cfg + left join pg_namespace n on cfg.cfgnamespace = n.oid + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_dictionary'] %} + SELECT 'fts_dictionary' AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info + FROM pg_ts_dict dict + left join pg_namespace ns on dict.dictnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_parser'] %} + SELECT 'fts_parser' AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info + FROM pg_ts_parser prs + left join pg_namespace ns on prs.prsnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_template'] %} + SELECT 'fts_template' AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info + FROM pg_ts_template tmpl + left join pg_namespace ns on tmpl.tmplnamespace = ns.oid + AND {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain'] %} + select 'domain' AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info + from pg_type t + inner join pg_namespace n on t.typnamespace = n.oid + where t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain_constraints'] %} + SELECT 'domain_constraints' AS obj_type, + c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info + FROM pg_constraint c JOIN pg_type t + ON t.oid=contypid JOIN pg_namespace n + ON n.oid=t.typnamespace + WHERE t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_data_wrapper'] %} + select 'foreign_data_wrapper' AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info + from pg_foreign_data_wrapper +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_server'] %} + select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info + from pg_foreign_server sr + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['user_mapping'] %} + select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info + from pg_user_mapping um + inner join pg_roles ro on um.umuser = ro.oid + inner join pg_foreign_server sr on um.umserver = sr.oid + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_table'] %} + select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info + from pg_foreign_table ft + inner join pg_class c on ft.ftrelid = c.oid + inner join pg_namespace ns on c.relnamespace = ns.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['extension'] %} + select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info + FROM pg_extension x + JOIN pg_namespace n on x.extnamespace=n.oid + join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['collation'] %} + SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info + FROM pg_collation c + JOIN pg_namespace n ON n.oid=c.collnamespace + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} + +) sn +where lower(sn.obj_name) like '%{{ search_text }}%' +{% if not show_system_objects %} +AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }}) +AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%') +{% endif %} +ORDER BY 1, 2, 3 diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/default/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/default/search.sql new file mode 100644 index 000000000..b384b316d --- /dev/null +++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/pg/default/search.sql @@ -0,0 +1,367 @@ +{% import 'catalog/pg/macros/catalogs.sql' as CATALOGS %} +{% set all_obj = false %} +{% if obj_type == 'all' or obj_type is none %} +{% set all_obj = true %} +{% endif %} +SELECT obj_type, obj_name, + REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path, + schema_name, show_node, other_info, + CASE + WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN + CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END + ELSE 'N' + END AS catalog_level +FROM ( +{% if all_obj or obj_type in ['table', 'sequence', 'view', 'mview'] %} + SELECT + CASE + WHEN c.relkind = 'r' THEN 'table' + WHEN c.relkind = 'S' THEN 'sequence' + WHEN c.relkind = 'v' THEN 'view' + WHEN c.relkind = 'm' THEN 'mview' + ELSE 'should not happen' + END::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || + CASE + WHEN c.relkind = 'r' THEN ':table.' + WHEN c.relkind = 'S' THEN ':sequence.' + WHEN c.relkind = 'v' THEN ':view.' + WHEN c.relkind = 'm' THEN ':mview.' + ELSE 'should not happen' + END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name, + CASE + WHEN c.relkind = 'r' THEN {{ show_node_prefs['table'] }} + WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }} + WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }} + WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }} + ELSE False + END AS show_node, NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + {% if all_obj %} + WHERE c.relkind in ('r','S','v','m') + {% elif obj_type == 'table' %} + WHERE c.relkind = 'r' + {% elif obj_type == 'sequence' %} + WHERE c.relkind = 'S' + AND {{ CATALOGS.DB_SUPPORT('n') }} + {% elif obj_type == 'view' %} + WHERE c.relkind = 'v' + {% elif obj_type == 'mview' %} + WHERE c.relkind = 'm' + AND {{ CATALOGS.DB_SUPPORT('n') }} + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['index'] %} + SELECT 'index'::text AS obj_type, cls.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info + FROM pg_index idx + JOIN pg_class cls ON cls.oid=indexrelid + JOIN pg_class tab ON tab.oid=indrelid + JOIN pg_namespace n ON n.oid=tab.relnamespace + LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') + LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) + LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid + LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) + WHERE contype IS NULL +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger_function', 'function'] %} + SELECT + CASE + WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function' + ELSE 'function' END::text AS obj_type, p.proname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || case when t.typname = 'trigger' then ':trigger_function.' else ':function.' end || p.oid ||':/' || p.proname AS obj_path, n.nspname AS schema_name, + CASE WHEN t.typname IN ('trigger', 'event_trigger') THEN {{ show_node_prefs['trigger_function'] }} ELSE {{ show_node_prefs['function'] }} END AS show_node, + pg_catalog.pg_get_function_identity_arguments(p.oid) AS other_info + from pg_proc p + left join pg_namespace n on p.pronamespace = n.oid + left join pg_type t on p.prorettype = t.oid + WHERE ({{ CATALOGS.DB_SUPPORT('n') }}) +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['event_trigger'] %} + select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['schema'] %} + select 'schema'::text AS obj_type, n.nspname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name, + {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n + where {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['column'] %} + select 'column'::text AS obj_type, a.attname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname || '/' || + case + WHEN t.relkind = 'r' THEN ':table.' + WHEN t.relkind = 'v' THEN ':view.' + WHEN t.relkind = 'm' THEN ':mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info + from pg_attribute a + inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m') + left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0 +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %} + SELECT + CASE + WHEN c.contype = 'c' THEN 'check_constraint' + WHEN c.contype = 'f' THEN 'foreign_key' + WHEN c.contype = 'p' THEN 'primary_key' + WHEN c.contype = 'u' THEN 'unique_constraint' + WHEN c.contype = 'x' THEN 'exclusion_constraint' + END::text AS obj_type, + case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name, + ':schema.'||n.oid||':/' || n.nspname||'/:table.'|| t.oid || ':/'||t.relname|| + CASE + WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid + WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid + WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid + WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid + WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid + END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info + from pg_constraint c + left join pg_class t on c.conrelid = t.oid + left join pg_class tf on c.confrelid = tf.oid + left join pg_namespace n on t.relnamespace = n.oid + where c.contypid = 0 + {% if obj_type == 'check_constraint' %} + AND c.contype = 'c' + {% elif obj_type == 'foreign_key' %} + AND c.contype = 'f' + {% elif obj_type == 'primary_key' %} + AND c.contype = 'p' + {% elif obj_type == 'unique_constraint' %} + AND c.contype = 'u' + {% elif obj_type == 'exclusion_constraint' %} + AND c.contype = 'x' + {% else %} + AND c.contype IN ('c', 'f', 'p', 'u', 'x') + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['rule'] %} + select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| + case + WHEN t.relkind = 'r' THEN '/:table.' + when t.relkind = 'v' then '/:view.' + when t.relkind = 'm' then '/:mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info + from pg_rewrite r + left join pg_class t on r.ev_class = t.oid + left join pg_namespace n on t.relnamespace = n.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger'] %} + select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| + case + WHEN t.relkind = 'r' THEN '/:table.' + when t.relkind = 'v' then '/:view.' + when t.relkind = 'm' then '/:mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info + from pg_trigger tr + left join pg_class t on tr.tgrelid = t.oid + left join pg_namespace n on t.relnamespace = n.oid + where tr.tgisinternal = false + and {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['type'] %} + SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || + '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info + FROM pg_type t + LEFT OUTER JOIN pg_type e ON e.oid=t.typelem + LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' + LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid + WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' + {% if not show_system_objects %} + AND ct.oid is NULL + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['cast'] %} + SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name, + ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info + FROM pg_cast ca + JOIN pg_type st ON st.oid=castsource + JOIN pg_type tt ON tt.oid=casttarget + {% if not show_system_objects %} + WHERE ca.oid > {{last_system_oid}}::OID + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['language'] %} + SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info + FROM pg_language lan + WHERE lanispl IS TRUE +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_configuration'] %} + SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info + FROM pg_ts_config cfg + left join pg_namespace n on cfg.cfgnamespace = n.oid + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_dictionary'] %} + SELECT 'fts_dictionary'::text AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info + FROM pg_ts_dict dict + left join pg_namespace ns on dict.dictnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_parser'] %} + SELECT 'fts_parser'::text AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info + FROM pg_ts_parser prs + left join pg_namespace ns on prs.prsnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_template'] %} + SELECT 'fts_template'::text AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info + FROM pg_ts_template tmpl + left join pg_namespace ns on tmpl.tmplnamespace = ns.oid + AND {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain'] %} + select 'domain'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info + from pg_type t + inner join pg_namespace n on t.typnamespace = n.oid + where t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain_constraints'] %} + SELECT 'domain_constraints'::text AS obj_type, + c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info + FROM pg_constraint c JOIN pg_type t + ON t.oid=contypid JOIN pg_namespace n + ON n.oid=t.typnamespace + WHERE t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_data_wrapper'] %} + select 'foreign_data_wrapper'::text AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info + from pg_foreign_data_wrapper +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_server'] %} + select 'foreign_server'::text AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info + from pg_foreign_server sr + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['user_mapping'] %} + select 'user_mapping'::text AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info + from pg_user_mapping um + inner join pg_roles ro on um.umuser = ro.oid + inner join pg_foreign_server sr on um.umserver = sr.oid + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_table'] %} + select 'foreign_table'::text AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info + from pg_foreign_table ft + inner join pg_class c on ft.ftrelid = c.oid + inner join pg_namespace ns on c.relnamespace = ns.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['extension'] %} + select 'extension'::text AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info + FROM pg_extension x + JOIN pg_namespace n on x.extnamespace=n.oid + join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['collation'] %} + SELECT 'collation'::text AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info + FROM pg_collation c + JOIN pg_namespace n ON n.oid=c.collnamespace + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} + +) sn +where lower(sn.obj_name) like '%{{ search_text }}%' +{% if not show_system_objects %} +AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }}) +AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%') +{% endif %} +ORDER BY 1, 2, 3 diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/10_plus/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/10_plus/search.sql new file mode 100644 index 000000000..87a32ee66 --- /dev/null +++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/10_plus/search.sql @@ -0,0 +1,493 @@ +{% import 'catalog/ppas/macros/catalogs.sql' as CATALOGS %} +{% set all_obj = false %} +{% if obj_type == 'all' or obj_type is none %} +{% set all_obj = true %} +{% endif %} +SELECT obj_type, obj_name, + REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path, + schema_name, show_node, other_info, + CASE + WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN + CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END + ELSE 'N' + END AS catalog_level +FROM ( +{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %} + SELECT + CASE + WHEN c.relkind = 'S' THEN 'sequence' + WHEN c.relkind = 'v' THEN 'view' + WHEN c.relkind = 'm' THEN 'mview' + ELSE 'should not happen' + END::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || + CASE + WHEN c.relkind = 'S' THEN ':sequence.' + WHEN c.relkind = 'v' THEN ':view.' + WHEN c.relkind = 'm' THEN ':mview.' + ELSE 'should not happen' + END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name, + CASE + WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }} + WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }} + WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }} + ELSE False + END AS show_node, NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + {% if all_obj %} + WHERE c.relkind in ('S','v','m') + {% elif obj_type == 'sequence' %} + WHERE c.relkind = 'S' + {% elif obj_type == 'view' %} + WHERE c.relkind = 'v' + {% elif obj_type == 'mview' %} + WHERE c.relkind = 'm' + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['table', 'partition'] %} + SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || ( + WITH RECURSIVE table_path_data as ( + select c.oid as oid, 0 as height, + CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) obj_path, n.nspname AS schema_name, + CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }} + ELSE {{ show_node_prefs['table'] }} END AS show_node, + NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind in ('p','r') + {% if obj_type == 'table' %} + AND NOT c.relispartition + {% elif obj_type == 'partition' %} + AND c.relispartition + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['index'] %} + SELECT 'index'::text AS obj_type, cls.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info + FROM pg_index idx + JOIN pg_class cls ON cls.oid=indexrelid + JOIN pg_class tab ON tab.oid=indrelid + JOIN pg_namespace n ON n.oid=tab.relnamespace + LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') + LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) + LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid + LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) + WHERE contype IS NULL +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure', 'edbfunc', 'edbproc'] %} + SELECT fd.obj_type, fd.obj_name, + CASE + WHEN fd.obj_type = 'function' THEN + ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:function.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'procedure' THEN + ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:procedure.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'trigger_function' THEN + ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:trigger_function.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'edbfunc' THEN + ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbfunc.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'edbproc' THEN + ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbproc.' || fd.obj_oid ||':/' || fd.obj_name + ELSE NULL + END AS obj_path, + CASE + WHEN fd.obj_type IN ('function', 'procedure', 'trigger_function') THEN fd.schema_name + WHEN fd.obj_type IN ('edbfunc', 'edbproc') THEN fd.next_schema_name + ELSE NULL + END AS schema_name, + CASE + WHEN fd.obj_type = 'function' THEN {{ show_node_prefs['function'] }} + WHEN fd.obj_type = 'procedure' THEN {{ show_node_prefs['procedure'] }} + WHEN fd.obj_type = 'trigger_function' THEN {{ show_node_prefs['trigger_function'] }} + WHEN fd.obj_type = 'edbfunc' THEN {{ show_node_prefs['edbfunc'] }} + WHEN fd.obj_type = 'edbproc' THEN {{ show_node_prefs['edbproc'] }} + ELSE NULL + END AS show_node, other_info + FROM ( + SELECT + CASE + WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function' + WHEN pr.protype = '0'::char THEN + CASE WHEN np.oid IS NOT NULL THEN 'edbfunc' ELSE 'function' END + WHEN pr.protype = '1'::char THEN + CASE WHEN np.oid IS NOT NULL THEN 'edbproc' ELSE 'procedure' END + ELSE null + END::text AS obj_type, pr.proname AS obj_name, pr.oid AS obj_oid, n.oid AS schema_oid, n.nspname AS schema_name, np.oid next_schema_oid, np.nspname next_schema_name, + pg_catalog.pg_get_function_identity_arguments(pr.oid) AS other_info + FROM pg_proc pr left join pg_namespace n + ON pr.pronamespace = n.oid left JOIN pg_namespace np + ON np.oid=n.nspparent left JOIN pg_type t + ON t.oid = pr.prorettype left JOIN pg_language l + ON l.oid = pr.prolang + WHERE NOT (t.typname = 'trigger' AND l.lanname = 'edbspl') + AND ({{ CATALOGS.DB_SUPPORT('n') }} AND {{ CATALOGS.DB_SUPPORT('np') }}) + ) fd + {% if not all_obj %} + WHERE fd.obj_type = '{{ obj_type }}' + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['event_trigger'] %} + select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['schema'] %} + select 'schema'::text AS obj_type, n.nspname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name, + {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n + where n.nspparent = 0 + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['column'] %} + select 'column'::text AS obj_type, a.attname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname || '/' || + case + WHEN t.relkind in ('r', 'p') THEN ':table.' + WHEN t.relkind = 'v' THEN ':view.' + WHEN t.relkind = 'm' THEN ':mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info + from pg_attribute a + inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','p','v','m') + left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0 + and not t.relispartition +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %} + SELECT + CASE + WHEN c.contype = 'c' THEN 'check_constraint' + WHEN c.contype = 'f' THEN 'foreign_key' + WHEN c.contype = 'p' THEN 'primary_key' + WHEN c.contype = 'u' THEN 'unique_constraint' + WHEN c.contype = 'x' THEN 'exclusion_constraint' + END::text AS obj_type, + case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name, + ':schema.'||n.oid||':/' || n.nspname||'/'|| + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) || + CASE + WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid + WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid + WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid + WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid + WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid + END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info + from pg_constraint c + left join pg_class t on c.conrelid = t.oid + left join pg_class tf on c.confrelid = tf.oid + left join pg_namespace n on t.relnamespace = n.oid + where c.contypid = 0 + {% if obj_type == 'check_constraint' %} + AND c.contype = 'c' + {% elif obj_type == 'foreign_key' %} + AND c.contype = 'f' + {% elif obj_type == 'primary_key' %} + AND c.contype = 'p' + {% elif obj_type == 'unique_constraint' %} + AND c.contype = 'u' + {% elif obj_type == 'exclusion_constraint' %} + AND c.contype = 'x' + {% else %} + AND c.contype IN ('c', 'f', 'p', 'u', 'x') + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['rule'] %} + select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' || + case + when t.relkind = 'v' then ':view.' + when t.relkind = 'm' then ':mview.' + WHEN t.relkind in ('r', 'p') THEN + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) + end + ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info + from pg_rewrite r + left join pg_class t on r.ev_class = t.oid + left join pg_namespace n on t.relnamespace = n.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger'] %} + select 'trigger'::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| + case + WHEN t.relkind = 'r' THEN '/:table.' + when t.relkind = 'v' then '/:view.' + when t.relkind = 'm' then '/:mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info + from pg_trigger tr + left join pg_class t on tr.tgrelid = t.oid + left join pg_namespace n on t.relnamespace = n.oid + where tr.tgisinternal = false + and {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['type'] %} + SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || + '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info + FROM pg_type t + LEFT OUTER JOIN pg_type e ON e.oid=t.typelem + LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' + LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid + WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' + {% if not show_system_objects %} + AND ct.oid is NULL + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['cast'] %} + SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name, + ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info + FROM pg_cast ca + JOIN pg_type st ON st.oid=castsource + JOIN pg_type tt ON tt.oid=casttarget + {% if not show_system_objects %} + WHERE ca.oid > {{last_system_oid}}::OID + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['language'] %} + SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info + FROM pg_language lan + WHERE lanispl IS TRUE +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_configuration'] %} + SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info + FROM pg_ts_config cfg + left join pg_namespace n on cfg.cfgnamespace = n.oid + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_dictionary'] %} + SELECT 'fts_dictionary' AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info + FROM pg_ts_dict dict + left join pg_namespace ns on dict.dictnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_parser'] %} + SELECT 'fts_parser' AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info + FROM pg_ts_parser prs + left join pg_namespace ns on prs.prsnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_template'] %} + SELECT 'fts_template' AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info + FROM pg_ts_template tmpl + left join pg_namespace ns on tmpl.tmplnamespace = ns.oid + AND {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain'] %} + select 'domain' AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info + from pg_type t + inner join pg_namespace n on t.typnamespace = n.oid + where t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain_constraints'] %} + SELECT 'domain_constraints' AS obj_type, + c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info + FROM pg_constraint c JOIN pg_type t + ON t.oid=contypid JOIN pg_namespace n + ON n.oid=t.typnamespace + WHERE t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_data_wrapper'] %} + select 'foreign_data_wrapper' AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info + from pg_foreign_data_wrapper +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_server'] %} + select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info + from pg_foreign_server sr + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['user_mapping'] %} + select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info + from pg_user_mapping um + inner join pg_roles ro on um.umuser = ro.oid + inner join pg_foreign_server sr on um.umserver = sr.oid + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_table'] %} + select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info + from pg_foreign_table ft + inner join pg_class c on ft.ftrelid = c.oid + inner join pg_namespace ns on c.relnamespace = ns.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['extension'] %} + select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info + FROM pg_extension x + JOIN pg_namespace n on x.extnamespace=n.oid + join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['collation'] %} + SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info + FROM pg_collation c + JOIN pg_namespace n ON n.oid=c.collnamespace + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['synonym'] %} + SELECT 'synonym' AS obj_type, s.synname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:synonym.'||s.oid||':/' || s.synname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['synonym'] }} AS show_node, NULL AS other_info + FROM pg_synonym s + JOIN pg_namespace n ON n.oid=s.synnamespace + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['package'] %} + SELECT 'package' AS obj_type, p.nspname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['package'] }} AS show_node, NULL AS other_info + FROM pg_namespace p + JOIN pg_namespace n ON n.oid=p.nspparent + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['edbvar'] %} + SELECT 'edbvar' AS obj_type, v.varname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname || '/:edbvar.'||v.oid||':/' || v.varname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['edbvar'] }} AS show_node, NULL AS other_info + FROM edb_variable v JOIN pg_namespace p + ON v.varpackage = p.oid JOIN pg_namespace n + ON p.nspparent = n.oid + WHERE {{ CATALOGS.DB_SUPPORT('p') }} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +) sn +where lower(sn.obj_name) like '%{{ search_text }}%' +{% if not show_system_objects %} +AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }}) +AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%') +{% endif %} +ORDER BY 1, 2, 3 diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/12_plus/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/12_plus/search.sql new file mode 100644 index 000000000..6faf56ad6 --- /dev/null +++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/12_plus/search.sql @@ -0,0 +1,516 @@ +{% import 'catalog/ppas/macros/catalogs.sql' as CATALOGS %} +{% set all_obj = false %} +{% if obj_type == 'all' or obj_type is none %} +{% set all_obj = true %} +{% endif %} +SELECT obj_type, obj_name, + REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path, + schema_name, show_node, other_info, + CASE + WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN + CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END + ELSE 'N' + END AS catalog_level +FROM ( +{% if all_obj or obj_type in ['sequence', 'view', 'mview'] %} + SELECT + CASE + WHEN c.relkind = 'S' THEN 'sequence' + WHEN c.relkind = 'v' THEN 'view' + WHEN c.relkind = 'm' THEN 'mview' + ELSE 'should not happen' + END::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || + CASE + WHEN c.relkind = 'S' THEN ':sequence.' + WHEN c.relkind = 'v' THEN ':view.' + WHEN c.relkind = 'm' THEN ':mview.' + ELSE 'should not happen' + END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name, + CASE + WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }} + WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }} + WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }} + ELSE False + END AS show_node, NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + {% if all_obj %} + WHERE c.relkind in ('S','v','m') + {% elif obj_type == 'sequence' %} + WHERE c.relkind = 'S' + {% elif obj_type == 'view' %} + WHERE c.relkind = 'v' + {% elif obj_type == 'mview' %} + WHERE c.relkind = 'm' + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['table', 'partition'] %} + SELECT CASE WHEN c.relispartition THEN 'partition' ELSE 'table' END::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || ( + WITH RECURSIVE table_path_data as ( + select c.oid as oid, 0 as height, + CASE c.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || c.oid || ':/' || c.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) obj_path, n.nspname AS schema_name, + CASE WHEN c.relispartition THEN {{ show_node_prefs['partition'] }} + ELSE {{ show_node_prefs['table'] }} END AS show_node, + NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind in ('p','r') + {% if obj_type == 'table' %} + AND NOT c.relispartition + {% elif obj_type == 'partition' %} + AND c.relispartition + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['index'] %} + SELECT 'index'::text AS obj_type, cls.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info + FROM pg_index idx + JOIN pg_class cls ON cls.oid=indexrelid + JOIN pg_class tab ON tab.oid=indrelid + JOIN pg_namespace n ON n.oid=tab.relnamespace + LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') + LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) + LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid + LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) + WHERE contype IS NULL +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure', 'edbfunc', 'edbproc'] %} + SELECT fd.obj_type, fd.obj_name, + CASE + WHEN fd.obj_type = 'function' THEN + ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:function.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'procedure' THEN + ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:procedure.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'trigger_function' THEN + ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:trigger_function.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'edbfunc' THEN + ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbfunc.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'edbproc' THEN + ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbproc.' || fd.obj_oid ||':/' || fd.obj_name + ELSE NULL + END AS obj_path, + CASE + WHEN fd.obj_type IN ('function', 'procedure', 'trigger_function') THEN fd.schema_name + WHEN fd.obj_type IN ('edbfunc', 'edbproc') THEN fd.next_schema_name + ELSE NULL + END AS schema_name, + CASE + WHEN fd.obj_type = 'function' THEN {{ show_node_prefs['function'] }} + WHEN fd.obj_type = 'procedure' THEN {{ show_node_prefs['procedure'] }} + WHEN fd.obj_type = 'trigger_function' THEN {{ show_node_prefs['trigger_function'] }} + WHEN fd.obj_type = 'edbfunc' THEN {{ show_node_prefs['edbfunc'] }} + WHEN fd.obj_type = 'edbproc' THEN {{ show_node_prefs['edbproc'] }} + ELSE NULL + END AS show_node, other_info + FROM ( + SELECT + CASE + WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function' + WHEN pr.protype = '0'::char THEN + CASE WHEN np.oid IS NOT NULL THEN 'edbfunc' ELSE 'function' END + WHEN pr.protype = '1'::char THEN + CASE WHEN np.oid IS NOT NULL THEN 'edbproc' ELSE 'procedure' END + ELSE null + END::text AS obj_type, pr.proname AS obj_name, pr.oid AS obj_oid, n.oid AS schema_oid, n.nspname AS schema_name, np.oid next_schema_oid, np.nspname next_schema_name, + pg_catalog.pg_get_function_identity_arguments(pr.oid) AS other_info + FROM pg_proc pr left join pg_namespace n + ON pr.pronamespace = n.oid left JOIN pg_namespace np + ON np.oid=n.nspparent left JOIN pg_type t + ON t.oid = pr.prorettype left JOIN pg_language l + ON l.oid = pr.prolang + WHERE NOT (t.typname = 'trigger' AND l.lanname = 'edbspl') + AND ({{ CATALOGS.DB_SUPPORT('n') }} AND {{ CATALOGS.DB_SUPPORT('np') }}) + ) fd + {% if not all_obj %} + WHERE fd.obj_type = '{{ obj_type }}' + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['event_trigger'] %} + select 'event_trigger'::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['schema'] %} + select 'schema'::text AS obj_type, n.nspname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name, + {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n + where n.nspparent = 0 + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['column'] %} + select 'column'::text AS obj_type, a.attname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname || '/' || + case + WHEN t.relkind in ('r', 'p') THEN ':table.' + WHEN t.relkind = 'v' THEN ':view.' + WHEN t.relkind = 'm' THEN ':mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info + from pg_attribute a + inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','p','v','m') + left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0 + and not t.relispartition +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %} + SELECT + CASE + WHEN c.contype = 'c' THEN 'check_constraint' + WHEN c.contype = 'f' THEN 'foreign_key' + WHEN c.contype = 'p' THEN 'primary_key' + WHEN c.contype = 'u' THEN 'unique_constraint' + WHEN c.contype = 'x' THEN 'exclusion_constraint' + END::text AS obj_type, + case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name, + ':schema.'||n.oid||':/' || n.nspname||'/'|| + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) || + CASE + WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid + WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid + WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid + WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid + WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid + END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info + from pg_constraint c + left join pg_class t on c.conrelid = t.oid + left join pg_class tf on c.confrelid = tf.oid + left join pg_namespace n on t.relnamespace = n.oid + where c.contypid = 0 + {% if obj_type == 'check_constraint' %} + AND c.contype = 'c' + {% elif obj_type == 'foreign_key' %} + AND c.contype = 'f' + {% elif obj_type == 'primary_key' %} + AND c.contype = 'p' + {% elif obj_type == 'unique_constraint' %} + AND c.contype = 'u' + {% elif obj_type == 'exclusion_constraint' %} + AND c.contype = 'x' + {% else %} + AND c.contype IN ('c', 'f', 'p', 'u', 'x') + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['rule'] %} + select 'rule'::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| '/' || + case + when t.relkind = 'v' then ':view.' + when t.relkind = 'm' then ':mview.' + WHEN t.relkind in ('r', 'p') THEN + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) + end + ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info + from pg_rewrite r + left join pg_class t on r.ev_class = t.oid + left join pg_namespace n on t.relnamespace = n.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger', 'compound_trigger'] %} + select + CASE WHEN tr.tgpackageoid != 0 THEN 'compound_trigger' ELSE 'trigger' END::text AS obj_type, tr.tgname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname|| '/' || + case + when t.relkind = 'v' then ':view.' + when t.relkind = 'm' then ':mview.' + WHEN t.relkind in ('r', 'p') THEN + ( + WITH RECURSIVE table_path_data as ( + select t.oid as oid, 0 as height, + CASE t.relispartition WHEN true THEN ':partition.' ELSE ':table.' END || t.oid || ':/' || t.relname as path + union + select rel.oid, pt.height+1 as height, + CASE rel.relispartition WHEN true THEN ':partition.' ELSE ':table.' END + || rel.oid || ':/' || rel.relname || '/' || pt.path as path + from pg_class rel JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + join pg_inherits inh ON inh.inhparent = rel.oid + join table_path_data pt ON inh.inhrelid = pt.oid + ) + select path from table_path_data order by height desc limit 1 + ) + end || CASE WHEN tr.tgpackageoid != 0 THEN '/:compound_trigger.' ELSE '/:trigger.' END || tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name, + CASE WHEN tr.tgpackageoid != 0 THEN {{ show_node_prefs['compound_trigger'] }} ELSE {{ show_node_prefs['trigger'] }} END AS show_node, + NULL AS other_info + from pg_trigger tr + left join pg_class t on tr.tgrelid = t.oid + left join pg_namespace n on t.relnamespace = n.oid + where tr.tgisinternal = false + and {{ CATALOGS.DB_SUPPORT('n') }} + {% if obj_type == 'compound_trigger' %} + AND tr.tgpackageoid != 0 + {% elif obj_type == 'trigger' %} + AND tr.tgpackageoid = 0 + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['type'] %} + SELECT 'type'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || + '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info + FROM pg_type t + LEFT OUTER JOIN pg_type e ON e.oid=t.typelem + LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' + LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid + WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' + {% if not show_system_objects %} + AND ct.oid is NULL + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['cast'] %} + SELECT 'cast'::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name, + ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info + FROM pg_cast ca + JOIN pg_type st ON st.oid=castsource + JOIN pg_type tt ON tt.oid=casttarget + {% if not show_system_objects %} + WHERE ca.oid > {{last_system_oid}}::OID + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['language'] %} + SELECT 'language'::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info + FROM pg_language lan + WHERE lanispl IS TRUE +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_configuration'] %} + SELECT 'fts_configuration'::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info + FROM pg_ts_config cfg + left join pg_namespace n on cfg.cfgnamespace = n.oid + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_dictionary'] %} + SELECT 'fts_dictionary'::text AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info + FROM pg_ts_dict dict + left join pg_namespace ns on dict.dictnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_parser'] %} + SELECT 'fts_parser'::text AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info + FROM pg_ts_parser prs + left join pg_namespace ns on prs.prsnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_template'] %} + SELECT 'fts_template'::text AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info + FROM pg_ts_template tmpl + left join pg_namespace ns on tmpl.tmplnamespace = ns.oid + AND {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain'] %} + select 'domain'::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info + from pg_type t + inner join pg_namespace n on t.typnamespace = n.oid + where t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain_constraints'] %} + SELECT 'domain_constraints'::text AS obj_type, + c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info + FROM pg_constraint c JOIN pg_type t + ON t.oid=contypid JOIN pg_namespace n + ON n.oid=t.typnamespace + WHERE t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_data_wrapper'] %} + select 'foreign_data_wrapper'::text AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info + from pg_foreign_data_wrapper +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_server'] %} + select 'foreign_server' AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info + from pg_foreign_server sr + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['user_mapping'] %} + select 'user_mapping' AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info + from pg_user_mapping um + inner join pg_roles ro on um.umuser = ro.oid + inner join pg_foreign_server sr on um.umserver = sr.oid + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_table'] %} + select 'foreign_table' AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info + from pg_foreign_table ft + inner join pg_class c on ft.ftrelid = c.oid + inner join pg_namespace ns on c.relnamespace = ns.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['extension'] %} + select 'extension' AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info + FROM pg_extension x + JOIN pg_namespace n on x.extnamespace=n.oid + join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['collation'] %} + SELECT 'collation' AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info + FROM pg_collation c + JOIN pg_namespace n ON n.oid=c.collnamespace + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['synonym'] %} + SELECT 'synonym' AS obj_type, s.synname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:synonym.'||s.oid||':/' || s.synname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['synonym'] }} AS show_node, NULL AS other_info + FROM pg_synonym s + JOIN pg_namespace n ON n.oid=s.synnamespace + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['package'] %} + SELECT 'package' AS obj_type, p.nspname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['package'] }} AS show_node, NULL AS other_info + FROM pg_namespace p + JOIN pg_namespace n ON n.oid=p.nspparent + WHERE p.nspcompoundtrigger = false + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['edbvar'] %} + SELECT 'edbvar' AS obj_type, v.varname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname || '/:edbvar.'||v.oid||':/' || v.varname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['edbvar'] }} AS show_node, NULL AS other_info + FROM edb_variable v JOIN pg_namespace p + ON v.varpackage = p.oid JOIN pg_namespace n + ON p.nspparent = n.oid + WHERE p.nspcompoundtrigger = false + AND {{ CATALOGS.DB_SUPPORT('p') }} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +) sn +where lower(sn.obj_name) like '%{{ search_text }}%' +{% if not show_system_objects %} +AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }}) +AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%') +{% endif %} +ORDER BY 1, 2, 3 diff --git a/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/default/search.sql b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/default/search.sql new file mode 100644 index 000000000..7bb126e32 --- /dev/null +++ b/web/pgadmin/tools/search_objects/templates/search_objects/sql/ppas/default/search.sql @@ -0,0 +1,437 @@ +{% import 'catalog/ppas/macros/catalogs.sql' as CATALOGS %} +{% set all_obj = false %} +{% if obj_type == 'all' or obj_type is none %} +{% set all_obj = true %} +{% endif %} +SELECT obj_type, obj_name, + REPLACE(obj_path, '/'||sn.schema_name||'/', '/'||{{ CATALOGS.LABELS_SCHEMACOL('sn.schema_name', _) }}||'/') AS obj_path, + schema_name, show_node, other_info, + CASE + WHEN {{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }} THEN + CASE WHEN {{ CATALOGS.DB_SUPPORT_SCHEMACOL('sn.schema_name') }} THEN 'D' ELSE 'O' END + ELSE 'N' + END AS catalog_level +FROM ( +{% if all_obj or obj_type in ['table', 'sequence', 'view', 'mview'] %} + SELECT + CASE + WHEN c.relkind = 'r' THEN 'table' + WHEN c.relkind = 'S' THEN 'sequence' + WHEN c.relkind = 'v' THEN 'view' + WHEN c.relkind = 'm' THEN 'mview' + ELSE 'should not happen' + END::text::text AS obj_type, c.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/' || + CASE + WHEN c.relkind = 'r' THEN ':table.' + WHEN c.relkind = 'S' THEN ':sequence.' + WHEN c.relkind = 'v' THEN ':view.' + WHEN c.relkind = 'm' THEN ':mview.' + ELSE 'should not happen' + END || c.oid ||':/' || c.relname AS obj_path, n.nspname AS schema_name, + CASE + WHEN c.relkind = 'r' THEN {{ show_node_prefs['table'] }} + WHEN c.relkind = 'S' THEN {{ show_node_prefs['sequence'] }} + WHEN c.relkind = 'v' THEN {{ show_node_prefs['view'] }} + WHEN c.relkind = 'm' THEN {{ show_node_prefs['mview'] }} + ELSE False + END AS show_node, NULL AS other_info + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + {% if all_obj %} + WHERE c.relkind in ('r','S','v','m') + {% elif obj_type == 'table' %} + WHERE c.relkind = 'r' + {% elif obj_type == 'sequence' %} + WHERE c.relkind = 'S' + {% elif obj_type == 'view' %} + WHERE c.relkind = 'v' + {% elif obj_type == 'mview' %} + WHERE c.relkind = 'm' + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['index'] %} + SELECT 'index'::text::text AS obj_type, cls.relname AS obj_name, + ':schema.'|| n.oid || ':/' || n.nspname || '/:table.'|| tab.oid ||':/' || tab.relname || '/:index.'|| cls.oid ||':/' || cls.relname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info + FROM pg_index idx + JOIN pg_class cls ON cls.oid=indexrelid + JOIN pg_class tab ON tab.oid=indrelid + JOIN pg_namespace n ON n.oid=tab.relnamespace + LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') + LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) + LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid + LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) + WHERE contype IS NULL +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger_function', 'function', 'procedure', 'edbfunc', 'edbproc'] %} + SELECT fd.obj_type, fd.obj_name, + CASE + WHEN fd.obj_type = 'function' THEN + ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:function.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'procedure' THEN + ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:procedure.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'trigger_function' THEN + ':schema.'|| fd.schema_oid || ':/' || fd.schema_name || '/:trigger_function.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'edbfunc' THEN + ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbfunc.' || fd.obj_oid ||':/' || fd.obj_name + WHEN fd.obj_type = 'edbproc' THEN + ':schema.'|| fd.next_schema_oid || ':/' || fd.next_schema_name || '/:package.'|| fd.schema_oid || ':/' || fd.schema_name || '/:edbproc.' || fd.obj_oid ||':/' || fd.obj_name + ELSE NULL + END AS obj_path, + CASE + WHEN fd.obj_type IN ('function', 'procedure', 'trigger_function') THEN fd.schema_name + WHEN fd.obj_type IN ('edbfunc', 'edbproc') THEN fd.next_schema_name + ELSE NULL + END AS schema_name, + CASE + WHEN fd.obj_type = 'function' THEN {{ show_node_prefs['function'] }} + WHEN fd.obj_type = 'procedure' THEN {{ show_node_prefs['procedure'] }} + WHEN fd.obj_type = 'trigger_function' THEN {{ show_node_prefs['trigger_function'] }} + WHEN fd.obj_type = 'edbfunc' THEN {{ show_node_prefs['edbfunc'] }} + WHEN fd.obj_type = 'edbproc' THEN {{ show_node_prefs['edbproc'] }} + ELSE NULL + END AS show_node, other_info + FROM ( + SELECT + CASE + WHEN t.typname IN ('trigger', 'event_trigger') THEN 'trigger_function' + WHEN pr.protype = '0'::char THEN + CASE WHEN np.oid IS NOT NULL THEN 'edbfunc' ELSE 'function' END + WHEN pr.protype = '1'::char THEN + CASE WHEN np.oid IS NOT NULL THEN 'edbproc' ELSE 'procedure' END + ELSE null + END::text::text AS obj_type, pr.proname AS obj_name, pr.oid AS obj_oid, n.oid AS schema_oid, n.nspname AS schema_name, np.oid next_schema_oid, np.nspname next_schema_name, + pg_catalog.pg_get_function_identity_arguments(pr.oid) AS other_info + FROM pg_proc pr left join pg_namespace n + ON pr.pronamespace = n.oid left JOIN pg_namespace np + ON np.oid=n.nspparent left JOIN pg_type t + ON t.oid = pr.prorettype left JOIN pg_language l + ON l.oid = pr.prolang + WHERE NOT (t.typname = 'trigger' AND l.lanname = 'edbspl') + AND ({{ CATALOGS.DB_SUPPORT('n') }} AND {{ CATALOGS.DB_SUPPORT('np') }}) + ) fd + {% if not all_obj %} + WHERE fd.obj_type = '{{ obj_type }}' + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['event_trigger'] %} + select 'event_trigger'::text::text AS obj_type, evtname AS obj_name, ':event_trigger.'||oid||':/' || evtname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['index'] }} AS show_node, NULL AS other_info from pg_event_trigger +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['schema'] %} + select 'schema'::text::text AS obj_type, n.nspname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname as obj_path, n.nspname AS schema_name, + {{ show_node_prefs['schema'] }} AS show_node, NULL AS other_info from pg_namespace n + where n.nspparent = 0 + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['column'] %} + select 'column'::text::text AS obj_type, a.attname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname || '/' || + case + WHEN t.relkind = 'r' THEN ':table.' + WHEN t.relkind = 'v' THEN ':view.' + WHEN t.relkind = 'm' THEN ':mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname || '/:column.'|| a.attnum ||':/' || a.attname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['column'] }} AS show_node, NULL AS other_info + from pg_attribute a + inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m') + left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0 +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['constraints', 'check_constraint', 'foreign_key', 'primary_key', 'unique_constraint', 'exclusion_constraint'] %} + SELECT + CASE + WHEN c.contype = 'c' THEN 'check_constraint' + WHEN c.contype = 'f' THEN 'foreign_key' + WHEN c.contype = 'p' THEN 'primary_key' + WHEN c.contype = 'u' THEN 'unique_constraint' + WHEN c.contype = 'x' THEN 'exclusion_constraint' + END::text::text AS obj_type, + case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_name, + ':schema.'||n.oid||':/' || n.nspname||'/:table.'|| t.oid || ':/'||t.relname|| + CASE + WHEN c.contype = 'c' THEN '/:check_constraint.' ||c.oid + WHEN c.contype = 'f' THEN '/:foreign_key.' ||c.conindid + WHEN c.contype = 'p' THEN '/:primary_key.' ||c.conindid + WHEN c.contype = 'u' THEN '/:unique_constraint.' ||c.conindid + WHEN c.contype = 'x' THEN '/:exclusion_constraint.' ||c.conindid + END ||':/'|| case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['constraints'] }} AS show_node, NULL AS other_info + from pg_constraint c + left join pg_class t on c.conrelid = t.oid + left join pg_class tf on c.confrelid = tf.oid + left join pg_namespace n on t.relnamespace = n.oid + where c.contypid = 0 + {% if obj_type == 'check_constraint' %} + AND c.contype = 'c' + {% elif obj_type == 'foreign_key' %} + AND c.contype = 'f' + {% elif obj_type == 'primary_key' %} + AND c.contype = 'p' + {% elif obj_type == 'unique_constraint' %} + AND c.contype = 'u' + {% elif obj_type == 'exclusion_constraint' %} + AND c.contype = 'x' + {% else %} + AND c.contype IN ('c', 'f', 'p', 'u', 'x') + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['rule'] %} + select 'rule'::text::text AS obj_type, r.rulename AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| + case + WHEN t.relkind = 'r' THEN '/:table.' + when t.relkind = 'v' then '/:view.' + when t.relkind = 'm' then '/:mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname ||'/:rule.'||r.oid||':/'|| r.rulename AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['rule'] }} AS show_node, NULL AS other_info + from pg_rewrite r + left join pg_class t on r.ev_class = t.oid + left join pg_namespace n on t.relnamespace = n.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['trigger'] %} + select 'trigger'::text::text AS obj_type, tr.tgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname|| + case + WHEN t.relkind = 'r' THEN '/:table.' + when t.relkind = 'v' then '/:view.' + when t.relkind = 'm' then '/:mview.' + else 'should not happen' + end || t.oid || ':/' || t.relname || '/:trigger.'|| tr.oid || ':/' || tr.tgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['trigger'] }} AS show_node, NULL AS other_info + from pg_trigger tr + left join pg_class t on tr.tgrelid = t.oid + left join pg_namespace n on t.relnamespace = n.oid + where tr.tgisinternal = false + and {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['type'] %} + SELECT 'type'::text::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || + '/:type.'|| t.oid ||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['type'] }} AS show_node, NULL AS other_info + FROM pg_type t + LEFT OUTER JOIN pg_type e ON e.oid=t.typelem + LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' + LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid + WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' + {% if not show_system_objects %} + AND ct.oid is NULL + {% endif %} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['cast'] %} + SELECT 'cast'::text::text AS obj_type, format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_name, + ':cast.'||ca.oid||':/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod) AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['cast'] }} AS show_node, NULL AS other_info + FROM pg_cast ca + JOIN pg_type st ON st.oid=castsource + JOIN pg_type tt ON tt.oid=casttarget + {% if not show_system_objects %} + WHERE ca.oid > {{last_system_oid}}::OID + {% endif %} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['language'] %} + SELECT 'language'::text::text AS obj_type, lanname AS obj_name, ':language.'||lan.oid||':/' || lanname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['language'] }} AS show_node, NULL AS other_info + FROM pg_language lan + WHERE lanispl IS TRUE +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_configuration'] %} + SELECT 'fts_configuration'::text::text AS obj_type, cfg.cfgname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:fts_configuration.'||cfg.oid||':/' || cfg.cfgname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['fts_configuration'] }} AS show_node, NULL AS other_info + FROM pg_ts_config cfg + left join pg_namespace n on cfg.cfgnamespace = n.oid + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_dictionary'] %} + SELECT 'fts_dictionary'::text::text AS obj_type, dict.dictname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_dictionary.'||dict.oid||':/' || dict.dictname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_dictionary'] }} AS show_node, NULL AS other_info + FROM pg_ts_dict dict + left join pg_namespace ns on dict.dictnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_parser'] %} + SELECT 'fts_parser'::text::text AS obj_type, prs.prsname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_parser.'||prs.oid||':/' || prs.prsname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_parser'] }} AS show_node, NULL AS other_info + FROM pg_ts_parser prs + left join pg_namespace ns on prs.prsnamespace = ns.oid + WHERE {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['fts_template'] %} + SELECT 'fts_template'::text::text AS obj_type, tmpl.tmplname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:fts_template.'||tmpl.oid||':/' || tmpl.tmplname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['fts_template'] }} AS show_node, NULL AS other_info + FROM pg_ts_template tmpl + left join pg_namespace ns on tmpl.tmplnamespace = ns.oid + AND {{ CATALOGS.DB_SUPPORT('ns') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain'] %} + select 'domain'::text::text AS obj_type, t.typname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['domain'] }} AS show_node, NULL AS other_info + from pg_type t + inner join pg_namespace n on t.typnamespace = n.oid + where t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['domain_constraints'] %} + SELECT 'domain_constraints'::text::text AS obj_type, + c.conname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:domain.'||t.oid||':/' || t.typname || '/:domain_constraints.'||c.oid||':/' || c.conname AS obj_path, + n.nspname AS schema_name, + {{ show_node_prefs['domain_constraints'] }} AS show_node, NULL AS other_info + FROM pg_constraint c JOIN pg_type t + ON t.oid=contypid JOIN pg_namespace n + ON n.oid=t.typnamespace + WHERE t.typtype = 'd' + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_data_wrapper'] %} + select 'foreign_data_wrapper'::text AS obj_type, fdwname AS obj_name, ':foreign_data_wrapper.'||oid||':/' || fdwname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_data_wrapper'] }} AS show_node, NULL AS other_info + from pg_foreign_data_wrapper +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_server'] %} + select 'foreign_server'::text AS obj_type, sr.srvname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['foreign_server'] }} AS show_node, NULL AS other_info + from pg_foreign_server sr + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['user_mapping'] %} + select 'user_mapping'::text AS obj_type, ro.rolname AS obj_name, ':foreign_data_wrapper.'||fdw.oid||':/' || fdw.fdwname || '/:foreign_server.'||sr.oid||':/' || sr.srvname || '/:user_mapping.'||ro.oid||':/' || ro.rolname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['user_mapping'] }} AS show_node, NULL AS other_info + from pg_user_mapping um + inner join pg_roles ro on um.umuser = ro.oid + inner join pg_foreign_server sr on um.umserver = sr.oid + inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['foreign_table'] %} + select 'foreign_table'::text AS obj_type, c.relname AS obj_name, ':schema.'||ns.oid||':/' || ns.nspname || '/:foreign_table.'||c.oid||':/' || c.relname AS obj_path, ns.nspname AS schema_name, + {{ show_node_prefs['foreign_table'] }} AS show_node, NULL AS other_info + from pg_foreign_table ft + inner join pg_class c on ft.ftrelid = c.oid + inner join pg_namespace ns on c.relnamespace = ns.oid +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['extension'] %} + select 'extension'::text AS obj_type, x.extname AS obj_name, ':extension.'||x.oid||':/' || x.extname AS obj_path, ''::text AS schema_name, + {{ show_node_prefs['extension'] }} AS show_node, NULL AS other_info + FROM pg_extension x + JOIN pg_namespace n on x.extnamespace=n.oid + join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['collation'] %} + SELECT 'collation'::text AS obj_type, c.collname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:collation.'||c.oid||':/' || c.collname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['collation'] }} AS show_node, NULL AS other_info + FROM pg_collation c + JOIN pg_namespace n ON n.oid=c.collnamespace + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['synonym'] %} + SELECT 'synonym'::text AS obj_type, s.synname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:synonym.'||s.oid||':/' || s.synname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['synonym'] }} AS show_node, NULL AS other_info + FROM pg_synonym s + JOIN pg_namespace n ON n.oid=s.synnamespace + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['package'] %} + SELECT 'package'::text AS obj_type, p.nspname AS obj_name, ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['package'] }} AS show_node, NULL AS other_info + FROM pg_namespace p + JOIN pg_namespace n ON n.oid=p.nspparent + WHERE {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +{% if all_obj %} + UNION +{% endif %} +{% if all_obj or obj_type in ['edbvar'] %} + SELECT 'edbvar'::text AS obj_type, v.varname AS obj_name, + ':schema.'||n.oid||':/' || n.nspname || '/:package.'||p.oid||':/' || p.nspname || '/:edbvar.'||v.oid||':/' || v.varname AS obj_path, n.nspname AS schema_name, + {{ show_node_prefs['edbvar'] }} AS show_node, NULL AS other_info + FROM edb_variable v JOIN pg_namespace p + ON v.varpackage = p.oid JOIN pg_namespace n + ON p.nspparent = n.oid + WHERE {{ CATALOGS.DB_SUPPORT('p') }} + AND {{ CATALOGS.DB_SUPPORT('n') }} +{% endif %} +) sn +where lower(sn.obj_name) like '%{{ search_text }}%' +{% if not show_system_objects %} +AND NOT ({{ CATALOGS.IS_CATALOG_SCHEMA('sn.schema_name') }}) +AND (sn.schema_name IS NOT NULL AND sn.schema_name NOT LIKE 'pg\_%') +{% endif %} +ORDER BY 1, 2, 3 diff --git a/web/pgadmin/tools/search_objects/tests/__init__.py b/web/pgadmin/tools/search_objects/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/web/pgadmin/tools/search_objects/tests/test_api_search.py b/web/pgadmin/tools/search_objects/tests/test_api_search.py new file mode 100644 index 000000000..3952006d2 --- /dev/null +++ b/web/pgadmin/tools/search_objects/tests/test_api_search.py @@ -0,0 +1,75 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +from __future__ import print_function +import sys +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression import parent_node_dict +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from regression.python_test_utils import test_utils as utils + +try: + from urllib import urlencode +except Exception as e: + from urllib.parse import urlencode + + +class SearchObjectsApiSearch(BaseTestGenerator): + """ This class will test search API of search objects. """ + scenarios = [ + ('Search with all types', dict(text='emp', type='all', singles=False)), + ('Search with None types', dict(text='emp', type=None, singles=False)), + ('Search for all single types', + dict(text='emp', type=None, singles=True)), + ] + + def runFor(self, text=None, type=None): + url_params = dict( + text=text + ) + if type is not None: + url_params['type'] = type + + url_params = urlencode(url_params) + response = self.tester.get(self.base_url + '?' + url_params) + + self.assertEquals(response.status_code, 200) + + def runTest(self): + database_info = parent_node_dict["database"][-1] + server_id = database_info["server_id"] + db_id = database_info["db_id"] + + db_con = database_utils.connect_database(self, + utils.SERVER_GROUP, + server_id, + db_id) + if not db_con["info"] == "Database connected.": + raise Exception("Could not connect to database to add the schema.") + + self.base_url = '/search_objects/search/' \ + + str(server_id) + '/' + str(db_id) + + if not self.singles: + self.runFor(text=self.text, type=self.type) + else: + # test for all the node types individually + types_url = '/search_objects/types/' +\ + str(server_id) + '/' + str(db_id) + response = self.tester.get(types_url) + self.assertEquals(response.status_code, 200) + types_data = json.loads(response.data.decode('utf-8'))['data'] + + for a_type in types_data: + print('Running search for type {0}'.format(a_type), + file=sys.stderr) + self.runFor(text=self.text, type=a_type) diff --git a/web/pgadmin/tools/search_objects/tests/test_api_types.py b/web/pgadmin/tools/search_objects/tests/test_api_types.py new file mode 100644 index 000000000..aed5571ad --- /dev/null +++ b/web/pgadmin/tools/search_objects/tests/test_api_types.py @@ -0,0 +1,47 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json +from pgadmin.utils.route import BaseTestGenerator +from regression import parent_node_dict +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from regression.python_test_utils import test_utils as utils + + +class SearchObjectsApiTypes(BaseTestGenerator): + """ This class will test types API of search objects. """ + scenarios = [ + # Fetching default URL for schema node. + ('Types API URL', dict(url='/search_objects/types')) + ] + + def runTest(self): + database_info = parent_node_dict["database"][-1] + server_id = database_info["server_id"] + + db_id = database_info["db_id"] + db_con = database_utils.connect_database(self, + utils.SERVER_GROUP, + server_id, + db_id) + if not db_con["info"] == "Database connected.": + raise Exception("Could not connect to database to add the schema.") + + url = self.url + '/' + str(server_id) + '/' + str(db_id) + response = self.tester.get(url) + self.assertEquals(response.status_code, 200) + + # repsonse data should be dict + response_data = json.loads(response.data.decode('utf-8'))['data'] + self.assertEquals(type(response_data), dict) + + # response data key values should not be None + for key, value in response_data.items(): + self.assertIsNotNone(value, 'Key {0} has value None'.format(key)) diff --git a/web/pgadmin/tools/search_objects/tests/test_search_objects_helper.py b/web/pgadmin/tools/search_objects/tests/test_search_objects_helper.py new file mode 100644 index 000000000..ec9c369b9 --- /dev/null +++ b/web/pgadmin/tools/search_objects/tests/test_search_objects_helper.py @@ -0,0 +1,117 @@ +import sys + +from pgadmin.tools.search_objects.utils import SearchObjectsHelper, current_app +from pgadmin.utils.route import BaseTestGenerator + +if sys.version_info < (3, 3): + from mock import patch, MagicMock +else: + from unittest.mock import patch, MagicMock + + +class SearchObjectsHelperTest(BaseTestGenerator): + scenarios = [ + ('scenario', dict( + node_blueprints=[ + dict(node_type='table', coll_label='Tables', + backend_supported=True), + dict(node_type='view', coll_label='Views', + backend_supported=False), + dict(node_type='index', coll_label='Indexes', + backend_supported=True), + dict(node_type='role', coll_label='Roles', + backend_supported=True) + ], + all_node_types=['table', 'view', 'index'], + expected_show_node_prefs=dict(table=True, view=False, index=True), + expected_supported_types=dict(table='Tables', index='Indexes'), + expected_supported_types_skip=dict(table='Tables', view='Views', + index='Indexes'), + execute_dict_return_value=( + True, dict(rows=[ + dict(obj_name='name1', obj_type='table', + obj_path='some/path', show_node=True, + other_info=None, catalog_level='N'), + dict(obj_name='name2', obj_type='view', + obj_path='some1/path', show_node=True, + other_info=None, catalog_level='D'), + dict(obj_name='name3', obj_type='index', + obj_path='some2/path1', show_node=True, + other_info='oid', catalog_level='O'), + ])), + expected_search_op=( + True, [ + dict(name='name1', type='table', type_label='Tables', + path='some/path', + show_node=True, other_info=None, catalog_level='N'), + dict(name='name2', type='view', type_label='Views', + path='some1/path', + show_node=True, other_info=None, catalog_level='D'), + dict(name='name3', type='index', type_label='Indexes', + path='some2/path1', + show_node=True, other_info='oid', catalog_level='O'), + ] + ) + )) + ] + + def __create_manager(self): + connection = MagicMock( + execute_dict=MagicMock(), + db='somedb' + ) + connection.execute_dict.return_value = self.execute_dict_return_value + + def connection_function(did): + return connection + + return MagicMock( + connection=connection_function + ) + + @patch('pgadmin.tools.search_objects.utils.get_node_blueprint') + @patch('pgadmin.tools.search_objects.utils.get_driver') + def runTest(self, get_driver_mock, get_node_blueprint_mock): + manager = self.__create_manager() + + get_driver_mock.return_value = MagicMock( + connection_manager=lambda session_id: manager) + + def __get_node_blueprint_mock(node_type): + blueprints = self.node_blueprints + blueprint = None + for data in blueprints: + if node_type == data['node_type']: + blueprint = MagicMock( + BackendSupported=MagicMock( + return_value=data['backend_supported']), + collection_label=data['coll_label'], + show_node=data['backend_supported'], + ) + return blueprint + + get_node_blueprint_mock.side_effect = __get_node_blueprint_mock + + with self.app.app_context(): + + so_obj = SearchObjectsHelper(2, 18456, + node_types=self.all_node_types) + so_obj.get_sql = MagicMock(return_value='dummy query') + + # test template path + manager.server_type = 'pg' + manager.version = 906000 + self.assertEquals(so_obj.get_template_path(), + 'search_objects/sql/pg/#906000#') + + self.assertEquals(so_obj.get_show_node_prefs(), + self.expected_show_node_prefs) + + self.assertEquals(so_obj.get_supported_types(), + self.expected_supported_types) + + self.assertEquals(so_obj.get_supported_types(skip_check=True), + self.expected_supported_types_skip) + + self.assertEquals(so_obj.search('searchtext', 'all'), + self.expected_search_op) diff --git a/web/pgadmin/tools/search_objects/utils.py b/web/pgadmin/tools/search_objects/utils.py new file mode 100644 index 000000000..cf858d6e2 --- /dev/null +++ b/web/pgadmin/tools/search_objects/utils.py @@ -0,0 +1,131 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +from flask import current_app, render_template +from flask_babelex import gettext + +from pgadmin.utils.driver import get_driver +from config import PG_DEFAULT_DRIVER + + +def get_node_blueprint(node_type): + blueprint = None + node_type = 'NODE-' + node_type + if node_type in current_app.blueprints: + blueprint = current_app.blueprints[node_type] + + return blueprint + + +class SearchObjectsHelper: + def __init__(self, sid, did, show_system_objects=False, node_types=None): + self.sid = sid + self.did = did + self.show_system_objects = show_system_objects + self.manager = get_driver( + PG_DEFAULT_DRIVER + ).connection_manager(sid) + + self._all_node_types = [ + 'cast', 'fts_dictionary', 'check_constraint', + 'exclusion_constraint', 'foreign_key', + 'primary_key', 'unique_constraint', 'constraints', 'trigger', + 'table', 'compound_trigger', 'rule', 'column', 'partition', + 'index', 'type', 'domain', 'domain_constraints', 'schema', + 'synonym', 'sequence', 'edbvar', 'edbfunc', 'edbproc', 'package', + 'foreign_table', 'fts_parser', 'function', 'procedure', + 'trigger_function', 'fts_template', 'collation', 'view', 'mview', + 'fts_configuration', 'extension', 'language', + 'event_trigger', 'foreign_server', 'user_mapping', + 'foreign_data_wrapper' + ] if node_types is None else node_types + + @property + def all_node_types(self): + return self._all_node_types + + def get_template_path(self): + return 'search_objects/sql/{0}/#{1}#'.format( + self.manager.server_type, self.manager.version) + + def get_show_node_prefs(self): + return_types = {} + for node_type in self.all_node_types: + blueprint = get_node_blueprint(node_type) + if blueprint is None: + continue + + return_types[node_type] = blueprint.show_node + return return_types + + def get_supported_types(self, skip_check=False): + return_types = {} + for node_type in self.all_node_types: + blueprint = get_node_blueprint(node_type) + if blueprint is None: + continue + + if blueprint.BackendSupported(self.manager, is_catalog=False, + did=self.did) or skip_check: + if node_type in ['edbfunc', 'edbproc']: + return_types[node_type] =\ + gettext('Package {0}').format( + blueprint.collection_label) + else: + return_types[node_type] = blueprint.collection_label + + return return_types + + def get_sql(self, sql_file, **kwargs): + return render_template( + "/".join([self.get_template_path(), sql_file]), + **kwargs + ) + + def finalize_id_path(self, path, base_path): + if base_path is not None: + path = '{0}/{1}'.format(base_path, path) + + return path + + def search(self, text, obj_type=None): + conn = self.manager.connection(did=self.did) + last_system_oid = (self.manager.db_info[self.did])['datlastsysoid'] \ + if self.manager.db_info is not None and self.did in \ + self.manager.db_info else 0 + + show_node_prefs = self.get_show_node_prefs() + node_labels = self.get_supported_types(skip_check=True) + # Column catalog_level has values as + # N - Not a catalog schema + # D - Catalog schema with DB support - pg_catalog + # O - Catalog schema with object support only - info schema, dbo, sys + status, res = conn.execute_dict( + self.get_sql('search.sql', search_text=text, obj_type=obj_type, + show_system_objects=self.show_system_objects, + show_node_prefs=show_node_prefs, _=gettext, + last_system_oid=last_system_oid) + ) + + if not status: + return status, res + + ret_val = [ + { + 'name': row['obj_name'], + 'type': row['obj_type'], + 'type_label': node_labels[row['obj_type']], + 'path': row['obj_path'], + 'show_node': row['show_node'], + 'other_info': row['other_info'], + 'catalog_level': row['catalog_level'], + } + for row in res['rows'] + ] + return True, ret_val diff --git a/web/pgadmin/tools/sqleditor/static/css/sqleditor.css b/web/pgadmin/tools/sqleditor/static/css/sqleditor.css index 52b821d8b..f9d15b8da 100644 --- a/web/pgadmin/tools/sqleditor/static/css/sqleditor.css +++ b/web/pgadmin/tools/sqleditor/static/css/sqleditor.css @@ -112,7 +112,7 @@ li { font-size: 9pt; } -.slick-header-column.ui-state-default { +#datagrid .slick-header-column.ui-state-default { height: 32px !important; } diff --git a/web/regression/javascript/fake_endpoints.js b/web/regression/javascript/fake_endpoints.js index fa01b3f89..157a34863 100644 --- a/web/regression/javascript/fake_endpoints.js +++ b/web/regression/javascript/fake_endpoints.js @@ -19,5 +19,7 @@ define(function () { 'datagrid.initialize_query_tool_with_did': '/initialize/query_tool///', 'restore.create_job': '/restore/job/', 'datagrid.panel': '/panel/', + 'search_objects.types': '/search_objects/types//', + 'search_objects.search': '/search_objects/search//', }; }); diff --git a/web/regression/javascript/search_objects/search_objects_dialog_spec.js b/web/regression/javascript/search_objects/search_objects_dialog_spec.js new file mode 100644 index 000000000..039db1970 --- /dev/null +++ b/web/regression/javascript/search_objects/search_objects_dialog_spec.js @@ -0,0 +1,155 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import SearchObjectsDialog from 'tools/search_objects/static/js/search_objects_dialog'; +import {TreeFake} from '../tree/tree_fake'; +import MockAdapter from 'axios-mock-adapter'; +import axios from 'axios/index'; + +const context = describe; + +describe('SearchObjectsDialog', () => { + let soDialog; + let pgBrowser; + let jquerySpy; + let alertifySpy; + + beforeEach(() => { + pgBrowser = { + treeMenu: new TreeFake(), + Nodes: { + server: { + hasId: true, + label: 'server', + getTreeNodeHierarchy: jasmine.createSpy('server.getTreeNodeHierarchy'), + }, + database: { + hasId: true, + label: 'database', + getTreeNodeHierarchy: jasmine.createSpy('db.getTreeNodeHierarchy'), + }, + schema: { + hasId: true, + label: 'schema', + getTreeNodeHierarchy: jasmine.createSpy('db.getTreeNodeHierarchy'), + }, + }, + stdW: { + sm: 500, + md: 700, + lg: 900, + default: 500, + }, + stdH: { + sm: 200, + md: 400, + lg: 550, + default: 550, + }, + }; + pgBrowser.Nodes.server.hasId = true; + pgBrowser.Nodes.database.hasId = true; + jquerySpy = jasmine.createSpy('jquerySpy'); + + const hierarchy = { + children: [ + { + id: 'root', + children: [ + { + id: 'serverTreeNode', + data: { + _id: 10, + _type: 'server', + user: {name: 'username'}, + label: 'theserver', + }, + children: [ + { + id: 'some_database', + data: { + _type: 'database', + _id: 11, + label: 'thedatabase', + }, + }, + ], + }, + { + id: 'ppasServer', + data: { + _type: 'server', + server_type: 'ppas', + children: [ + {id: 'someNodeUnderneathPPASServer'}, + ], + }, + }, + ], + }, + ], + }; + + pgBrowser.treeMenu = TreeFake.build(hierarchy); + }); + + describe('#draw', () => { + let networkMock; + beforeEach(() => { + networkMock = new MockAdapter(axios); + alertifySpy = jasmine.createSpyObj('alertify', ['alert', 'dialog']); + alertifySpy['search_objects'] = jasmine.createSpy('search_objects'); + soDialog = new SearchObjectsDialog( + pgBrowser, + jquerySpy, + alertifySpy, + null + ); + + pgBrowser.get_preference = jasmine.createSpy('get_preferences'); + }); + + afterEach(() => { + networkMock.restore(); + }); + + context('there are no ancestors of the type database', () => { + it('does not create a dialog', () => { + pgBrowser.treeMenu.selectNode([{id: 'serverTreeNode'}]); + soDialog.draw(null, null, null); + expect(alertifySpy['search_objects']).not.toHaveBeenCalled(); + }); + + it('display an alert with a Backup Error', () => { + soDialog.draw(null, [{id: 'serverTreeNode'}], null); + expect(alertifySpy.alert).toHaveBeenCalledWith( + 'Search Objects Error', + 'Please select a database or its child node from the browser.' + ); + }); + }); + + context('there is an ancestor of the type database', () => { + let soDialogResizeToSpy; + beforeEach(() => { + soDialogResizeToSpy = jasmine.createSpyObj('soDialogResizeToSpy', ['resizeTo']); + alertifySpy['search_objects'].and + .returnValue(soDialogResizeToSpy); + }); + + it('displays the dialog when database node selected', (done) => { + soDialog.draw(null, [{id: 'some_database'}], null, pgBrowser.stdW.md, pgBrowser.stdH.md); + setTimeout(() => { + expect(alertifySpy['search_objects']).toHaveBeenCalledWith('Search Objects - thedatabase/username@theserver'); + expect(soDialogResizeToSpy.resizeTo).toHaveBeenCalledWith(pgBrowser.stdW.md, pgBrowser.stdH.md); + done(); + }, 0); + }); + }); + }); +}); diff --git a/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js b/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js new file mode 100644 index 000000000..e3c698bb8 --- /dev/null +++ b/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js @@ -0,0 +1,545 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import {TreeFake} from '../tree/tree_fake'; +import SearchObjectsDialogWrapper from 'tools/search_objects/static/js/search_objects_dialog_wrapper'; +import axios from 'axios/index'; +import MockAdapter from 'axios-mock-adapter'; +import {TreeNode} from '../../../pgadmin/static/js/tree/tree'; + +let context = describe; + +describe('SearchObjectsDialogWrapper', () => { + let jquerySpy; + let pgBrowser; + let alertifySpy; + let dialogModelKlassSpy = null; + let backform; + let soDialogWrapper; + let noDataNode; + let serverTreeNode; + let databaseTreeNode; + let viewSchema; + let soJQueryContainerSpy; + let soNodeChildNodeSpy; + let soNode; + + beforeEach(() => { + pgBrowser = { + treeMenu: new TreeFake(), + Nodes: { + server: { + hasId: true, + getTreeNodeHierarchy: jasmine.createSpy('getTreeNodeHierarchy'), + }, + database: { + hasId: true, + getTreeNodeHierarchy: jasmine.createSpy('getTreeNodeHierarchy'), + }, + 'coll-sometype': { + type: 'coll-sometype', + hasId: false, + label: 'Some types coll', + }, + sometype: { + type: 'sometype', + hasId: true, + }, + someothertype: { + type: 'someothertype', + hasId: true, + collection_type: 'coll-sometype', + }, + 'coll-edbfunc': { + type: 'coll-edbfunc', + hasId: true, + label: 'Functions', + }, + 'coll-edbproc': { + type: 'coll-edbfunc', + hasId: true, + label: 'Procedures', + }, + 'coll-edbvar': { + type: 'coll-edbfunc', + hasId: true, + label: 'Variables', + }, + }, + keyboardNavigation: jasmine.createSpyObj('keyboardNavigation', ['getDialogTabNavigator']), + }; + noDataNode = pgBrowser.treeMenu.addNewNode('level1.1', undefined, [{id: 'level1'}]); + serverTreeNode = pgBrowser.treeMenu.addNewNode('level2.1', { + _type: 'server', + _id: 10, + label: 'some-tree-label', + }, [{id: 'level2.1'}]); + databaseTreeNode = new TreeNode('database-tree-node', { + _type: 'database', + _id: 123, + _label: 'some-database-label', + }, [{id: 'database-tree-node'}]); + pgBrowser.treeMenu.addChild(serverTreeNode, databaseTreeNode); + + jquerySpy = jasmine.createSpy('jquerySpy'); + soNode = { + __internal: { + buttons: [{}, {}, {}, { + element: { + disabled: false, + }, + }], + }, + elements: { + body: { + childNodes: [ + {}, + ], + }, + content: jasmine.createSpyObj('content', ['appendChild', 'attr']), + }, + }; + + soJQueryContainerSpy = jasmine.createSpyObj('soJQueryContainer', ['get', 'attr']); + soJQueryContainerSpy.get.and.returnValue(soJQueryContainerSpy); + + viewSchema = {}; + backform = jasmine.createSpyObj('backform', ['generateViewSchema', 'Dialog']); + backform.generateViewSchema.and.returnValue(viewSchema); + + soNodeChildNodeSpy = jasmine.createSpyObj('something', ['addClass']); + jquerySpy.and.callFake((selector) => { + if (selector === '
') { + return soJQueryContainerSpy; + } else if (selector === soNode.elements.body.childNodes[0]) { + return soNodeChildNodeSpy; + } + }); + alertifySpy = jasmine.createSpyObj('alertify', ['alert', 'dialog']); + + }); + + describe('#prepare', () => { + beforeEach(() => { + soDialogWrapper = new SearchObjectsDialogWrapper( + '
', + 'soDialogTitle', + 'search_objects', + jquerySpy, + pgBrowser, + alertifySpy, + dialogModelKlassSpy, + backform + ); + soDialogWrapper = Object.assign(soDialogWrapper, soNode); + spyOn(soDialogWrapper, 'prepareDialog').and.callThrough(); + spyOn(soDialogWrapper, 'setTypes'); + spyOn(soDialogWrapper, 'setResultCount'); + }); + + context('no tree element is selected', () => { + it('does not prepare dialog', () => { + spyOn(soDialogWrapper, 'prepareDialog'); + soDialogWrapper.prepare(); + expect(soDialogWrapper.prepareDialog).not.toHaveBeenCalled(); + }); + }); + + context('selected tree node has no data', () => { + beforeEach(() => { + pgBrowser.treeMenu.selectNode(noDataNode.domNode); + }); + + it('does not prepare the dialog', () => { + spyOn(soDialogWrapper, 'prepareDialog'); + soDialogWrapper.prepare(); + expect(soDialogWrapper.prepareDialog).not.toHaveBeenCalled(); + }); + }); + + context('tree element is selected', () => { + let gridDestroySpy; + let networkMock; + + beforeEach(() => { + pgBrowser.treeMenu.selectNode(databaseTreeNode.domNode); + soDialogWrapper.grid = jasmine.createSpyObj('grid', ['destroy']); + spyOn(soDialogWrapper, 'showMessage'); + gridDestroySpy = spyOn(soDialogWrapper.grid, 'destroy'); + + networkMock = new MockAdapter(axios); + + }); + + afterEach(() => { + networkMock.restore(); + }); + + it('creates dialog and displays it', () => { + soDialogWrapper.prepare(); + expect(soDialogWrapper.prepareDialog).toHaveBeenCalled(); + expect(soDialogWrapper.showMessage).toHaveBeenCalledWith(null); + }); + + + it('if grid set then destroy it', () => { + soDialogWrapper.prepare(); + expect(gridDestroySpy).toHaveBeenCalled(); + expect(soDialogWrapper.grid).toBe(null); + }); + + it('set result count to 0', () => { + soDialogWrapper.prepare(); + expect(soDialogWrapper.setResultCount).toHaveBeenCalledWith(0); + }); + + it('setTypes called before and after the ajax success', (done) => { + networkMock.onGet('/search_objects/types/10/123').reply(200, { + 'data': { + 'type1': 'Type Label 1', + 'type2': 'Type Label 2', + }, + }); + + soDialogWrapper.prepare(); + + expect(soDialogWrapper.setTypes.calls.argsFor(0)).toEqual([ + [{ id: -1, text: 'Loading...', value: null }], false, + ]); + + setTimeout(()=>{ + expect(soDialogWrapper.setTypes.calls.argsFor(1)).toEqual([ + [{id: 'all', text: 'All types'}, + {id: 'type1', text: 'Type Label 1'}, + {id: 'type2', text: 'Type Label 2'}], + ]); + done(); + }, 0); + }); + + it('setTypes called after the ajax fail', (done) => { + networkMock.onGet('/search_objects/types/10/123').reply(500); + + soDialogWrapper.prepare(); + + expect(soDialogWrapper.setTypes.calls.argsFor(0)).toEqual([ + [{ id: -1, text: 'Loading...', value: null }], false, + ]); + + setTimeout(()=>{ + expect(soDialogWrapper.setTypes.calls.argsFor(1)).toEqual([ + [{id: -1, text: 'Failed', value: null }], false, + ]); + done(); + }, 0); + }); + }); + }); + + describe('showMessage', () => { + beforeEach(() => { + soDialogWrapper = new SearchObjectsDialogWrapper( + '
', + 'soDialogTitle', + 'search_objects', + jquerySpy, + pgBrowser, + alertifySpy, + dialogModelKlassSpy, + backform + ); + soDialogWrapper.statusBar = document.createElement('div'); + soDialogWrapper.statusBar.classList.add('d-none'); + document.body.appendChild(soDialogWrapper.statusBar); + }); + + afterEach(() => { + document.body.removeChild(soDialogWrapper.statusBar); + }); + it('when info message', ()=>{ + soDialogWrapper.showMessage('locating', false); + expect(soDialogWrapper.statusBar.classList.contains('d-none')).toBe(false); + expect(soDialogWrapper.statusBar.querySelector('.error-in-footer')).toBe(null); + expect(soDialogWrapper.statusBar.querySelector('.info-in-footer')).not.toBe(null); + expect(soDialogWrapper.statusBar.querySelector('.alert-text').innerHTML).toEqual('locating'); + }); + + it('when error message', ()=>{ + soDialogWrapper.showMessage('some error', true); + expect(soDialogWrapper.statusBar.classList.contains('d-none')).toBe(false); + expect(soDialogWrapper.statusBar.querySelector('.error-in-footer')).not.toBe(null); + expect(soDialogWrapper.statusBar.querySelector('.info-in-footer')).toBe(null); + expect(soDialogWrapper.statusBar.querySelector('.alert-text').innerHTML).toEqual('some error'); + }); + + it('when no message', ()=>{ + soDialogWrapper.showMessage(null); + expect(soDialogWrapper.statusBar.classList.contains('d-none')).toBe(true); + }); + }); + + describe('function', () => { + beforeEach(() => { + soDialogWrapper = new SearchObjectsDialogWrapper( + '
', + 'soDialogTitle', + 'search_objects', + jquerySpy, + pgBrowser, + alertifySpy, + dialogModelKlassSpy, + backform + ); + }); + + it('updateDimOfSearchResult', ()=>{ + soDialogWrapper.searchResultContainer = document.createElement('div'); + soDialogWrapper.searchResult = document.createElement('div'); + spyOn(soDialogWrapper.searchResultContainer, 'getBoundingClientRect').and.returnValue({height:100, width: 50}); + + soDialogWrapper.updateDimOfSearchResult(); + expect(soDialogWrapper.searchResult.style.height).toEqual('100px'); + expect(soDialogWrapper.searchResult.style.width).toEqual('50px'); + }); + + it('setLoading', ()=>{ + soDialogWrapper.loader = document.createElement('div'); + soDialogWrapper.loader.innerHTML = ` +
+ `; + + soDialogWrapper.setLoading('loading'); + expect(soDialogWrapper.loader.classList.contains('d-none')).toBe(false); + expect(soDialogWrapper.loader.querySelector('.pg-sp-text').innerHTML).toEqual('loading'); + + soDialogWrapper.setLoading(null); + expect(soDialogWrapper.loader.classList.contains('d-none')).toBe(true); + }); + + it('searchBtnEnabled', ()=>{ + soDialogWrapper.searchBtn = document.createElement('button'); + + soDialogWrapper.searchBtnEnabled(true); + expect(soDialogWrapper.searchBtn.disabled).toEqual(false); + expect(soDialogWrapper.searchBtnEnabled()).toEqual(true); + + soDialogWrapper.searchBtnEnabled(false); + expect(soDialogWrapper.searchBtn.disabled).toEqual(true); + expect(soDialogWrapper.searchBtnEnabled()).toEqual(false); + }); + + it('searchBoxVal', ()=>{ + soDialogWrapper.searchBox = document.createElement('input'); + soDialogWrapper.searchBoxVal('abc'); + expect(soDialogWrapper.searchBox.value).toEqual('abc'); + expect(soDialogWrapper.searchBoxVal()).toEqual('abc'); + }); + + it('typesVal', ()=>{ + soDialogWrapper.typesSelect = document.createElement('select'); + let opt = document.createElement('option'); + opt.appendChild( document.createTextNode('Some type') ); + opt.value = 'sometype'; + soDialogWrapper.typesSelect.appendChild(opt); + + soDialogWrapper.typesVal('sometype'); + expect(soDialogWrapper.typesSelect.value).toEqual('sometype'); + expect(soDialogWrapper.typesVal()).toEqual('sometype'); + }); + + it('setGridData', ()=>{ + soDialogWrapper.dataview = jasmine.createSpyObj('dataview', ['setItems']); + soDialogWrapper.setGridData([{id:'somedata'}]); + expect(soDialogWrapper.dataview.setItems).toHaveBeenCalled(); + }); + + it('setGridData', ()=>{ + soDialogWrapper.searchResultCount = document.createElement('span'); + + soDialogWrapper.setResultCount(0); + expect(soDialogWrapper.searchResultCount.innerHTML).toEqual('0 matches found.'); + + soDialogWrapper.setResultCount(1); + expect(soDialogWrapper.searchResultCount.innerHTML).toEqual('1 match found.'); + + soDialogWrapper.setResultCount(); + expect(soDialogWrapper.searchResultCount.innerHTML).toEqual('Unknown matches found.'); + }); + + it('onDialogResize', ()=>{ + soDialogWrapper.grid = jasmine.createSpyObj('grid', ['autosizeColumns', 'resizeCanvas']); + spyOn(soDialogWrapper, 'updateDimOfSearchResult'); + + soDialogWrapper.onDialogResize(); + expect(soDialogWrapper.updateDimOfSearchResult).toHaveBeenCalled(); + expect(soDialogWrapper.grid.resizeCanvas).toHaveBeenCalled(); + expect(soDialogWrapper.grid.autosizeColumns).toHaveBeenCalled(); + }); + + it('onDialogShow', (done)=>{ + spyOn(soDialogWrapper, 'prepareGrid').and.callFake(function() { + this.grid = jasmine.createSpyObj('grid', ['init']); + }); + + spyOn(soDialogWrapper, 'focusOnDialog'); + spyOn(soDialogWrapper, 'updateDimOfSearchResult'); + spyOn(soDialogWrapper, 'setGridData'); + spyOn(soDialogWrapper, 'onDialogResize'); + + + soDialogWrapper.onDialogShow(); + setTimeout(()=>{ + expect(soDialogWrapper.prepareGrid).toHaveBeenCalled(); + expect(soDialogWrapper.focusOnDialog).toHaveBeenCalled(); + expect(soDialogWrapper.setGridData).toHaveBeenCalledWith([]); + expect(soDialogWrapper.onDialogResize).toHaveBeenCalled(); + done(); + }, 750); + }); + + context('getCollNode', ()=>{ + it('type have same coll node', ()=>{ + let collNode = soDialogWrapper.getCollNode('sometype'); + expect(collNode.type).toEqual('coll-sometype'); + }); + + it('type does not same coll node', ()=>{ + let collNode = soDialogWrapper.getCollNode('someothertype'); + expect(collNode.type).toEqual('coll-sometype'); + }); + + it('type does not have coll node at all', ()=>{ + let collNode = soDialogWrapper.getCollNode('database'); + expect(collNode).toBe(null); + }); + }); + + it('finaliseData', ()=>{ + spyOn(soDialogWrapper, 'translateSearchObjectsPath').and.returnValue(['disp/path', 'id/path']); + let data = soDialogWrapper.finaliseData({ + name: 'objname', + type: 'sometype', + type_label: 'Some types coll', + path: ':some.123:/path', + show_node: true, + }); + expect(data).toEqual({ + id: 'id/path', + icon: 'icon-sometype', + name: 'objname', + type: 'sometype', + type_label: 'Some types coll', + path: 'disp/path', + id_path: 'id/path', + show_node: true, + }); + }); + + context('translateSearchObjectsPath', ()=>{ + let path = null, catalog_level = null; + beforeEach(()=>{ + pgBrowser.Nodes = { + 'server_group': { + type:'server_group', + label: 'Server group', + }, + 'server': { + type:'server', + label: 'Server', + }, + 'coll-database': { + type:'coll-database', + label: 'Databases', + }, + 'database': { + type:'database', + label: 'Database', + }, + 'coll-schema': { + type:'coll-schema', + label: 'Schemas', + }, + 'schema': { + type:'schema', + label: 'Schema', + }, + 'coll-table': { + type:'coll-table', + label: 'Tables', + }, + 'table': { + type:'table', + label: 'Table', + }, + 'sometype': { + type:'sometype', + label: 'Some type', + collection_type: 'coll-table', + }, + 'coll-catalog': { + type:'coll-catalog', + label: 'Catalogs', + }, + 'catalog': { + type:'catalog', + label: 'Catalog', + }, + 'coll-catalog_object': { + type:'coll-catalog_object', + label: 'Catalog Objects', + }, + 'catalog_object': { + type:'catalog_object', + label: 'catalog object', + }, + }; + + soDialogWrapper.treeInfo = { + 'server_group': {'id': 'server_group/1', '_id': 1}, + 'server': {'id': 'server/3', '_id': 3}, + 'database': {'id': 'database/18456', '_id': 18456}, + }; + }); + it('regular schema', ()=>{ + path = ':schema.2200:/test_db/:table.2604:/sampletab'; + catalog_level = 'N'; + + let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level); + expect(retVal).toEqual([ + 'Schemas/test_db/Tables/sampletab', + ['server_group/1','server/3','coll-database/3','database/18456','coll-schema/18456','schema/2200','coll-table/2200','table/2604'], + ]); + }); + + context('catalog schema', ()=>{ + it('with db support', ()=>{ + path = ':schema.11:/PostgreSQL Catalog (pg_catalog)/:table.2604:/pg_class'; + catalog_level = 'D'; + + let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level); + expect(retVal).toEqual([ + 'Catalogs/PostgreSQL Catalog (pg_catalog)/Tables/pg_class', + ['server_group/1','server/3','coll-database/3','database/18456','coll-catalog/18456','catalog/11','coll-table/11','table/2604'], + ]); + }); + + it('with object support only', ()=>{ + path = ':schema.11:/ANSI (information_schema)/:table.2604:/attributes'; + catalog_level = 'O'; + + let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level); + expect(retVal).toEqual([ + 'Catalogs/ANSI (information_schema)/Catalog Objects/attributes', + ['server_group/1','server/3','coll-database/3','database/18456','coll-catalog/18456','catalog/11','coll-catalog_object/11','catalog_object/2604'], + ]); + }); + }); + }); + }); +}); diff --git a/web/regression/javascript/tree/tree_fake.js b/web/regression/javascript/tree/tree_fake.js index c0c17796a..f476bb272 100644 --- a/web/regression/javascript/tree/tree_fake.js +++ b/web/regression/javascript/tree/tree_fake.js @@ -41,6 +41,9 @@ export class TreeFake extends Tree { this.aciTreeToOurTreeTranslator = {}; this.aciTreeApi = jasmine.createSpyObj( 'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']); + this.aciTreeApi.unload.and.callFake(function(domNode, config) { + config.success(); + }); } addNewNode(id, data, domNode, path) { diff --git a/web/regression/javascript/tree/tree_spec.js b/web/regression/javascript/tree/tree_spec.js index bb607796c..038fcc24c 100644 --- a/web/regression/javascript/tree/tree_spec.js +++ b/web/regression/javascript/tree/tree_spec.js @@ -246,39 +246,70 @@ describe('tree tests', () => { tree.aciTreeApi = jasmine.createSpyObj( 'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']); + tree.aciTreeApi.unload.and.callFake((domNode, config) => { + config.success(); + }); }); - it('reloads the node and its children', () => { - level2.reload(tree); - expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2); + it('reloads the node and its children', (done) => { + level2.reload(tree) + .then(()=>{ + expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2); + done(); + }) + .catch((error)=>{ + fail(error); + }); }); - it('does not reload the children of node', () => { - level2.reload(tree); - expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull(); + it('does not reload the children of node', (done) => { + level2.reload(tree) + .then(()=>{ + expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull(); + done(); + }) + .catch((error)=>{ + fail(error); + }); }); it('select the node', (done) => { - level2.reload(tree); - setTimeout(() => { - expect(tree.selected()).toEqual([{id: 'level2'}]); - done(); - }, 20); + level2.reload(tree) + .then(()=>{ + setTimeout(() => { + expect(tree.selected()).toEqual([{id: 'level2'}]); + done(); + }, 20); + }) + .catch((error)=>{ + fail(error); + }); }); describe('ACITree specific', () => { - it('sets the current node as a Inode, changing the Icon back to +', () => { - level2.reload(tree); - expect(tree.aciTreeApi.setInode).toHaveBeenCalledWith([{id: 'level2'}]); + it('sets the current node as a Inode, changing the Icon back to +', (done) => { + level2.reload(tree) + .then(()=>{ + expect(tree.aciTreeApi.setInode).toHaveBeenCalledWith([{id: 'level2'}]); + done(); + }) + .catch((error)=>{ + fail(error); + }); }); it('deselect the node and selects it again to trigger ACI tree' + ' events', (done) => { - level2.reload(tree); - setTimeout(() => { - expect(tree.aciTreeApi.deselect).toHaveBeenCalledWith([{id: 'level2'}]); - done(); - }, 20); + level2.reload(tree) + .then(()=>{ + setTimeout(() => { + expect(tree.aciTreeApi.deselect).toHaveBeenCalledWith([{id: 'level2'}]); + done(); + }, 20); + }) + .catch((error)=>{ + fail(error); + }); }); }); }); @@ -292,17 +323,32 @@ describe('tree tests', () => { level2 = tree.addNewNode('level2', {data: 'data'}, ['
  • level2
  • '], ['level1']); tree.addNewNode('level3', {data: 'more data'}, ['
  • level3
  • '], ['level1', 'level2']); tree.aciTreeApi = jasmine.createSpyObj('ACITreeApi', ['unload']); + tree.aciTreeApi.unload.and.callFake((domNode, config) => { + config.success(); + }); }); - it('unloads the children of the current node', () => { - level2.unload(tree); - expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2); - expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull(); + it('unloads the children of the current node', (done) => { + level2.unload(tree) + .then(()=>{ + expect(tree.findNodeByDomElement([{id: 'level2'}])).toEqual(level2); + expect(tree.findNodeByDomElement([{id: 'level3'}])).toBeNull(); + done(); + }) + .catch((error)=>{ + fail(error); + }); }); - it('calls unload on the ACI Tree', () => { - level2.unload(tree); - expect(tree.aciTreeApi.unload).toHaveBeenCalledWith(['
  • level2
  • ']); + it('calls unload on the ACI Tree', (done) => { + level2.unload(tree) + .then(()=>{ + expect(tree.aciTreeApi.unload).toHaveBeenCalledWith(['
  • level2
  • '], jasmine.any(Object)); + done(); + }) + .catch((error)=>{ + fail(error); + }); }); }); }); diff --git a/web/webpack.config.js b/web/webpack.config.js index 9fd0a32e9..29811388a 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -494,7 +494,8 @@ module.exports = [{ ',pgadmin.tools.debugger.controller' + ',pgadmin.tools.debugger.direct' + ',pgadmin.node.pga_job' + - ',pgadmin.tools.schema_diff', + ',pgadmin.tools.schema_diff' + + ',pgadmin.tools.search_objects', }, }, { test: require.resolve('snapsvg'), diff --git a/web/webpack.shim.js b/web/webpack.shim.js index fe5a74e53..bca198d6d 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -277,6 +277,8 @@ var webpackShimConfig = { 'pgadmin.tools.restore': path.join(__dirname, './pgadmin/tools/restore/static/js/restore'), 'pgadmin.tools.schema_diff': path.join(__dirname, './pgadmin/tools/schema_diff/static/js/schema_diff'), 'pgadmin.tools.schema_diff_ui': path.join(__dirname, './pgadmin/tools/schema_diff/static/js/schema_diff_ui'), + 'pgadmin.tools.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js/search_objects'), + 'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'), 'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'), 'pgadmin.user_management.current_user': '/user_management/current_user', 'slick.pgadmin.editors': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/editors'), diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index 92f280cbc..b48d104ba 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -105,6 +105,7 @@ module.exports = { 'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'), 'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'), 'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'), + 'tools': path.join(__dirname, './pgadmin/tools/'), }, }, }; diff --git a/web/yarn.lock b/web/yarn.lock index 73002f1c2..9fcfc2d75 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -29,12 +29,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.6.4", "@babel/generator@^7.8.6": - version "7.8.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.8.tgz#cdcd58caab730834cee9eeadb729e833b625da3e" - integrity sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg== +"@babel/generator@^7.6.4", "@babel/generator@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.4.tgz#12441e90c3b3c4159cdecf312075bf1a8ce2dbce" + integrity sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA== dependencies: - "@babel/types" "^7.8.7" + "@babel/types" "^7.9.0" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -54,15 +54,6 @@ "@babel/helper-explode-assignable-expression" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-call-delegate@^7.8.7": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.8.7.tgz#28a279c2e6c622a6233da548127f980751324cab" - integrity sha512-doAA5LAKhsFCR0LAFIf+r2RSMmC+m8f/oQ+URnUET/rWeEzC0yTRmAGyWkD4sSu3xwbS7MYQ2u+xlt1V5R56KQ== - dependencies: - "@babel/helper-hoist-variables" "^7.8.3" - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.7" - "@babel/helper-create-regexp-features-plugin@^7.8.3", "@babel/helper-create-regexp-features-plugin@^7.8.8": version "7.8.8" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz#5d84180b588f560b7864efaeea89243e58312087" @@ -126,17 +117,17 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-module-transforms@^7.8.3": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz#6a13b5eecadc35692047073a64e42977b97654a4" - integrity sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg== +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== dependencies: "@babel/helper-module-imports" "^7.8.3" "@babel/helper-replace-supers" "^7.8.6" "@babel/helper-simple-access" "^7.8.3" "@babel/helper-split-export-declaration" "^7.8.3" "@babel/template" "^7.8.6" - "@babel/types" "^7.8.6" + "@babel/types" "^7.9.0" lodash "^4.17.13" "@babel/helper-optimise-call-expression@^7.8.3": @@ -194,6 +185,11 @@ dependencies: "@babel/types" "^7.8.3" +"@babel/helper-validator-identifier@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" + integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw== + "@babel/helper-wrap-function@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610" @@ -205,27 +201,27 @@ "@babel/types" "^7.8.3" "@babel/helpers@^7.6.2": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73" - integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w== + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== dependencies: "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" "@babel/highlight@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" - integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== dependencies: + "@babel/helper-validator-identifier" "^7.9.0" chalk "^2.0.0" - esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.6.4", "@babel/parser@^7.8.6": - version "7.8.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.8.tgz#4c3b7ce36db37e0629be1f0d50a571d2f86f6cd4" - integrity sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA== +"@babel/parser@^7.6.4", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" + integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.8.3" @@ -253,9 +249,9 @@ "@babel/plugin-syntax-json-strings" "^7.8.0" "@babel/plugin-proposal-object-rest-spread@^7.6.2": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb" - integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz#a28993699fc13df165995362693962ba6b061d6f" + integrity sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow== dependencies: "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" @@ -343,9 +339,9 @@ lodash "^4.17.13" "@babel/plugin-transform-classes@^7.5.5": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.6.tgz#77534447a477cbe5995ae4aee3e39fbc8090c46d" - integrity sha512-k9r8qRay/R6v5aWZkrEclEhKO6mc1CCQr2dLsVHBmOQiMpN6I2bpjX3vgnldUWeEI1GHVNByULVxZ4BdP4Hmdg== + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz#8603fc3cc449e31fdbdbc257f67717536a11af8d" + integrity sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ== dependencies: "@babel/helper-annotate-as-pure" "^7.8.3" "@babel/helper-define-map" "^7.8.3" @@ -394,9 +390,9 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-for-of@^7.4.4": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.6.tgz#a051bd1b402c61af97a27ff51b468321c7c2a085" - integrity sha512-M0pw4/1/KI5WAxPsdcUL/w2LJ7o89YHN3yLkzNjg7Yl15GlVGgzHyCU+FMeAxevHGsLVmUqbirlUIKTafPmzdw== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz#0f260e27d3e29cd1bb3128da5e76c761aa6c108e" + integrity sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ== dependencies: "@babel/helper-plugin-utils" "^7.8.3" @@ -423,40 +419,40 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-modules-amd@^7.5.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz#65606d44616b50225e76f5578f33c568a0b876a5" - integrity sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz#19755ee721912cf5bb04c07d50280af3484efef4" + integrity sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q== dependencies: - "@babel/helper-module-transforms" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" "@babel/plugin-transform-modules-commonjs@^7.6.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz#df251706ec331bd058a34bdd72613915f82928a5" - integrity sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz#e3e72f4cbc9b4a260e30be0ea59bdf5a39748940" + integrity sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g== dependencies: - "@babel/helper-module-transforms" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-simple-access" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" "@babel/plugin-transform-modules-systemjs@^7.5.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz#d8bbf222c1dbe3661f440f2f00c16e9bb7d0d420" - integrity sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz#e9fd46a296fc91e009b64e07ddaa86d6f0edeb90" + integrity sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ== dependencies: "@babel/helper-hoist-variables" "^7.8.3" - "@babel/helper-module-transforms" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" "@babel/plugin-transform-modules-umd@^7.2.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz#592d578ce06c52f5b98b02f913d653ffe972661a" - integrity sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz#e909acae276fec280f9b821a5f38e1f08b480697" + integrity sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ== dependencies: - "@babel/helper-module-transforms" "^7.8.3" + "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-named-capturing-groups-regex@^7.6.3": @@ -482,11 +478,10 @@ "@babel/helper-replace-supers" "^7.8.3" "@babel/plugin-transform-parameters@^7.4.4": - version "7.8.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.8.tgz#0381de466c85d5404565243660c4496459525daf" - integrity sha512-hC4Ld/Ulpf1psQciWWwdnUspQoQco2bMzSrwU6TmzRlvoYQe4rQFy9vnCZDTlVeCQj0JPfL+1RX0V8hCJvkgBA== + version "7.9.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz#3028d0cc20ddc733166c6e9c8534559cee09f54a" + integrity sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg== dependencies: - "@babel/helper-call-delegate" "^7.8.7" "@babel/helper-get-function-arity" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" @@ -613,9 +608,9 @@ semver "^5.5.0" "@babel/runtime@^7.8.4": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.7.tgz#8fefce9802db54881ba59f90bb28719b4996324d" - integrity sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg== + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06" + integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q== dependencies: regenerator-runtime "^0.13.4" @@ -628,27 +623,27 @@ "@babel/parser" "^7.8.6" "@babel/types" "^7.8.6" -"@babel/traverse@^7.6.3", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.6.tgz#acfe0c64e1cd991b3e32eae813a6eb564954b5ff" - integrity sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A== +"@babel/traverse@^7.6.3", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892" + integrity sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.6" + "@babel/generator" "^7.9.0" "@babel/helper-function-name" "^7.8.3" "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.8.6" - "@babel/types" "^7.8.6" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.0" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.6.3", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.8.7": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.7.tgz#1fc9729e1acbb2337d5b6977a63979b4819f5d1d" - integrity sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw== +"@babel/types@^7.6.3", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" + integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng== dependencies: - esutils "^2.0.2" + "@babel/helper-validator-identifier" "^7.9.0" lodash "^4.17.13" to-fast-properties "^2.0.0" @@ -665,159 +660,158 @@ integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== "@types/node@*": - version "13.9.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349" - integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg== + version "13.11.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b" + integrity sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ== "@types/q@^1.5.1": version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== -"@webassemblyjs/ast@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" - integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== dependencies: - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" -"@webassemblyjs/floating-point-hex-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" - integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== -"@webassemblyjs/helper-api-error@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" - integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== -"@webassemblyjs/helper-buffer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" - integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== -"@webassemblyjs/helper-code-frame@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" - integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== dependencies: - "@webassemblyjs/wast-printer" "1.8.5" + "@webassemblyjs/wast-printer" "1.9.0" -"@webassemblyjs/helper-fsm@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" - integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== -"@webassemblyjs/helper-module-context@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" - integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== dependencies: - "@webassemblyjs/ast" "1.8.5" - mamacro "^0.0.3" + "@webassemblyjs/ast" "1.9.0" -"@webassemblyjs/helper-wasm-bytecode@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" - integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== -"@webassemblyjs/helper-wasm-section@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" - integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" -"@webassemblyjs/ieee754@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" - integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" - integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" - integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== -"@webassemblyjs/wasm-edit@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" - integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/helper-wasm-section" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-opt" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" - "@webassemblyjs/wast-printer" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" -"@webassemblyjs/wasm-gen@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" - integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" -"@webassemblyjs/wasm-opt@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" - integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-buffer" "1.8.5" - "@webassemblyjs/wasm-gen" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" -"@webassemblyjs/wasm-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" - integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-wasm-bytecode" "1.8.5" - "@webassemblyjs/ieee754" "1.8.5" - "@webassemblyjs/leb128" "1.8.5" - "@webassemblyjs/utf8" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" -"@webassemblyjs/wast-parser@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" - integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/floating-point-hex-parser" "1.8.5" - "@webassemblyjs/helper-api-error" "1.8.5" - "@webassemblyjs/helper-code-frame" "1.8.5" - "@webassemblyjs/helper-fsm" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" - integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/wast-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -843,6 +837,11 @@ JSONStream@^1.0.3: jsonparse "^1.2.0" through ">=2.2.7 <3" +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + accepts@~1.3.4, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -919,7 +918,7 @@ ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.9.1: "alertifyjs@git+https://github.com/EnterpriseDB/AlertifyJS/#72c1d794f5b6d4ec13a68d123c08f19021afe263": version "1.7.1" - resolved "git+https://github.com/EnterpriseDB/AlertifyJS.git#72c1d794f5b6d4ec13a68d123c08f19021afe263" + resolved "git+https://github.com/EnterpriseDB/AlertifyJS/#72c1d794f5b6d4ec13a68d123c08f19021afe263" alphanum-sort@^1.0.0: version "1.0.2" @@ -979,7 +978,7 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -aproba@^1.1.1: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== @@ -996,6 +995,14 @@ archive-type@^4.0.0: dependencies: file-type "^4.2.0" +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.6, argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1100,24 +1107,25 @@ atob@^2.1.2: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== autoprefixer@^9.6.4: - version "9.7.4" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.4.tgz#f8bf3e06707d047f0641d87aee8cfb174b2a5378" - integrity sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g== + version "9.7.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.7.5.tgz#8df10b9ff9b5814a8d411a5cfbab9c793c392376" + integrity sha512-URo6Zvt7VYifomeAfJlMFnYDhow1rk2bufwkbamPEAtQFcL11moLk4PnR7n9vlu7M+BkXAZkHFA0mIcY7tjQFg== dependencies: - browserslist "^4.8.3" - caniuse-lite "^1.0.30001020" + browserslist "^4.11.0" + caniuse-lite "^1.0.30001036" chalk "^2.4.2" normalize-range "^0.1.2" num2fraction "^1.2.2" - postcss "^7.0.26" - postcss-value-parser "^4.0.2" + postcss "^7.0.27" + postcss-value-parser "^4.0.3" axios-mock-adapter@^1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.17.0.tgz#0dbee43c606d4aaba5a43d88d96d6661a7cc3c04" - integrity sha512-q3efmwJUOO4g+wsLNSk9Ps1UlJoF3fQ3FSEe4uEEhkRtu7SoiAVPj8R3Hc/WP55MBTVFzaDP9QkdJhdVhP8A1Q== + version "1.18.1" + resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.18.1.tgz#a2ba2638ef513d954793f96bde3e26bd4a1b7940" + integrity sha512-kFBZsG1Ma5yxjRGHq5KuuL55mPb7WzFULhypquEhzPg8SH5CXICb+qwC2CCA5u+GQVpiqGPwKSRkd3mBCs6gdw== dependencies: - deep-equal "^1.0.1" + fast-deep-equal "^3.1.1" + is-buffer "^2.0.3" axios@^0.18.1: version "0.18.1" @@ -1887,7 +1895,61 @@ browserify-zlib@^0.2.0, browserify-zlib@~0.2.0: dependencies: pako "~1.0.5" -browserify@^16.1.0, browserify@~16.2.3: +browserify@^16.1.0: + version "16.5.1" + resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.5.1.tgz#3c13c97436802930d5c3ae28658ddc33bfd37dc2" + integrity sha512-EQX0h59Pp+0GtSRb5rL6OTfrttlzv+uyaUVlK6GX3w11SQ0jKPKyjC/54RhPR2ib2KmfcELM06e8FxcI5XNU2A== + dependencies: + JSONStream "^1.0.3" + assert "^1.4.0" + browser-pack "^6.0.1" + browser-resolve "^1.11.0" + browserify-zlib "~0.2.0" + buffer "~5.2.1" + cached-path-relative "^1.0.0" + concat-stream "^1.6.0" + console-browserify "^1.1.0" + constants-browserify "~1.0.0" + crypto-browserify "^3.0.0" + defined "^1.0.0" + deps-sort "^2.0.0" + domain-browser "^1.2.0" + duplexer2 "~0.1.2" + events "^2.0.0" + glob "^7.1.0" + has "^1.0.0" + htmlescape "^1.1.0" + https-browserify "^1.0.0" + inherits "~2.0.1" + insert-module-globals "^7.0.0" + labeled-stream-splicer "^2.0.0" + mkdirp-classic "^0.5.2" + module-deps "^6.0.0" + os-browserify "~0.3.0" + parents "^1.0.1" + path-browserify "~0.0.0" + process "~0.11.0" + punycode "^1.3.2" + querystring-es3 "~0.2.0" + read-only-stream "^2.0.0" + readable-stream "^2.0.2" + resolve "^1.1.4" + shasum "^1.0.0" + shell-quote "^1.6.1" + stream-browserify "^2.0.0" + stream-http "^3.0.0" + string_decoder "^1.1.1" + subarg "^1.0.0" + syntax-error "^1.1.1" + through2 "^2.0.0" + timers-browserify "^1.0.1" + tty-browserify "0.0.1" + url "~0.11.0" + util "~0.10.1" + vm-browserify "^1.0.0" + xtend "^4.0.0" + +browserify@~16.2.3: version "16.2.3" resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.2.3.tgz#7ee6e654ba4f92bce6ab3599c3485b1cc7a0ad0b" integrity sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ== @@ -1941,15 +2003,15 @@ browserify@^16.1.0, browserify@~16.2.3: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.8.3: - version "4.10.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.10.0.tgz#f179737913eaf0d2b98e4926ac1ca6a15cbcc6a9" - integrity sha512-TpfK0TDgv71dzuTsEAlQiHeWQ/tiPqgNZVdv046fvNtBZrjbv2O3TsWCDU0AWGJJKCF/KsjNdLzR9hXOsh/CfA== +browserslist@^4.0.0, browserslist@^4.11.0, browserslist@^4.6.0, browserslist@^4.8.3: + version "4.11.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.11.1.tgz#92f855ee88d6e050e7e7311d987992014f1a1f1b" + integrity sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g== dependencies: - caniuse-lite "^1.0.30001035" - electron-to-chromium "^1.3.378" - node-releases "^1.1.52" - pkg-up "^3.1.0" + caniuse-lite "^1.0.30001038" + electron-to-chromium "^1.3.390" + node-releases "^1.1.53" + pkg-up "^2.0.0" buffer-alloc-unsafe@^1.1.0: version "1.1.0" @@ -2001,6 +2063,14 @@ buffer@^5.0.2, buffer@^5.2.1: base64-js "^1.0.2" ieee754 "^1.1.4" +buffer@~5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" + integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -2012,9 +2082,9 @@ bytes@3.1.0: integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== cacache@^12.0.2, cacache@^12.0.3: - version "12.0.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" - integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw== + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== dependencies: bluebird "^3.5.5" chownr "^1.1.1" @@ -2146,10 +2216,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001020, caniuse-lite@^1.0.30001035: - version "1.0.30001035" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz#2bb53b8aa4716b2ed08e088d4dc816a5fe089a1e" - integrity sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001036, caniuse-lite@^1.0.30001038: + version "1.0.30001039" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz#b3814a1c38ffeb23567f8323500c09526a577bbe" + integrity sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q== caw@^2.0.0, caw@^2.0.1: version "2.0.1" @@ -2191,7 +2261,22 @@ check-types@^8.0.3: resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== -"chokidar@>=2.0.0 <4.0.0", chokidar@^2.0.2, chokidar@^2.1.1: +"chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" + integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.3.0" + optionalDependencies: + fsevents "~2.1.2" + +chokidar@^2.1.1, chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== @@ -2210,21 +2295,6 @@ check-types@^8.0.3: optionalDependencies: fsevents "^1.2.7" -chokidar@^3.0.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" - integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.3.0" - optionalDependencies: - fsevents "~2.1.2" - chownr@^1.1.1, chownr@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -2306,10 +2376,15 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + codemirror@^5.50.0: - version "5.52.0" - resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.52.0.tgz#4dbd6aef7f0e63db826b9a23922f0c03ac75c0a7" - integrity sha512-K2UB6zjscrfME03HeRe/IuOmCeqNpw7PLKGHThYpLbZEuKf+ZoujJPhxZN4hHJS1O7QyzEsV7JJZGxuQWVaFCg== + version "5.52.2" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.52.2.tgz#c29e1f7179f85eb0dd17c0586fa810e4838ff584" + integrity sha512-WCGCixNUck2HGvY8/ZNI1jYfxPG5cRHv0VjmWuNzbtCLz8qYA5d+je4QhSSCtCaagyeOwMi/HmmPTjBgiTm2lQ== collection-visit@^1.0.0: version "1.0.0" @@ -2326,11 +2401,16 @@ color-convert@^1.9.0, color-convert@^1.9.1: dependencies: color-name "1.1.3" -color-name@1.1.3, color-name@^1.0.0: +color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + color-string@^1.5.2: version "1.5.3" resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" @@ -2442,6 +2522,11 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + console-stream@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/console-stream/-/console-stream-0.1.1.tgz#a095fe07b20465955f2fafd28b5d72bccd949d44" @@ -2464,7 +2549,14 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.1.0, convert-source-map@^1.1.3, convert-source-map@~1.1.0: +convert-source-map@^1.1.0, convert-source-map@^1.1.3: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + dependencies: + safe-buffer "~5.1.1" + +convert-source-map@~1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" integrity sha1-SCnId+n+SbMWHzvzZziI4gRpmGA= @@ -2679,6 +2771,14 @@ css-tree@1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" +css-tree@1.0.0-alpha.39: + version "1.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" + integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== + dependencies: + mdn-data "2.0.6" + source-map "^0.6.1" + css-what@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" @@ -2758,11 +2858,11 @@ cssnano@^4.1.10: postcss "^7.0.0" csso@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.2.tgz#e5f81ab3a56b8eefb7f0092ce7279329f454de3d" - integrity sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg== + version "4.0.3" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" + integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== dependencies: - css-tree "1.0.0-alpha.37" + css-tree "1.0.0-alpha.39" cubic2quad@^1.0.0: version "1.1.1" @@ -2819,7 +2919,7 @@ debug@=3.1.0, debug@~3.1.0: dependencies: ms "2.0.0" -debug@^3.2.6: +debug@^3.0.0, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -2890,9 +2990,9 @@ decompress-unzip@^4.0.1: yauzl "^2.4.2" decompress@^4.0.0, decompress@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.0.tgz#7aedd85427e5a92dacfe55674a7c505e96d01f9d" - integrity sha1-eu3YVCflqS2s/lVnSnxQXpbQH50= + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== dependencies: decompress-tar "^4.0.0" decompress-tarbz2 "^4.0.0" @@ -2903,17 +3003,10 @@ decompress@^4.0.0, decompress@^4.2.0: pify "^2.3.0" strip-dirs "^2.0.0" -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== deep-is@~0.1.3: version "0.1.3" @@ -2954,6 +3047,11 @@ defined@^1.0.0: resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -2987,6 +3085,11 @@ detect-file@^1.0.0: resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + detective@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" @@ -3150,14 +3253,14 @@ ejs@^2.6.1: integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== ejs@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.0.1.tgz#30c8f6ee9948502cc32e85c37a3f8b39b5a614a5" - integrity sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw== + version "3.0.2" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.0.2.tgz#745b01cdcfe38c1c6a2da3bbb2d9957060a31226" + integrity sha512-IncmUpn1yN84hy2shb0POJ80FWrfGNY0cxO9f4v+/sG7qcBvAtVWUA1IdzY/8EYUmOVhoKJVdJjNd3AZcnxOjA== -electron-to-chromium@^1.3.378: - version "1.3.379" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.379.tgz#81dc5e82a3e72bbb830d93e15bc35eda2bbc910e" - integrity sha512-NK9DBBYEBb5f9D7zXI0hiE941gq3wkBeQmXs1ingigA/jnTg5mhwY2Z5egwA+ZI8OLGKCx0h1Cl8/xeuIBuLlg== +electron-to-chromium@^1.3.390: + version "1.3.397" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.397.tgz#db640c2e67b08d590a504c20b56904537aa2bafa" + integrity sha512-zcUd1p/7yzTSdWkCTrqGvbnEOASy96d0RJL/lc5BDJoO23Z3G/VHd0yIPbguDU9n8QNUTCigLO7oEdtOb7fp2A== elliptic@^6.0.0: version "6.5.2" @@ -3281,10 +3384,10 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: - version "1.17.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" - integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: + version "1.17.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" + integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== dependencies: es-to-primitive "^1.2.1" function-bind "^1.1.1" @@ -3394,11 +3497,11 @@ esprima@^4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.1.0.tgz#c5c0b66f383e7656404f86b31334d72524eddb48" - integrity sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q== + version "1.2.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.2.0.tgz#a010a519c0288f2530b3404124bfb5f02e9797fe" + integrity sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q== dependencies: - estraverse "^4.0.0" + estraverse "^5.0.0" esrecurse@^4.1.0: version "4.2.1" @@ -3407,11 +3510,16 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: +estraverse@^4.1.0, estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== +estraverse@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.0.0.tgz#ac81750b482c11cca26e4b07e83ed8f75fbcdc22" + integrity sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A== + estree-walker@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" @@ -3662,9 +3770,9 @@ fd-slicer@~1.1.0: pend "~1.2.0" figgy-pudding@^3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" - integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== figures@^1.3.5: version "1.7.0" @@ -3806,6 +3914,13 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -3848,9 +3963,9 @@ flat-cache@^2.0.1: write "1.0.3" flatted@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" - integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== "flotr2@git+https://github.com/EnterpriseDB/Flotr2.git": version "0.1.0" @@ -3864,13 +3979,20 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" -follow-redirects@1.5.10, follow-redirects@^1.0.0: +follow-redirects@1.5.10: version "1.5.10" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== dependencies: debug "=3.1.0" +follow-redirects@^1.0.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.11.0.tgz#afa14f08ba12a52963140fe43212658897bc0ecb" + integrity sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA== + dependencies: + debug "^3.0.0" + font-awesome@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133" @@ -3927,6 +4049,13 @@ fs-extra@^7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -3972,6 +4101,20 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + geometry-interfaces@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/geometry-interfaces/-/geometry-interfaces-1.1.4.tgz#9e82af6700ca639a675299f08e1f5fbc4a79d48d" @@ -4043,9 +4186,9 @@ glob-parent@^3.1.0: path-dirname "^1.0.0" glob-parent@~5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" - integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== dependencies: is-glob "^4.0.1" @@ -4237,6 +4380,11 @@ has-to-string-tag-x@^1.2.0: dependencies: has-symbol-support-x "^1.4.1" +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -4352,7 +4500,7 @@ http-cache-semantics@3.8.1: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== -http-errors@1.7.2, http-errors@~1.7.2: +http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== @@ -4363,6 +4511,17 @@ http-errors@1.7.2, http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-proxy@^1.13.0: version "1.18.0" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a" @@ -4388,7 +4547,7 @@ iconfont-webpack-plugin@^4.2.1: svgicons2svgfont "9.1.1" ttf2woff "2.0.1" -iconv-lite@0.4.24, iconv-lite@^0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -4417,6 +4576,13 @@ iferr@^0.1.5: resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= +ignore-walk@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + dependencies: + minimatch "^3.0.4" + ignore@^3.3.5: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -4509,9 +4675,9 @@ imagemin@^5.3.1: replace-ext "^1.0.0" immutability-helper@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-3.0.1.tgz#4f609c5afbf8d78cb297970e8af2fba8b0eda1d6" - integrity sha512-U92ROQQt7XkIwrdqCByUI118TQM1hXdKnRQpvKeA0HRyGSnJipu9IWHe4UD8zCN00O8UnQjQzPCgZ1CC3yBzHA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-3.0.2.tgz#e9187158b47c93368a92e84c31714c4b3dff30b0" + integrity sha512-fcrJ26wpvUcuGRpoGY4hyQ/JOeR1HAunMmE3C0XYXSe6plAGtgTlB2S4BzueBANCPrDJ7AByL1yrIRLIlVfwpA== dependencies: invariant "^2.2.4" @@ -4606,7 +4772,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4621,7 +4787,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.4, ini@^1.3.5: +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== @@ -4726,11 +4892,6 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-arguments@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" - integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -4760,7 +4921,7 @@ is-buffer@^1.1.0, is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.2: +is-buffer@^2.0.2, is-buffer@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== @@ -4858,6 +5019,13 @@ is-finite@^1.0.0: resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -4938,7 +5106,7 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= -is-regex@^1.0.4, is-regex@^1.0.5: +is-regex@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== @@ -5043,7 +5211,12 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" -jasmine-core@^3.3, jasmine-core@~3.3.0: +jasmine-core@^3.3: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.5.0.tgz#132c23e645af96d85c8bca13c8758b18429fc1e4" + integrity sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA== + +jasmine-core@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.3.0.tgz#dea1cdc634bc93c7e0d4ad27185df30fa971b10e" integrity sha512-3/xSmG/d35hf80BEN66Y6g9Ca5l/Isdeg/j6zvbTYlTzeKinzmaTM4p9am5kYqOmE05D7s1t8FGjzdSnbUbceA== @@ -5057,9 +5230,9 @@ jest-worker@^24.9.0: supports-color "^6.1.0" jest-worker@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.1.0.tgz#75d038bad6fdf58eba0d2ec1835856c497e3907a" - integrity sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg== + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.2.6.tgz#d1292625326794ce187c38f51109faced3846c58" + integrity sha512-FJn9XDUSxcOR4cwDzRfL1z56rUofNTFs539FGASpd50RHdb6EVkhxQqktodW2mI49l+W3H+tFJDotCHUQF6dmA== dependencies: merge-stream "^2.0.0" supports-color "^7.0.0" @@ -5089,16 +5262,16 @@ js-string-escape@^1.0.0: resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= - -js-tokens@^4.0.0: +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + js-yaml@^3.12.0, js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" @@ -5164,9 +5337,9 @@ json5@^1.0.1: minimist "^1.2.0" json5@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e" - integrity sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ== + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== dependencies: minimist "^1.2.5" @@ -5213,9 +5386,9 @@ karma-chrome-launcher@^2.2.0: which "^1.2.1" karma-jasmine-html-reporter@^1.4.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.2.tgz#a846b703dbe5c8d803481e68636eb93346dc5966" - integrity sha512-ILBPsXqQ3eomq+oaQsM311/jxsypw5/d0LnZXj26XkfThwq7jZ55A2CFSKJVA5VekbbOGvMyv7d3juZj0SeTxA== + version "1.5.3" + resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.5.3.tgz#c724078436ed7b7d17a47e79164af36eed2d2713" + integrity sha512-ci0VrjuCaFj+9d1tYlTE3KIPUCp0rz874zWWU3JgCMqGIyw5ke+BXWFPOAGAqUdCJcrMwneyvp1zFXA74MiPUA== karma-jasmine@~2.0.1: version "2.0.1" @@ -5388,6 +5561,14 @@ loader-utils@1.4.0, loader-utils@^1.0.1, loader-utils@^1.0.2, loader-utils@^1.0. emojis-list "^3.0.0" json5 "^1.0.1" +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -5524,11 +5705,6 @@ make-dir@^3.0.2: dependencies: semver "^6.0.0" -mamacro@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" - integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== - map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -5554,9 +5730,9 @@ map-visit@^1.0.0: object-visit "^1.0.0" marked@^0.8.0: - version "0.8.1" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.1.tgz#a233f39572fab15ede53a3c3be8a139bff86d2dd" - integrity sha512-tZfJS8uE0zpo7xpTffwFwYRfW9AzNcdo04Qcjs+C9+oCy8MSRD2reD5iDVtYx8mtLaqsGughw/YLlcwNxAHA1g== + version "0.8.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.2.tgz#4faad28d26ede351a7a1aaa5fec67915c869e355" + integrity sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw== md5.js@^1.3.4: version "1.3.5" @@ -5572,6 +5748,11 @@ mdn-data@2.0.4: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== +mdn-data@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" + integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -5759,6 +5940,14 @@ minipass-pipeline@^1.2.2: dependencies: minipass "^3.0.0" +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + minipass@^3.0.0, minipass@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" @@ -5766,6 +5955,13 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + mississippi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" @@ -5790,10 +5986,15 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.3.tgz#5a514b7179259287952881e94410ec5465659f8c" - integrity sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg== +mkdirp-classic@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz#54c441ce4c96cd7790e10b41a87aa51068ecab2b" + integrity sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g== + +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" @@ -5917,6 +6118,15 @@ neatequal@^1.0.0: dependencies: varstream "^0.3.2" +needle@^2.2.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.1.tgz#14af48732463d7475696f937626b1b993247a56a" + integrity sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -5961,12 +6171,34 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-releases@^1.1.52: - version "1.1.52" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.52.tgz#bcffee3e0a758e92e44ecfaecd0a47554b0bcba9" - integrity sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ== +node-pre-gyp@*: + version "0.14.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83" + integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA== dependencies: - semver "^6.3.0" + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4.4.2" + +node-releases@^1.1.53: + version "1.1.53" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4" + integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ== + +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: version "2.5.0" @@ -6009,6 +6241,13 @@ normalize-url@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== +npm-bundled@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + npm-conf@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" @@ -6017,6 +6256,20 @@ npm-conf@^1.1.0: config-chain "^1.1.11" pify "^3.0.0" +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-packlist@^1.1.6: + version "1.4.8" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" + integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-normalize-package-bin "^1.0.1" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -6024,6 +6277,16 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -6041,6 +6304,11 @@ num2fraction@^1.2.2: resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -6065,11 +6333,6 @@ object-inspect@^1.7.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== -object-is@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" - integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== - object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -6192,6 +6455,11 @@ os-filter-obj@^2.0.0: dependencies: arch "^2.1.0" +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + os-locale@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" @@ -6206,11 +6474,19 @@ os-shim@^0.1.3: resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" integrity sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc= -os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + outpipe@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/outpipe/-/outpipe-1.1.1.tgz#50cf8616365e87e031e29a5ec9339a3da4725fa2" @@ -6262,13 +6538,27 @@ p-is-promise@^2.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.2.1, p-limit@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -6321,6 +6611,11 @@ p-timeout@^2.0.1: dependencies: p-finally "^1.0.0" +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" @@ -6500,9 +6795,9 @@ pend@~1.2.0: integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= picomatch@^2.0.4, picomatch@^2.0.7: - version "2.2.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" - integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: version "2.3.0" @@ -6545,12 +6840,12 @@ pkg-dir@^4.1.0: dependencies: find-up "^4.0.0" -pkg-up@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= dependencies: - find-up "^3.0.0" + find-up "^2.1.0" pngquant-bin@^5.0.0: version "5.0.2" @@ -6892,12 +7187,12 @@ postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss-value-parser@^4.0.2: +postcss-value-parser@^4.0.2, postcss-value-parser@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz#651ff4593aa9eda8d5d0d66593a2417aeaeb325d" integrity sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg== -postcss@7.0.27, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6: +postcss@7.0.27, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0.6: version "7.0.27" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.27.tgz#cc67cdc6b0daa375105b7c424a85567345fc54d9" integrity sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ== @@ -7098,6 +7393,16 @@ raw-loader@^1.0.0: loader-utils "^1.1.0" schema-utils "^1.0.0" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + read-only-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0" @@ -7122,7 +7427,7 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -7145,6 +7450,15 @@ readable-stream@^1.0.33: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -7216,14 +7530,6 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexp.prototype.flags@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" @@ -7405,7 +7711,7 @@ rimraf@2.6.3: dependencies: glob "^7.1.3" -rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@^2.5.4, rimraf@^2.6.0, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -7453,18 +7759,18 @@ run-queue@^1.0.0, run-queue@^1.0.3: aproba "^1.1.1" rxjs@^6.4.0: - version "6.5.4" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" - integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== + version "6.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec" + integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ== dependencies: tslib "^1.9.0" -safe-buffer@5.1.2, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== @@ -7604,7 +7910,7 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" -set-blocking@^2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -7687,9 +7993,9 @@ shim-loader@^1.0.1: webpack-sources "^0.2.3" signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== simple-concat@^1.0.0: version "1.0.0" @@ -8007,6 +8313,16 @@ stream-http@^2.0.0, stream-http@^2.7.2: to-arraybuffer "^1.0.0" xtend "^4.0.0" +stream-http@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.0.tgz#22fb33fe9b4056b4eccf58bd8f400c4b993ffe57" + integrity sha512-cuB6RgO7BqC4FBYzmnvhob5Do3wIdIsXAgGycHJnW+981gHqoYcYz9lqjJrk8WXRddbwPuqPYRl+bag6mYv4lw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^3.0.6" + xtend "^4.0.0" + stream-shift@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" @@ -8036,7 +8352,16 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= -string-width@^2.1.0: +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -8063,21 +8388,39 @@ string.prototype.codepointat@^0.2.0: resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz#004ad44c8afc727527b108cd462b4d971cd469bc" integrity sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg== -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== +string.prototype.trimend@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz#ee497fd29768646d84be2c9b819e292439614373" + integrity sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA== dependencies: define-properties "^1.1.3" - function-bind "^1.1.1" + es-abstract "^1.17.5" + +string.prototype.trimleft@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" + integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trimstart "^1.0.0" string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== + version "2.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" + integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== dependencies: define-properties "^1.1.3" - function-bind "^1.1.1" + es-abstract "^1.17.5" + string.prototype.trimend "^1.0.0" + +string.prototype.trimstart@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz#afe596a7ce9de905496919406c9734845f01a2f2" + integrity sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" @@ -8098,7 +8441,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0: +strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= @@ -8145,7 +8488,7 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" -strip-json-comments@^2.0.1: +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -8308,6 +8651,19 @@ tar-stream@^1.5.2: to-buffer "^1.1.1" xtend "^4.0.0" +tar@^4.4.2: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + temp-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" @@ -8372,9 +8728,9 @@ terser-webpack-plugin@^2.2.2: webpack-sources "^1.4.3" terser@^4.1.2, terser@^4.4.3, terser@^4.6.2: - version "4.6.7" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72" - integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g== + version "4.6.10" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.10.tgz#90f5bd069ff456ddbc9503b18e52f9c493d3b7c2" + integrity sha512-qbF/3UOo11Hggsbsqm2hPa6+L4w7bkr+09FNseEe8xrcVD3APGLFqE+Oz1ZKAxjYnFsj80rLOfgAtJ0LNJjtTA== dependencies: commander "^2.20.0" source-map "~0.6.1" @@ -8575,9 +8931,9 @@ umd@^3.0.0: integrity sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow== unbzip2-stream@^1.0.9: - version "1.3.3" - resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz#d156d205e670d8d8c393e1c02ebd506422873f6a" - integrity sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg== + version "1.4.0" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.0.tgz#097ca7b18b5b71e6c8bc8e514a0f1884a12d6eb1" + integrity sha512-kVx7CDAsdBSWVf404Mw7oI9i09w5/mTT/Ruk+RWa64PLYKvsAucLLFHvQtnvjeADM4ZizxrvG5SHnF4Te4T2Cg== dependencies: buffer "^5.2.1" through "^2.3.8" @@ -8594,9 +8950,9 @@ undeclared-identifiers@^1.1.2: xtend "^4.0.1" underscore@>=1.7.0, underscore@>=1.8.3, underscore@^1.8.0, underscore@^1.8.3, underscore@^1.9.1: - version "1.9.2" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.2.tgz#0c8d6f536d6f378a5af264a72f7bec50feb7cf2f" - integrity sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ== + version "1.10.2" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf" + integrity sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg== unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" @@ -8744,7 +9100,7 @@ useragent@2.3.0: lru-cache "4.1.x" tmp "0.0.x" -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -8844,17 +9200,17 @@ watchify@~3.11.1: xtend "^4.0.0" watchpack@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" - integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + version "1.6.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.1.tgz#280da0a8718592174010c078c7585a74cd8cd0e2" + integrity sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA== dependencies: - chokidar "^2.0.2" + chokidar "^2.1.8" graceful-fs "^4.1.2" neo-async "^2.5.0" "webcabin-docker@git+https://github.com/EnterpriseDB/wcDocker/#7a14f50a7197fe3824d706c85485a49fa9166804": version "2.2.4-dev" - resolved "git+https://github.com/EnterpriseDB/wcDocker.git#7a14f50a7197fe3824d706c85485a49fa9166804" + resolved "git+https://github.com/EnterpriseDB/wcDocker/#7a14f50a7197fe3824d706c85485a49fa9166804" dependencies: FileSaver "^0.10.0" font-awesome "^4.7.0" @@ -8938,14 +9294,14 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack- source-map "~0.6.1" webpack@^4.41.2: - version "4.42.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.0.tgz#b901635dd6179391d90740a63c93f76f39883eb8" - integrity sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w== + version "4.42.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.42.1.tgz#ae707baf091f5ca3ef9c38b884287cfe8f1983ef" + integrity sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg== dependencies: - "@webassemblyjs/ast" "1.8.5" - "@webassemblyjs/helper-module-context" "1.8.5" - "@webassemblyjs/wasm-edit" "1.8.5" - "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" acorn "^6.2.1" ajv "^6.10.2" ajv-keywords "^3.4.1" @@ -8957,7 +9313,7 @@ webpack@^4.41.2: loader-utils "^1.2.3" memory-fs "^0.4.1" micromatch "^3.1.10" - mkdirp "^0.5.1" + mkdirp "^0.5.3" neo-async "^2.6.1" node-libs-browser "^2.2.1" schema-utils "^1.0.0" @@ -8978,6 +9334,13 @@ which@^1.2.1, which@^1.2.14, which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + wkx@^0.4.6: version "0.4.8" resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.8.tgz#a092cf088d112683fdc7182fd31493b2c5820003" @@ -9064,7 +9427,7 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.2: +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==