From 7ac1e00d01075829e8358ec5d30cbeada14aae80 Mon Sep 17 00:00:00 2001 From: "R. de Veen" Date: Tue, 14 Sep 2021 18:01:45 +0200 Subject: [PATCH] [FileExplorer] Add PDF Thumbnail Provider for Windows Explorer (#13058) * Add PdfPreviewHandler to build dependency of runner * PDF Thumbnail Provider * Remove using brackets * Pdf Thumbnail - Settings and Unit Tests * Removed resx * Add PDF Thumbnail Provider binary * Install Pdf Thumbnail Provider * Fix pagee spelling error. * Update Windows dependency to version 10.0.18362.0 because that is the minimal required version of the PowerToys. * Add Pdf Preview Handler and Pdf Thumbnail Provider --- .pipelines/pipeline.user.windows.yml | 5 +- PowerToys.sln | 19 ++++ installer/PowerToysSetup/Product.wxs | 24 ++++- .../PdfPreviewHandler.csproj | 2 +- .../PdfThumbnailProvider.cs | 96 ++++++++++++++++++ .../PdfThumbnailProvider.csproj | 71 +++++++++++++ .../SvgThumbnailProvider.cs | 1 - .../HelperFiles/sample.pdf | Bin 0 -> 44743 bytes .../PdfThumbnailProviderTests.cs | 93 +++++++++++++++++ .../UnitTests-PdfThumbnailProvider.csproj | 78 ++++++++++++++ .../UnitTests-PdfThumbnailProvider/app.config | 15 +++ src/modules/previewpane/powerpreview/CLSID.h | 3 + .../previewpane/powerpreview/Resources.resx | 3 + .../previewpane/powerpreview/powerpreview.cpp | 10 ++ .../PowerPreviewProperties.cs | 17 ++++ .../ViewModels/PowerPreviewViewModel.cs | 20 ++++ .../ViewModelTests/PowerPreview.cs | 19 ++++ .../Strings/en-us/Resources.resw | 8 +- .../Views/PowerPreviewPage.xaml | 7 ++ .../BugReportTool/RegistryUtils.cpp | 5 +- 20 files changed, 487 insertions(+), 9 deletions(-) create mode 100644 src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs create mode 100644 src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj create mode 100644 src/modules/previewpane/UnitTests-PdfThumbnailProvider/HelperFiles/sample.pdf create mode 100644 src/modules/previewpane/UnitTests-PdfThumbnailProvider/PdfThumbnailProviderTests.cs create mode 100644 src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj create mode 100644 src/modules/previewpane/UnitTests-PdfThumbnailProvider/app.config diff --git a/.pipelines/pipeline.user.windows.yml b/.pipelines/pipeline.user.windows.yml index 636c090b2a..1c6d883455 100644 --- a/.pipelines/pipeline.user.windows.yml +++ b/.pipelines/pipeline.user.windows.yml @@ -42,8 +42,6 @@ restore: name: 'Restore Tools packages' command: '.pipelines\restore-tools.cmd' - - build: commands: # Localize the files before the Build PowerToys step to generate translated resx files from the lcl files @@ -113,6 +111,8 @@ build: - 'modules\FileExplorerPreview\MarkdownPreviewHandler.comhost.dll' - 'modules\FileExplorerPreview\PdfPreviewHandler.dll' - 'modules\FileExplorerPreview\PdfPreviewHandler.comhost.dll' + - 'modules\FileExplorerPreview\PdfThumbnailProvider.dll' + - 'modules\FileExplorerPreview\PdfThumbnailProvider.comhost.dll' - 'modules\FileExplorerPreview\powerpreview.dll' - 'modules\FileExplorerPreview\PreviewHandlerCommon.dll' - 'modules\FileExplorerPreview\SvgPreviewHandler.dll' @@ -229,7 +229,6 @@ build: signing_options: sign_inline: true # This does signing as soon as this command completes - #package: # commands: # - !!buildcommand diff --git a/PowerToys.sln b/PowerToys.sln index d58e52fadd..b17039b9fd 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -17,6 +17,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runner", "src\runner\runner {0B593A6C-4143-4337-860E-DB5710FB87DB} = {0B593A6C-4143-4337-860E-DB5710FB87DB} {E364F67B-BB12-4E91-B639-355866EBCD8B} = {E364F67B-BB12-4E91-B639-355866EBCD8B} {D940E07F-532C-4FF3-883F-790DA014F19A} = {D940E07F-532C-4FF3-883F-790DA014F19A} + {69E1EE8D-143A-4060-9129-4658ACF14AAF} = {69E1EE8D-143A-4060-9129-4658ACF14AAF} {DA425894-6E13-404F-8DCB-78584EC0557A} = {DA425894-6E13-404F-8DCB-78584EC0557A} {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} = {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} {A7D5099E-F0FD-4BF3-8522-5A682759F915} = {A7D5099E-F0FD-4BF3-8522-5A682759F915} @@ -362,6 +363,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoConferenceProxyFilter" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VideoConference", "VideoConference", "{470FBAF9-E1F8-4F3E-8786-198A1C81C8A8}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PdfThumbnailProvider", "src\modules\previewpane\PdfThumbnailProvider\PdfThumbnailProvider.csproj", "{11491FD8-F921-48BF-880C-7FEA185B80A1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-PdfThumbnailProvider", "src\modules\previewpane\UnitTests-PdfThumbnailProvider\UnitTests-PdfThumbnailProvider.csproj", "{F40C3397-1834-4530-B2D9-8F8B8456BCDF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -948,6 +953,18 @@ Global {AC2857B4-103D-4D6D-9740-926EBF785042}.Release|x64.Build.0 = Release|x64 {AC2857B4-103D-4D6D-9740-926EBF785042}.Release|x86.ActiveCfg = Release|Win32 {AC2857B4-103D-4D6D-9740-926EBF785042}.Release|x86.Build.0 = Release|Win32 + {11491FD8-F921-48BF-880C-7FEA185B80A1}.Debug|x64.ActiveCfg = Debug|x64 + {11491FD8-F921-48BF-880C-7FEA185B80A1}.Debug|x64.Build.0 = Debug|x64 + {11491FD8-F921-48BF-880C-7FEA185B80A1}.Debug|x86.ActiveCfg = Debug|x64 + {11491FD8-F921-48BF-880C-7FEA185B80A1}.Release|x64.ActiveCfg = Release|x64 + {11491FD8-F921-48BF-880C-7FEA185B80A1}.Release|x64.Build.0 = Release|x64 + {11491FD8-F921-48BF-880C-7FEA185B80A1}.Release|x86.ActiveCfg = Release|x64 + {F40C3397-1834-4530-B2D9-8F8B8456BCDF}.Debug|x64.ActiveCfg = Debug|x64 + {F40C3397-1834-4530-B2D9-8F8B8456BCDF}.Debug|x64.Build.0 = Debug|x64 + {F40C3397-1834-4530-B2D9-8F8B8456BCDF}.Debug|x86.ActiveCfg = Debug|x64 + {F40C3397-1834-4530-B2D9-8F8B8456BCDF}.Release|x64.ActiveCfg = Release|x64 + {F40C3397-1834-4530-B2D9-8F8B8456BCDF}.Release|x64.Build.0 = Release|x64 + {F40C3397-1834-4530-B2D9-8F8B8456BCDF}.Release|x86.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1061,6 +1078,8 @@ Global {5ABA70DE-3A3F-41F6-A1F5-D1F74F54F9BB} = {470FBAF9-E1F8-4F3E-8786-198A1C81C8A8} {AC2857B4-103D-4D6D-9740-926EBF785042} = {470FBAF9-E1F8-4F3E-8786-198A1C81C8A8} {470FBAF9-E1F8-4F3E-8786-198A1C81C8A8} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC} + {11491FD8-F921-48BF-880C-7FEA185B80A1} = {2F305555-C296-497E-AC20-5FA1B237996A} + {F40C3397-1834-4530-B2D9-8F8B8456BCDF} = {2F305555-C296-497E-AC20-5FA1B237996A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0} diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index 164a248b19..3790b05b13 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -511,6 +511,19 @@ + + + + + + + + + + + + + @@ -543,6 +556,10 @@ + + + + @@ -791,7 +808,7 @@ - + @@ -809,6 +826,11 @@ + + + + + diff --git a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj index a49bb3b7b3..b6e6a59aa4 100644 --- a/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj +++ b/src/modules/previewpane/PdfPreviewHandler/PdfPreviewHandler.csproj @@ -65,7 +65,7 @@ - $(MSBuildProgramFiles32)\Windows Kits\10\UnionMetadata\10.0.17134.0\Windows.winmd + $(MSBuildProgramFiles32)\Windows Kits\10\UnionMetadata\10.0.18362.0\Windows.winmd true diff --git a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs new file mode 100644 index 0000000000..c12152e673 --- /dev/null +++ b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs @@ -0,0 +1,96 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using System; +using System.Drawing; +using System.IO; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using Common.ComInterlop; +using Common.Utilities; +using Windows.Data.Pdf; +using Windows.Storage.Streams; + +namespace Microsoft.PowerToys.ThumbnailHandler.Pdf +{ + /// + /// PDF Thumbnail Provider. + /// + [Guid("BCC13D15-9720-4CC4-8371-EA74A274741E")] + [ClassInterface(ClassInterfaceType.None)] + [ComVisible(true)] + public class PdfThumbnailProvider : IInitializeWithStream, IThumbnailProvider + { + /// + /// Gets the stream object to access file. + /// + public IStream Stream { get; private set; } + + /// + /// The maximum dimension (width or height) thumbnail we will generate. + /// + private const uint MaxThumbnailSize = 10000; + + /// + public void Initialize(IStream pstream, uint grfMode) + { + // Ignore the grfMode always use read mode to access the file. + this.Stream = pstream; + } + + /// + public void GetThumbnail(uint cx, out IntPtr phbmp, out WTS_ALPHATYPE pdwAlpha) + { + phbmp = IntPtr.Zero; + pdwAlpha = WTS_ALPHATYPE.WTSAT_UNKNOWN; + + if (cx == 0 || cx > MaxThumbnailSize) + { + return; + } + + using var dataStream = new ReadonlyStream(this.Stream as IStream); + using var memStream = new MemoryStream(); + + dataStream.CopyTo(memStream); + memStream.Position = 0; + + // AsRandomAccessStream() extension method from System.Runtime.WindowsRuntime + var pdf = PdfDocument.LoadFromStreamAsync(memStream.AsRandomAccessStream()).GetAwaiter().GetResult(); + + if (pdf.PageCount > 0) + { + using var page = pdf.GetPage(0); + + var image = PageToImage(page, cx); + + using Bitmap thumbnail = new Bitmap(image); + + phbmp = thumbnail.GetHbitmap(); + pdwAlpha = WTS_ALPHATYPE.WTSAT_RGB; + } + } + + /// + /// Transform the PdfPage to an Image. + /// + /// The page to transform to an Image. + /// The height of the page. + /// An object of type + private static Image PageToImage(PdfPage page, uint height) + { + Image imageOfPage; + + using var stream = new InMemoryRandomAccessStream(); + + page.RenderToStreamAsync(stream, new PdfPageRenderOptions() + { + DestinationHeight = height, + }).GetAwaiter().GetResult(); + + imageOfPage = Image.FromStream(stream.AsStream()); + + return imageOfPage; + } + } +} diff --git a/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj new file mode 100644 index 0000000000..dd026f4b54 --- /dev/null +++ b/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.csproj @@ -0,0 +1,71 @@ + + + x64 + true + {11491FD8-F921-48BF-880C-7FEA185B80A1} + Microsoft.PowerToys.ThumbnailHandler.Pdf + PdfThumbnailProvider + PdfThumbnailProvider + PowerToys PdfPreviewHandler + Microsoft Corporation + Copyright (C) 2020 Microsoft Corporation + PowerToys + netcoreapp3.1 + true + true + Microsoft Corporation + PowerToys + en-US + PowerToys PdfPreviewHandler + Copyright (C) 2020 Microsoft Corporation + $(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\ + true + false + false + true + + + + + + + all + + + all + + + all + + + all + + + all + + + all + + + + + + + + + + + + + StyleCop.json + + + + + + $(MSBuildProgramFiles32)\Windows Kits\10\UnionMetadata\10.0.18362.0\Windows.winmd + true + + + + \ No newline at end of file diff --git a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs index 73810bbc60..a3c9ff4005 100644 --- a/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs +++ b/src/modules/previewpane/SvgThumbnailProvider/SvgThumbnailProvider.cs @@ -12,7 +12,6 @@ using System.Runtime.InteropServices.ComTypes; using System.Windows.Forms; using Common.ComInterlop; using Common.Utilities; -using Microsoft.PowerToys.Telemetry; using PreviewHandlerCommon; namespace Microsoft.PowerToys.ThumbnailHandler.Svg diff --git a/src/modules/previewpane/UnitTests-PdfThumbnailProvider/HelperFiles/sample.pdf b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/HelperFiles/sample.pdf new file mode 100644 index 0000000000000000000000000000000000000000..96304d9b21979762d1443f6d2163def110ad0d43 GIT binary patch literal 44743 zcmeEu1yEhvk|^%(?rsNncXtWy?he5{1b2eFySoPs4#6e3LvZJlym#l_``^6zGgb5J z*HnGjhqd?G-MxCX_o`EnD~gKKGcj<$!;m+=|G>jA5it_k8(G1_@bUswJsnH|B8D!8 zHumNKMMHB_XCmhJ*UA7{LpyUSI~#g=S!yDHoT-bU$vY4c%P(AIfV!oryQ!0+lc|}h zlc}BYI}*!pEPj4?7*jiw-^71S{AHEj)Bz&)u68a&YycTc6K8EAmS5zEm{|Wdu>Wn~ z{5>!;{u*?N{!H^1_&?EnXZxKAm%sC^Z0c<9>h#Xi`{u;$?Oc8hOhjzIXaU5TiJ1P* zCqT@@MMA~J(8cr}KthFyk?8&U1@nH-MD%{W-}CbW6rJpiRZLy90q-&dsG54X0Hkc+ zg(Up9LF8|P)GsFAWn^M$C~WVc{f^2=#Ky(Oz)Zx+%EZ9MtV{I1Yde>B9-WDP?-U^6 zWbf+mhxC6x08{{~PKI{Q4!`zd>3c0^5$?M+MpvZi+CE*3;AjO@RVoL!tu4Q=6JJTk@;d!+{$kwVV{I{NYE z`#Gg362J-|#V|X9uWu4fTF5hJ;Yuh-_dC8LlNovJf6HYIUf!-E~k#Bk!<*{+zspf*uoZ) z)F(AW`!dHOS`Rq^#IAPSun9|4+?azdvS{gEvjka8lKVu0ufKmiPb@cFqwq%#)8 zg4o6cz!~Eb4C{U&d4?~=^%m2JL&_o>Eivi=Rd^vhiU(^raxr=+kt)=8bHO> z$mN$e{hDC}2pc+^{+<>V5fu{?qZKi56naesT=ue~@~I=I+75pn(E44^^8{F}u;v;PbH4;B@iOiZ2L1w!?QK;EN{vZ=Y{ zyXZZsgx({H>HCC=tAm4$sqHUkXZ$mvUrYQ!=->454;FrNByVVI3ix+*@$NR}zXBLQ z>OBft8VlK(+n5qD0)&2P!-a^0jq&fAaUr5-et!@#bdWUtrNrN_gxt(EEKS}$jg6TR zAZO_Dw+AN9_orXd)A$=C%e$yP{2l8T4V8C^slTKAh7tZ9H0ashgU+u7h?rOyxqi`p z4;#NoygRokGZFJ|Yxwh~f5)r8?E2qA8bDYMAaCzvYiI*7HY8&D3)Vjc|9=llMCgCR z`ln$2+cf^L991V*)8BIcEo5=#zZk#xzczjiOFJPuXUl(chF?Vgp|*EH{5BnNODAU+ z5eq}7UpkUC{Kx%oS-Vy7{lEBYuKs!qb5~KLcS8mD}s4 z9$z;t+DlMoVcDI>DNL~90sDAn`AI@otxnP4aKR{3!neU+`)6d0;lGLiUJ*B`G9O1_w1M>3c`vo0-?^uLJ8vMD*$EeQkvg&3lUqqIntA@ zRx4jKW!DYinYnj|yib9#kv&%%yWqSLbiP1tcLxx2y~dOiGryK&34mSz%hpLU{JRN} z>EANZA4SdoJk$G~p8h*3Gp0YM-v4iU|F=!=&sD_#(5Uyf66wDq>ixMA`v0c)f7$eY zcc_2lnE!(5u@Eu;Kkh=A|JKI;H(1v5vvMD7ltEX-A^d^rd4YWY+oDZ*owNBi$G_6!uA5347nHfhZ{hgj%lx0LX@7@=Ki9Os5&wzNe^kqVscHYr z*?(6x%k-!AhJ%&m_j-SCZ&?2`?F}Q#-`g8zR>ps7Z&-dGzWimsf39YQTwN^eov4)G z+dwB5qW4}{-PF{M$c(|7!H|JSPDTE`Hxzk4;dpO1sb1fJobBXP z!2}YVM_mtWgE32&0|G;rU@=^#p7ar|uj7)?v3qzltxM0VH z{&Pk@PDFFi$NhSmZvBTVccFjZkN;eO{%iR$vAzHP{cwzlh=Y-f^Y=l*KjPAf59|l+ zg)f_}cSqp_l9Iw80j@&4QG)CS&$38}z|0DuPCa%u!DO*Uog~nxUPl8r4f00?a*vHm zZHUER*nOfnDjm`u@Z6ab9P3!@(iVM+RvJbq*4(9Q z+TOiF9=`4i>_6}OWs}kZixLMnTu=yA{a`Y`D)mue3NArXEPhtfC-Eh|r4m+x6^W1 z9pc4B=7xGE1BW`MS-IVtco|ZDf_3kRs;Gh6)E3}N>X{_;+;i7|-JK~1zZ)hDszRCm z1p0weL{qd=@#1n1)_ld%*jzEd8y;KWE4C0ckvmJ<=RvZMgH zEpYO23*{BQOGc=e3$e&-LvSv+fP~!GWNukE5eg7obS>R_)g!q)#DlR5d_;*U?_frp zRc+BQ)pQ<(5Y7?GV-V<-%=HPOZ;Cr&-PL)e_qSt7zj9A$tcG3ntBz71NF|Ey$<_L{ zw;_m`>=(lwV}><6{UXeywad=#&}DnJNq5kAZkNr@WTD^VY%@i|_(`k!3{sexpJXyS0;^Bh?NK&ZkA%#-E;^a|%2#KNY6 zEfv*SU5$Kq%1?BE38jLKA<0+1Z?Z_u9Hq-Q3(jKx{hNy;i*D=MIYRY_6-h#y~=R!=}TbR zPIP+%#UZt*6oJb?=v2%V=oDR>RlstOS647B3Z^z~S!5emFoz>g(j45iX=x~+;a!pS zur)QrN@bcZ{^l=v+~X7AS{A*-N~6?5z=w@wkTw@2;|!j&#knx+=Thr z0Vf4vhjp%GTGoKpzfP}0sETV<*4I<6ixYMD{M0C?=FcK2|K1tJ_*w1S7wAE7yZ{>_ z;sXt(08`J43RpQ2N@te^um$t!h8s91E?f$hYcv8+c`PQ+pTkOqWX;~AdI7q-SzCSx zp>$vJXKnI9D-?Xoen1W`!KtvYog)4y26*(XuZ=I+dXsD)K@99}ySf5w9QwRB(5R3H z%@*0>9G6kC^E(sLfxs}HhDAy2$s?p0#|ZEC!`#3I zo$!EhUf0LtQ?E?>V+DEwI^L=v87&~8fjfVAyAV`Zp29Bs`19cSAjo|EnSpzje|f63 zC$Oj8LUO`j(WEBm~hJ? zHX`;BG}eq7y4y_7Qy(59pt8Ls$j+Rv<)idAPl=Jw{@~CmPqwO(YnvLjhRSJ3n7(L8 zo);yLS4%Lcjh^dU=GRd_4IEPJ+$+ylW8Evp$Jk`Pg^e$K0=kWAZt?jn?I=U1B(OHz z{6nx#u(UA^#TG&YPwFg{3z|vS4fcDc7%2%xlHBl177i{#vOv4cF62s+&zTlXaA3vE zH3UM`6gJQ=X|!Ya_qloOv8p8o!*T*FP#T>XA;PP5XLDF}~gFqxiXs*ZL46q5(8qo(49M*=Y6roIAo zEGw~%fD|x_W+DtdiPB`2$mONnB6g5^VUOlsT7>GS%^SwXpOFnnnT2UO*}0JdUPeo| zdwq4Ml-VsSx7&nlOL{)!Hc#gQoTg9HvCNtc1&5%`=&0 zo_F#9zi$~ilPYX)KB?m8S2cL+zTdQz#m8awwBoF^!ZBHBGnw%uv$EtIW<$DPQa?7y z=X!QgOK=JIwWZh{@$TfLS7G6j%iMW#7WSpdo^I9B%c|F&r`{ojzMj$k>9LP#WdY-M zx$AmhtqH*IxOf{vNl@o=rrLU1tDa<6gZu}~^44V&mkFaJ&LfzW zatiJ!I!kAzs%g2BWXWPE$fdZ?I=$>y(>d|)22B%B8IWjJd5+;Tvu-A?Av$_zfvdaS zmyeG#FWZVr?rzS0p7C`KHO_iL%C4^QoZVy*+(qA`EY6B zC(cyIA;K41O3;5^rR&992gy9#Zhk%hBIe_ADNC&y;iwEQ^(I3207Y|tGMN}7mtjcY z*U{lzC*X{>&4AgP!W3;Vy3?iFKOd_VRIGgeWsBz`VFF&|Lio8pUAL7iHPKDD(h&*xG$c*L*a6v#>RY92j-~=80u)3sKXNbA! zBy*;u`1i8pSLl-aF8y(;+-gm`pjZ2YC#H$YSb^l1kGEqcs^m+uJ`g92p-s66tU%d# zw?c=@F$g`y(FhHw7nUwqSzbzD3#=Di4$x#zvofQk$;XjVkp zbBUN7g}m7V?F0FHJQOj@Ys>?%N7`#TnB4Y&4gI{ZDJiV(g#9ZrUet@F3#v!PM=bAA z{-{R-xN}apt8-ui$|>EN71A0zf;YKS0ruE4A&Tq!OFueyGlA~wW?8oUB0Z4IbI7PY z!4&tYhPh7&lK5lYg)}J}@fdV((oP$f+H-@ueq!L?p1xq0+{j(T9h+Vd1?^bSdWWtY zmRTjvu1vUCXS2GC}1sb5K+}twm~{V4tyD;v|!F;by2A}JGIJoqh}PmH8GB6$2Gm3 zW|c)Z$$q%O%qOl;k%G1X?QmS{(}er0T3Kg@nA6E+r|i#Y9|oSA1sE>+IBAAdx$hJj z^TSWq6nyz~s^#!7t+|pav#sWbFCdVw;cshOnl-90bi0Cb49=FPo`nHyHIkYitBSK08UalJ3|m(Q<%tw7ZC3lm4^fR}B^65rkZZJp^r*xK3pujVd8%V6{Q9aY zDxzMyRw1H!{;woAd4c`tOYCj3RqE2qtm2icTI8MuqcjU?4LJGYS!*;4KxT?#$yGq& zJG#CS6yTojIlda1X8jQLvzk*TwTW5P%O&cV84_x??W!2{gO*E+WcBl>b)FF&$^a`! zDrWon<_47sLOS+iZI^qw?i+SclyN(r(w zw5*tibXwS%rWPUJbEa|FU}&_(f!BZ-;=iN0CeJ0}qR&}U-`E7S7U-NS;keS|R|rzX zZ8nDiHpqcFSd?2uFZCHVGV}fFN6VNiS#-Kcgpy(ML3rS-tMq-t23*K#Tub9lI>Z39 z+!|dnQH|O*MHv9PPPpk2O@2zx5G3~jOn~u<`FWBh{YO5@tWJ&GK7K{&RIhMzyoDu~3&Goz6Ix~EXiL57VrZ}%=XGr6X$v>=&BBGPnZArRCXzf^bT&zn z8=8PSwb>l*UxHwhDxq5*0`U<~rPQ&~Po-oHynRmz$nZdy4msQN?!o0YfPa&rmPuh*`Y~F-YjS{c`&6TA9mf;I2F`0%b1{8#C_-9N0(55^JR=5^ zHDDRGZfS#(Fo4U$?GPq8q7CGT1&%5kzW`zXVtbCG_DZ|=j#*w3JBJgtK4xrAymC1w z&UD|z3N(83+a=G8S*$zkk%JniY*b@%L=uj7pdzqx#Nq7KL zerK^#At6ulIaQ(B#=bed0UQ%)yme`8=cCa~7<74oJy?xruA@5}a+-v3hh0qB+QPm9 zy4oL~{D&0+lIe#-v~<4*rf?kLTvw)8H5~(z*$x0U8+Pj-1K?9V;lu4WuRqwl0wdgM zU}&h8SK1n#XdDOQlj#qoj(`0ss|QtRvaBo;*Q(fiGC$vRv*CtB2+HY9Ty(p3tlM2x z*)PY)Y+OB$IDZPQWBbBJD`hRQT1z*^PdlR7+BkQ4eO2i$ z9fjp(YRkkU3)E%(~ig2GlboEg1_5?BUe zSGlM*rVsh-i-8d9s~p;fsag+>R*}6OOEt=-x76fEPOz#dA!Oys^rYc+HDD>&;qg|J zT?GZOW8)Aqxx$xjxqI{wDcD%XXiF)<%%u7JmdvL8%w0K(Z?c`eQB?N}^Ax`qRVJL^eZLmB)TvFOAxB8v zVwT?EC1q(#8m4J!-SBAjk_v6ihRS1llpS8~3AN55V#7=z zfc>O`nzfby^*hWHzVs%nJA>V>43lIGdD8waW_3`w&R3IbYAu=+YI>WfrRBE9&QLTM z&hkR71U>zVvgdcxY@-=FS=PHk? zL3rCmP61|!zd)GqpjLU+uh{Q$7#9iN!Xl0 z>H;6!wDeHn6|XY_J$-!%+Z4fh<4t;=r5WW$TXVUW&0Cs%H=75pN0ghq1~4{~b{T!m z&oBx}7~W;KXQRTiZNb!yMt6mnpY06p*mbhG%4JG0EyW=;5Hpu@>eaq$ky+&<$XLu-bbyB2|X~q5XX{uwMPcl zRLsd(Ov*Auh=D^jF$s6Rj_wq_{QN*Q-dr8vyvr! z?8d1~b#O^yFclUi38hq7+u^H)VJ&M#VZls^A{MPsnF3?|wUA|+BsluoHN4taj-$fw zX#~26EtjSx2NBgeDkW@*MyPz`YM7QesZ!(8osGi=^JDcfRV4GvsfbXT!Y`ce*(JJi zvptaJ;FrYJCeq9hsRT(RJge^PxhqPDpIe(6wX@CI7n|~m$5+PH4lFG@6WL@6&5|wE z`73R`+gf{Hl9r>R;hTL-k0H#~GO58bpgz7Y9JJP4{08NaTgptH ziW{3lo0ZvI0X$1j7d);SYHK|c_G*uM9bhiC_SWDcMjvt3BrLhd&D&hnzmto)(+Cle%TO>K9`Op8v3Yu%v>oz zKA&BuN@#8x5?OoF!c-_dUE1MA5bjAv+H7*Br6FSHT9@SIT)Q-7WI>uL1z^IcXJ^TL z$t@_Dvofr+S2n}d*3p}5>=L@Mmu;#EJ!R86%q~-vehe>^Dikiw>F&7ZCqL`{V5Fr{ z>k_yA!ImwFuJOkT+>7p`F_9&ck!}c-lzgcxccZA!jDt?x7Jzm9{_$jogqRY;cRNzd zPqt92p{8P2g9d0hUs($C+hE~~Nq;wU8ofB_$t={9x7s5`nHXQy=%otV{5;HqabqLQ zv9TCLkg%t8wMJqR^(fl%=+=`Zz0KOpdf;0C@P^hkJqG3N;&(A0*cb^h z4x~!umh5HFQQB$}VU!cp>5EMDi)nrcSywJ~Ph^SCU2;9xwTZuC8O0g_e-1{ z7kHysdzDxuXcu~FTpYOFpEg-hZ$x}SZan`iXXCdn=et?7vY^3nFPOd2ba7g5gqprM zK*3%cE@$&!x_wfxS9mA*_QoEp$kK`Uv%5R_d)%8d!ZsRBp|wYbxYlw=@J3`uz_-2@ zGW%#W%>!bB6kwmwq1^)_pTr?_3qH~xj^sv#Fa&@c!j$hnTVPI;^*0^aw5mT0ZR1qR zP7iHsHK6WYbc26UMnn9`8NzBt7&9wr7Y*Hgj-~mn-BTx?L*nz?9@jh77f@aXiIs7} zT}NGt=`ymx3EVlCi-$ zfBs|xmq#Y8nDgnCKE}Cg(_sP=Z{i`apWM@#Q{RDe9~NQXyZ1*1fHUI?JnT>J*|cDB ze>lDaSBWgIYVkQ(iRg>bS&8FLi8p}P2%(AlCW<;H1}?x!gI2=UkV(h76Ds!ke^o?{ zbjg8Y#fSp2#RxH=6ZP%9&ux?O&z>g>Tm&tO! z^;Q7Y;=o=b<-(I74hL7FQXCr%RIQ9W5`94yRa!*V<`P`j)FUxukU5~J zZE0Mh!hf4y&}E*BcSNp)+-;a4ZkRFaKf54dV(?%Am4KB2Y?XN83ia{Izc4&ox#pO46S)o- zvvrZc&?9@7e#B7@HM5n^SkzcxnrzS0Zo!xn;y(`f%wh)S@1?44Tb!M7zEu{;W~ zx`+silW8yoOtG_XLYAH-?PiEaMC)xuA(*IFzDJ0Sw;tallQ)r*ay zTbQDl{!A1eb8^0aXHSwWje2e?B5wg4|FlRuU0$Y*s*jrKPe`JdM!xEB$_b`QI6O8F z6hJ$~BJ2ca%_qV;>Y2IiT8WcJ!Y+v<Dimi zI1`^t;%5h#e&c06yO1}^cI8(`=u00$!dxMv4aVu%1iQ3h;(Je9F{vxsmSGt^u`eTs zn=PdYpU2{WYAw?y#m=5LZ(Vn8HOql9Rjvl)edC1|>Xvw`EmJeVkd?1m6ArCbw%K&D z=6jzX)zEL3SGlm)D{ZfiIW&$xbZHfa??0E94Qj!wTMcNnHtl}}`W`$RQl8nTne}b{ z2T-XflX9H*!hB)`-$q%<)+Ogex3iYxJ>CfB*)v>h1;Uj%;Sl6xWbCNJ3)Ze3Hq$x_ z?P>@d^#1%JQmK*Q`o#VBT;hGt*ae}I=D;KkiN+w0L5T~&vj$BsgzE9&Ha1sc$us1u zg09f;yIKt&!G4Ui5bVCxg#A{(@g==U^K*h-Bk2lKPvbo-Q`{VC>vTJ$qw<*M+)_j&<;fD^_g@>=a$pLZqVMeEVN zJpmJm^=l@B>=^|$N_t1+!X5plart@f=IJ9ZF8Jk{%)^7j?DNzpzCxCxT?l{K)H zYF&I{_ks(YPViQBe$on)@lh$V`>BB7cABmPm=^=RV6tIbR^cuBME5=?Wd&5tz-KA8 zlq*wT`XAm0JA7FrnkXY9L_0S}AKE<2_p&cCk{>9?k5ct&2Y73ZuXP`lIN|q(b<^u* z85IJ7Jcqoh7Izs^e@yc5%y5(p>FgpR!3U$-uawbDtPLWdJZojc81FL4e`(~L9Bnz)-tHEzk8U}*@p@v{g0&pG@ZyrUpbJ*PoOUhyA3P>%@(gEvIU*N)YM zdx*e*j_*+v!vuDl?BZt8DCr@x#+Y&tf&0!b)m)kF1Q2dDr^?x2HjQaqwA2LX=qm>h9H=c@z9qvQRzOXD#Hgg0^B28^-AYLK-;gmGqHeRVJJ zfJd0#^sw+LDF+xUPAJl%k&jzF(+zDQCGEv%CscGrac$IWg6w)Af6S-XuTgpKn_!P` zH!Zul$No&x%<#p3_QI@PWju6TKOpIJ+@j?@+VtU)zW&gDj8BHLW}*%`?Lmi0%t!W- z>oDYC=N4-sA$SGxiCrIqxNHe`2Wm(R>+UkEYnfs32!DX$LsjkS#KJaQ>w{X8Xa6Am ziNRuaWbqb@WfN_d>_9@73nziK5f2Hn8!Ioabn)V}0Zl3|796YPW8mz_CNED0)Zic@ zdEklvxuQ42xcFARp}=trB?9?R7!2q2slM-W)bdsthC22XC`2sU{X)eCQ`1LiF#Z$n5+i!y+lYIVCLJ-D$U z#B&BM9NZYTWX=#MR6L}#Rh(f3)+Gl+Mu^g5PC0zJf|e!wYDFsi5b{1J;A+!B_{u*DrkHSsWa3RH+IW%7jMgaZoVHN=o3(~L>v>KTmNM<~&?^Q9&+Q4vXIc%oV1+bv&7 zu8Q1hX1maaabk8yLpOuD`7r`(iykfl97wRBp3=5PG%3%x4EKDydgg+>q&~!24A@lZ zB3G-8bPY{n^{{lsjC*U~x%3qUltc?Ak?!f~veZ&*sL4f{f$>m^(V!l{Q$Y36K-tvD z_ViAW<$`R*gHkiWavS3YRrci9WJD>5>_!;o-%HM8Y@O^i_JBMnm$nF;^#26*g!oFD zeCzm?4G(y1&M>;X!F1@p?&akpiIV>u`2^xZh6D`(#ePV75F!U%CnFxTNQRS_v7Xe~ zVj#XGiXl9HOIfJ-1&btHd@5*&GI4xO&&Q7ll=d*F4^+VLnK>RbpCU|ok@u`tT*Y=# z2%2`{Lz`KVjrh@G)&(UpAe=|Apis%+KpacVM3dVCUmK7NXdU5t384}ORt7^j6KjKd zJ7zgB6t)w8j9R5C7&9o}=c+>X~FeY@GEP8(P$o2-DB`6v~!#88`dcnPPR#y*J5<8RMQ5_+^NAD zDrx>%Et8u^;tgChoX4u*6`U))M?0TLrwwHVE>5V(I_MWD*`YAa4&uqtZG!%95Nr9m zK2xU$*Ki(#l=wC==H5_OC%{GcCz3-4EyZIzQ%s}L9ug9vL#s7D95wita5s^C3}-@j zQ=E9dB7(+i?YaHYH?DASv6b8%L@!iv)z%&+PII#>922+jh%W5`i-!;++}x0>tLizb z3xZ+hQ@w8PaBkOaBV~r0%+f_aXV#|oDaaP9L4Df>`T9jZL{pAL0-jAL4c~qsAzeF~C*CE*h4dt$mb~5&W*x_zYdMZ4Do^#~KbWk-b`g z+)awqO?r=SL+dMX5%v_F8nBX$5qpm7O{a@@!BO=6Mdf<@cZf| zTyuwrO@Dq{@mIWMHo0#M*vh_t6V3sRTcnHODCG3!803lXvb<+aj~v9aS;#dR=)Hy5 zhJ4j`)F42de;gdQf@hPgi!rUs!lsZR=2==mt2?(IRyPV2H63SwinwI0udkg7#=)G*W`X0uxpNO>{^l zq6hm1LJC^3sT$~jgch6v6qEx7Du{@*tk##-PtYgr=3+g&1R@?&Sqc*_X)1-=(^$?# z)gOu;W9j>~rA4*0jlz4a_=mMEHVg2i4cKO`91wxBpufM60i$qaiIEpl=;3n+pyt%k z4)XTI0yYr&=5j?D)d(zvv_~Am0<0#5Op&NW{(~nEcPr1mM@#-8u$D40SD?kDnt16Fq{wdB`%U zJhjj7-_VrZL=znf?j05)Dxq+|Q+#3o-Mq-(;J&!JdQyXQ(|gM|B?J_!Y?k(@$auYYI6v{y=8ZKOU<(9H{VbE(BydlhP z2!K6a<|;M51Q!EP$p$T2@t7g(46#qQG4l(W;zcmrbrqCVj$z}Q6Y%Q;_nKT@kM>qy z~LZ z#8%Sbxi9*uUYZ4Oyq6FxGMZLC}FLRv_HQO+$legDmds;z|3}bNbVboU^1J%?? zaQE!Azq;hrm-bw3^(}9R1_eX<>rjLfW^GH{M|Ukund*+*0CtbHaxzkx6qe{`%ht5- zHS>1ampSA>h>*yJHb$6{Yzm@PU|TMf?9B!ho_8fmsD>wf0w5Sv{`M<}Ty6_1%Z@ml zTsEe>pE!~e@5JqMzkm^iiyH%NQFKL_35fRW6HcFN^X+ucy^-UH=~V4mlEg^CLL01Z z)~{ZCM$*zAm5Y{CE*(9s`Gl5)fod3YrO)G+4vJU?cVbW)(oinjSin#%vV_5)Z0po+ z4&WSaxL}FNrL?r`m}eAof2&Tqn}Ouk*{&xvre6DT*v9;V1!S9Lf`(y;ppY7f{&#O-ZY0q-z~>= zqj_xrfsfLd#6SeObE%;^j;GV`=oxN9SQ{bp*Kz5#FuL!uq$R~&`ASfZq7(N0@BnB# zw^YppkcREj_b>a+Pn+Z4&M8|t&E`&56gL*-ltIUV93+(835S1h5kXgc{bD%)3?~&# z48~*xR>^V-s*zRsqO{ZE`Tj0Ka&dP$WdVtJ&j}%doX^2n;4k(%TsDbFHOkbe={=M z9ouf(N8Hmu#F@lu;4baU;&7Kmv@b}b&^k#H<@2W|4V?iYu{wo)v@YrqAEv=B=>{HumojnK}HO8l3YAr z?pavmvzGMR!6g-VzFx#8bwg>Q^Gqc!GJ_OV%)?&Z2>0$w=J(|mX%US1gGAnD$g^ie zje9OFb547elnH@cc^NFX2?v;Q{^!1^tK+Zx>2mWUVbtBDjI0HWtG-CN3=ps8GRFg>+g16&VVuTwW2B}(DZM$^32TRD+Ep1A#w(ig4r_)J5 z3o$s*beEsAlfSnN1h?s3wy}I^&SLACp=>l<*`ttQ`pDnVP{V$=-dZd*$N?h9eOsz^ z=P+)EXDhA(h!|bolk)g*G^$4Z^$4k?dbQi&@*%FDy!`cB;@F6iZXj%RjAegu8k0(AL=^XS zu~47H^y&8!+jCiHXi>(~w#ADA=(#mL6gse@;Z-(q^8oq6j1b2Iam9g|HB0%AejZWs zhJDiX%j(mz>7_0;YhP#+ionfAOO#SY=Yr!-lcjrkF%rox8gr3Z$HN z$vnxlsqjAG+?{;n{OG~;02bSW9}6@9%)|;o3n7WziyyR(@)aol{(L<54Q8XhPFDu< zX?_cQqWu$|hX%)U7r7c@srJ2zzh-*anX$WXvso@;PpkXq=T<|K{EvM?A@_M`EdJ+g zU&iiR+YTk2+Dx@9Ms-XmCBm>K3nN3wA=PuEoQ;uf5{#Eym*6FXZcEs9ixYK=Big0W za=6MlbgQ{K1Ur?OsG!er#7aM1Y``xt%@kt?KvnV#4T7AdU?_lKTVp=Pj}5iP11heG zFsRGmRA6F-)O0#T?v~k3$HcK*17+PkVApjN03fqx=}9O%PmhSqv)vZ89U(1^@F(=o1|gn+BD}1`2&M*S<0G)t0<8+!>NCVE_Gi1+EKqDG6&Q3 zxS;sko*2!50cn!j^=ib?i^{S_pmt4QvGZ}URZt1~#0`#zqYv1!_4DaBS)r#=EDJ9^ zmI80?$M#OC)|!LGqpuh8eA_?aCczfkmD4)2L66QEA+-q8#-#+v5blg??Gg;#w|gd) z1W?L6%Rcb8apS8#ybjV6+BCY2Vejzs>mTJmYD{J*E18tg0|3)b7URl`aL}7DBPL)c zL+H1eW|reSdq>I{NEs!X%ExF&KH<>QJE)4=wVZ60yk1wfR^sgq68O;@kX?8A01Y4R zu7Hh;W@Ym)!#4WmFn2ZsZ(eWwNFd2!^DO?KyG#JVK!sy&krXxb@#qla-1JXBl%*k|*BM`Hu6U0!=x z;wINLHdBJkRk2*<81io9d57{qB)x&Y$PCbkVAidJI-ZEi^!^V`M0R|EFLnZe2+UqG zVJwWjnl|u%I%D}q+)LzOfdZ`{cpjW{?!JGf zr-$qe2(>lnz!}`xTJO4oBm}T_zIoUkp%ljsh*?*q< z*{?8}GKg7Aa%I1wpzX-nEmCU!K@{#PO<;Q_cHX{uH z@NLyC1D5^tn}2P`nL%~jV5%zn8kllta;w&1$EBo5g2ra-0@kEKr?l0W4e4?C>r{y) zy(>{S(MN}6)^ZQyoB`h!Vr+N2B71RT*%w8A5LXs~Vd9;BQ)|Bn=II(t%BuAFr(DG= z7CX5TtlU&%6mIx)1{yJT6|1J}J?hVoWDM=q_s(fh#NX&qXH8rO`t(vnPyEtLI}=rv z%Y_}}4zZ6STH5+ESwzn=?!jMPh$i(1$syh34S+-}7fXlXnwa@Nn_T+s%nQU_o_!jU z`G6A{t@fM=T=Zhc{D$0yi%pG?u}r}+gHnbd6p@2m_3B6ei1d>4%X6Oed)1JFoGhTUMF<{PWa6bHifX&& zsp`Ak!P4cJx$^Z1U6-Tg(*40b^7NIEuMoOQ(`+B5Q2n~X#DZLZmh_>&RK)`r&P_+e z5DNWbxl$LjNA^;P*mwJ?SDI^v2a@Nc*5QN>Fl z#iBYeDK-Ddad8qzif2V>yCyPI61zAZjH}{4so=4nwqSabUFadPb)=!;5{pm|{TM(} z7n2X&&&#_&@;ty=FRc6dh*)jAzb|jPPU9sK`Qs=>d@9Q`U2mbxGp&6{0avE-sJu9L zo7axU11o+|uYDkxVx0$9a5CRbkW;0?xly1dA68J}m5)RW^x`i2mt*ZPj@l(Wc?3f5 z&X&5K#LU6BGec@^#v&=K1(#Nl$Z%uRBUqxDk7Y1!w8LuMf)SvPqoH`w>vu~;1EvLrQ}X%73Cx% z{H9fN?W&e!hzglE=3lZBCE*ReFP_j!aA&3dr{wqzY0D1bd72r**Kp_NYzmIl%^a~(&`O8Y*pgy z>})rCCw>Aw=My<7A_K&G&42|4;t>AE?)dVN>q5dQ*x#BWV3LEhC^*N`&0O!3)^lvh zbVJXXmN?MEwkTB^lr0k?rI-31bsA7@npxOrgG1W$5?7Dg0yV3JaZfA}QsCn*i+8A> z?~pLNKGdY&jZJ@MHLAnwz_=psC%U;Ab`b?G@d74}#*Wm+;Eh>SdH3Ae8|ionL3&8# z(}ZL1>Ur&mB`|tmeo8N$6VS@)4(cz4Bipba1 zbo*bdy;V?UQLrV56z*_wcXxMpzqmVG+_li6aCdiicQ4$fa4WQM*FuMW-Tmfu^hD3c zOvH{8nYp%{kBt3sPOg>gdAjbK0)7!mg`DaKNY8DOsrz@Z7+vPc4tMwJ$IVYe3`mSN zk2wJOnU;!sQ$z1po~~SZjrMZBPrtuB+}r(w@>|%-Bhr@p12lX0KaWNQe-zyqOPS7Z zGyabLSb?}PvRe08E9UL*-k_)mFh>*}n(?$T26fhi><@w%pcP+uAE=`MRp!JgmupA< zd{BJX|J;97{X~j95)M(I&}(SJf%Uz!P-H7*na}84u2T~w6sgR(Ps_?+%=7+Rxfq+N zi`vq+@8;w4CoI9kCvLVw{B?aQqpJ2wN7!4$UrGJt#LltrVVcsN^{6X*c;9jcOI6pv zp3LLdC=uPM%r|Uxirj7AbEf4t8zy4r1sHGkZJ;3TrF^jIylq+1GqG2fUd78+}I zX-e#-9k!L<$sVNSA0k0?0QN+7>V3Vc#WYUa(Q(f_E74ZP>0g6`?WwsUF|7Rxdf6AYHDdFjnaI$b4kdUzJeQ6$WeHm;# zdL$e?ykFLre%OCA+5el##`@nTvKo;5R|T{G&~^F`#{2(R{2#~tM}X}=buRul=s%d` z|C1;Ge;@+$vh(o%ClQ#3m7C*#BLc(ts%xx&@IEO`PEoKYnJ3CpnOLS%dJhT|j+2?U4uNd_UMI!E(pINwsEO$BMwe`%_N@YsvxVW6eeaB)fp@h{i)4=?KK z(r4S!!|QC8z@5O6;9>5|b`tS8$_TERhwrhr{b6||F4VhS8~bHOKTbfQ%i_=5s?4fA z+}SB(1=?(Z9^;*sxaF3mo4Pe znzNg|RPTP3j)X$p9Zl!3f7euW2aViYtCcC_ayb8bb~YQ0uC1)5A?9S$=GyzYI~bap ziioSPAD_1(%uUTd`DbHa&STa72Fo>j95i>P9@6xY@=>Yl$Wz8uJ$Vy{n?$|v!N+sz z!(%gO*j^dSi1D~=Gu%Czidbm=+nF+0oz1J5qV0QF)2{b>Pl~_ea|e81Thwf(E>cg+ zFQa{=tCf2R#WR;?2?2B=VjC}dgK5ldmbwSc&?-%CPxWQZ{2ryKj!mO&(9GE^-!zsC zf;!L2pY?H9X(vURjudfzOv^~@IHanz6nCUuTD2;A`b{CDn7?L+x_Tz!-mB#;hXxcc zQ!_Unj{(K|n@s$AD){wW&-kZ*)x(zf)K69D`T1IZ5(YUL1xU7Eb)x9wxR|x~^%b%a zTo*Om{Eig}40~Af=xf`z4V`&?3h=2eV>)Fu-{`XxizFq=pgNGBp5wkp-M{-MVKj3B z-v}l1bE8aCZG94}ot!}%wH%JVh3p6|V;?ah+atrZ*r(1T${&XI+J-?RRna@HB0hrZK-gu;QQb8i?Z8|27Mvk6RwT8mL8y;q zr^WyPX5b+Gvhn=AO^sZ$E>DNRl+9UD%P*)D%tE8>iP&}c(|pjRaElK%{^Gm8Rl-V- z87jRgXCd)!vI~Qpl7+OpxZ0}PnM41F-K}Pq->xxIY2Ap?mNvQOxFgDwA938BwenXn ztlelzYRK?d%o>$r%bup~kj=nu&9AV4MJMys27O&%^>O*`w#}twBTg@@eXUuX%S&` z>tow%MR-TJ5Duq;DeveQ11CN;wh+`bh^Zlx$uV8=M)MW_ozwrkU?R(za9@q4QT@{&(|NZ zGsg8rEsd?-G&7Q60e0eH0X`2-ZOi|xm+&{whMF+eyoCHmXgEshRdf9PmltP9gl%7{ zPYpaqx~-j*V|XM}X08W@iJ$kakJ+y%hZ$%LntlA0_`ba_JI+OD{`XNt?O zcsiH>6k{Cl}~k>f1-#8gvaJ)d|%L+g7X z?R(rovs^?f5C=`f$M<8d`jk*J^sz-b8HW>Cqh^b{I>vt!Oz;BpO3)dNX?_ zlP>e#!`*YX{88{|+h~7KClhk25_uHr+U2)ZoOs7PM2k}#a@)#EgnzwCOS$b7k)Bbo zD=of6Lc=akGb*+{IAvus-(GhCQ1DSV$0*5(+^u=#r!B-@!BUh>^PLS!6YEETi8yjg z#Vi^MUHOU3J<8$_l$lQ6?@{?Y_c4lfRB`yS0@a~Z;~>e|v-h#ex`zd#jMydxW`w3J zftc`ro!L@ImYy6*5hfLDsa~!;OvFfgdLa4UaNZX?GesnKLwWlMtp27869k{+-)3}0 zm@NEbc=Rtnt{9IiX)zd9~@6!V+ zlUeNzZ8=-cqsNOra5(h$V^$lmo9=y|FGUtSrelO~|II6yW(}hKxSU5w$Wc6oCWJ|O z-gFHGYflh9Vx@W6E6gul;RY0m)kNNXy=s1!V4ecT6ukD&Ev#QfqI%d+=N!4s*lL2z zRI;1Uuq&Y4$QP6%jj(8%5KDky7jVw!3|c?ySwg5^n>W_5m(~btFI--cEMt5rzFz2O zRov5evLoW42*q&7+pDR$S>CgmDARoPb;y>gZ-aYM56JPtR4BMn$S5(;IOQ9{vTCnb zY#)^BPR~5Wdl%{!{Y3^be;y@tS~wco!O!pcq4Ss9MQo8wX?fpIj_ph31N-E?6$Drr(D^%?Jju!B#pGD*igL>;hr~=rIC{t8H-0)Dr};e&Y|-x2!4M~(L9s^^}s8yNo0m80yzh*4{@ye zNP4jK6N~qb&gwkc^~PCyP7#>RG;9rQmUpfM;FqkD4ExY3C79*_sO1|pBRPT9sir9a zdti04X$PPN$dF`O0gx{SCG1hqV#zniL|W2f$<0$p76Fiei}DR3k$ki^CF#t=0aO39|B08&~@8CHWxYoJ1kX(S-2B%NYdf|g2#)iBZ-7@cAo4Jaxp zPb>sR!qZNa;7|_B(Eb1>%d(0^Vie;r4YSaO%Bj*xMgYW%aTp{U0Fpq&MALi#WHC*0 zp-7}J?QQWfv!qC*Kkz<fahs@YP3QL zdvQQthGA*on`k6T$#V~YSmuVG)}MY@h;}<|Pmp#yWsi{7pL}=&*iAW{1?(mrJ_B}B z4OaoX$%ZF^-4w%7z;2S^JK%ZB9xrWf${sFlZtC6&P=Inc2`E51ybnB2*wX?EPz@IW z1;~a6fdUl6!9W3$;dkJ9s%aX)0Jup#+ymSsA6BCEkU>i*REw+!c*;Ac0X*fL!vGs4 z?FNxXa?V+RHaX`g0Jpqz5}+@BPm0zd-ZTraBJZ37Sdnv%0cgoPrvS9%oI?O<^3EB6 zG&$!80Jgky0svdiIS6nh@0<(JE8)?KbS*xP-?O8gNi>ZDWR>u!!Fylq-mVWGwuDXE zqNJ@5G1Up`8-8!^esubO0kmXDuY~ot1KPVkoxDGHZ$AbP-@_(fQPQ4>nf`wS{_oe> z*u8BXJhTs++(1riBV=;q*WdPN@4j&I-q=0l|9K3Y3BSkN9mwHbn1tiY0hUSnAVIaL zovIhcBp7PWLCe)p^M!y2=f@MK67pLTrd;Om3YR3RXzF5s^bwlzuHF=`fbtX&?mUpL z@n?C+aj}dPC5UyNtkAMBL_#qk8eWCG1TXwF0tUBi zf*O6A0v>IeBvXka21GXxC>)na3a3I>B*9bWVA>->z?0{o+9QI&Q&h)vj)T#V+QbmS zlsJ?qqH&~HLO@SZ?Lm{EMnx)191ITyJ^%~R3rQt{BO)sr$O=UlC%(#eB|;Xp!BvHp zCdp5g0VJo=i)l1zn8kmT3PXeAIpmeQA8$p+1mJP)v}xV3bHNPzNo9>nGfg z=c^Y2T=*gq$1^07We)NM_!DBX;UsP(G$)!+Ga~kAW+lui*d!K81Md@>D@X_v-Le@VvRTzSDPagHo#!KlpI0vHX99GR^gSrm9xdiL;A3`O!xJXz!)r4ot57*x`U z!;iTD+3jzcII=U4iuq*w5hId`&dfVzw49+J4&ExVaeUE~gagL>NSWJ;{973pevmpv z13X6}jf}b!2U%kH6Tff}aF9F}Z;qv~04;14uS9|pZ4@*YA6|sV!LyeRMOWJWmA7cp z0dpdByd-<5ko3_!Lu(8q6J@8~_dh=*z-_9DRgG*IzA{)9S=D2R)RH!8Oxgail*?~1 zJx%up^`X!wLjqUAq0p_cIoywF46|VtvPA0qPLx(csnEQTqEMo8Cm-I!Wj!1{d@rI} zeL;+J`XHK|4GlK}Q5~pE>3*Od0U%Qv`mxmtMHDpH>N88K7kor=|I`n@!~fhHa>d-w z-M`YGxBH24jd|NE@q)19y2EZP{FVoiM{*S>6M*RZ?G5~y#iZcq32r(UCGZb;AJpT( zlhCu^j=>ILaR8)0z88WQh8Ot<#q8M)q(EJeQH~L^6Q{#gL?7o4MJLLCG@oVJ$apQ zooJoloLHUEP7T5znOKx>vmJBKd1t%lnwETw zoxDH~j~b*~l?NL3Rg1!PdmCCeks94jm|ClJuXI;*OY2y=Xu2JKlHoP!jfH-aULg+J zUc;~SfYu*bU7f^h4ZpUk;0g5m$hHkz1ezHZJNJR$A78ZJ%$vNCWfl) zKZdIKjsH+FkhKT-k8jR(U$~09%2|e3I_6_mrvNR#$e*NvQ*PojZ zad)9F;$`is-KOPPE3GI#pQHRW1S>7n%QIAj8yO@YSsCTCkV=`} zYoIA$n>3F?Z%$6pf@1Uz(Fow2AvDdtKM>gv@SW0I!<*PsoG03Tp?p3|R(t z7MK*&(vN4%Sq~3_)P$G}(lo}c2WUeygHeM=1xbpq*Q0_U@PeT8iL}8M!CU%$jfq&W z(;=szEx|cOIGxB?Fkr#i15f%njOkdQ(h(IPs30%`Z~A$R8Calkkkr9bzG^X$qamaq zMDr1Gz_Y;+VM4*hgMj(pa3Bz&BZJ6{QCU!NzyJ_XB0}*n_b?D5!uibc2>0MFfp#Pa z*N{En#5+&|BFrQhV_=&ieDTojf$AhsP7vcF=<%>TVEo3A=z(7S@Y-PPs4(eZCe`*F@J$*T~oSJN7$_JBm93v)@38Ku?x5|M?2zt=?tt(38*|qq979|} zUP4`hdqD69!p_0{4C)H%3gi#s54`BV=w}Yv2-FMG3(N}23N!-ahTsO<2s{fq3$zWg z4Xg^P3ZxIB51b5|43rO&4~zOgjY(0Ch4`hwX@Ijy#D*#oTu`#jqUd}=iXUlqfL9^O$!-w%NmF7TlDULy|7M{ zos=lIC*uUoR*{WnJR`h1e&45Ey|}F43OlT<>A&?I)u~G+Z%EY{jK8L`hjdrbTh-+m zCAYr2V(K)HQ|6P$^lD4A8aSVICzUMER%z`7H&Ea8 zi@cY~t#VQg5$w#%Of8hm%53G>ytx|KS2MI*7|$6z9^*=9gbMjqdC&E$@4V07h!^$Z zWDNrA5Y{ADQPS$=*DTKA&!ei=I7hviSKhQ5&Q>2**~zYeUbQR9V}5~x1D7VA4P9$J z>-x)P%OI(PZVqeL)kt3LI5daTd9%zuPH9V9@)4$yWi-MQ-Dl-1RWo-tBFS+@8rhmT zzHm)00&Wa!W5nXP*l=K)&A#yI1uwnu-;_IN#khUbQCk%?`swbC zup0v&rj%C}PYq1dpJv_xlYQi;aRfK#rd@0AtE4Cm(x}!%gK75yuzvQg-mbVcbYaTM}3dpc5xEAIgM!Ko@)NNG+`HOijfUS|ZI!e|RP(9+t`^c@jdNruqQ zKBGF2z~Aj5o0(>(!PxUre)Qhovwivvht^b@*Zg{U1c%ob|^4wp33@!Y4 z@7~GrySi)&=vYzJWdZ%6e}x8g29KZIJhkN8G<^1^nl9D1NV+FSybQFbHs+gduK$qI zw+OoL3F?6g>H+7#pdnBhBoqn@J@_^ZQs8?2enda)=K_s_$Kmu7sGq!lm6H$ZEgTS+ zDi4N!1TLDN;1+~)Xc_VG$mjTu<=fq-O%oJfr8vmPav!H4YME|d+r8eetqtC>$5hVe zpDK=Qk{0>IIaZv%r_LvwD2yv`WT3OFWoIDo7qmUV!SpUr`x@2S{`){*VzE=wN%aX? zD?UaHtu?G|_8;^$vszC)=aWy|N-$-k;;Zh!bVauJungy7%T}^Eo0Aw>Biw>P1fTkF zddy6J$nWuxID@6^t!HV;@6Wz+De-gIxd5$E8Ff* z(<~$8C)`Zs|MaK(pgMj^{52s5T~Y5+gGLro4vh7)&$@m>KY6}{RNDpMdbqkF=wayp zX`$da-ulx*f{@jsuu*7g{ISiu-tUVO(?COv9JX3;I?zC9KkES0IDd9l|q zzo=OqalpgZxx;0&E^FZWQ@;&R);phmps099g_kmTbo|z_df|M!OOI(*$jvyN1e$Vg z@p^f!2l=`C=5tQ3a2L@s(l3EnPu-qXRtN+JZ8VUaq21pHn&Q0j&Mz<#Jj!LfE4BLE zqT1S?H{7Sfe31T{p&~RwvyykE>o{K$7^Cn+4%LAU5MA9&4()KkN5cj~OH%#!?PX$S zLa`F$8p0us*1|fx6!j*C`dLQ97->!z-%BZVH5EdzJmtPmN#+UttNdJ*MYTN#+?1zf zW@aW9K5AduD$JZCw#`~=TCF$2OJgxEw$?GP{d`ca6Lj@3vAp>Se%Wo8*E3@Gwy47+ zzxjM0YzDe4R`jL&9xFMmLXGzch2Dk6WUc+Nm*_C0R^R) zu$R6@lFVZ!^dhb)0x^FQUv2r>$LHl7a>^A%D>Un>ZY~gp4YAd$w;-iuu^z z=v&GUP(5upG=5BtYM*4iDRO3#uSV*Ekb{Ak@Xf4ht+S+oejB+-p+5u_4)xDRe5h!x zLgylN1Z+#4c}km0JLedARCmu-PzvilkND_Suj%@CK))K0a9-q6-L={2O5w63e4MDz z(9F%8A_|uOWn%5&C^wzoX&~h8iynxVB*=6=-mW+CB?P2_BI}AZO>n|bs=Y*wBntl9 zhO;Jv$91oC2Fm^^kF~Q=zX4}ovO1ibs50As?;7eX7_*E!H-5Fw7i?xXrTzU+rBIAt zn+|_i&9J~IR?J}QF(9aK)w<~pt`(Hu>VD%G9Kn$OGacV;XApr}el%hlc?4?Ya5a0o zL5bCUHI}UVe8AVbsdQS$N`xNdz^l6;DH$h$KNXt}XBKCVn?qjqh|WRNMi zS4ictlZ&$cy%Q)fB+L);^hzxr zuISiJK7_1mZLOd$`d+NQK@KaYOCq-bUvdzt2Taw2G2AM|jJ^y5+6!MFZ+rx_5JID< zE|>fxpyd)5-MUt7lKmwLqMkn|H-X_hhAk`3f;iM$|?#dyW0zkUCm96z+Mi zWTkzG5xnenmn$^+eIvU^H-|p1_Bic3dW-7F6YG^VZ{}y8_UHgv?E>BDb5!I^Ik%3T zQW)dlnezOGHH)=>KxLIttT63Bn(3nRmOQf74^_uGJ^hZ1Fvr1qH&eUFNqGE=aYfD( zh0vesrB1F-+;7}3-tFR#7Hg&iPsdGL7#AAH&-~x#|9pQ~6J?BvE$wS+lje?E%06zU zCJgBFnWMSn#*L7I;pTnEb?Ez@jGC5uc60B(E4jY1KduDxyS6%L^W%ae7FA9gx_7C}= zi6?j~RKv96MnB~^r6<)W|MK5yc=irfksA&>$l^fF&@OH=Cw)0hODQEAeSI4xDN9W` z0%k01cuZoswk3zPL#ORloR!r7y8#R-iU4MD4=9QJh~yr!2; z5qr%oQAS3~hmN4pDVt{Dk$nMLC5xni+|2ajMqJ?Zc&~c5_}=p_*BPF?!P-A zA(2z{tb^55Y+i)biRBs9Zm*+RMf=^o36vcyy;;$kxd&O+EY@Dx5$CzOkm&bdhMa{> zwxSaAi44+TOSxlqEC5i zqn+tBm30Mewni#rAhDSVyE*)pyAAKq%cd1FDi8@xa7-@K^5Xk^_7}X_r4Nqc(s>I{YyVZfpfDrtaV&g+vXYldf}x}|-%zPUCuttM0mD;6oN zK^u1t&p&1&tT}`@U3rXagl&*gsPR14-HE1(fUgZOt6$+9&TQn(R2mOKMI~js|c*6=T$K3!g3@X;zm%O07Pb z;LGP9vtZrFeGvZtz6T~eV(*LyBTeyszV_d~p#1z70O2@g9Quh=A8rd)^%1;Nf;)BH zhoq_c$u*QUfN04QjQa&E|491p7BqYM0OF^a)7t+){=@$-(0`h{0boR5>pwpsUi6y5 zr1+yhgfDPsKtCfs9A?oTjI)Ax8@cA~sg`qFq8yqOoETWRmoYo-t=Swx4jT>U?QN@* zhH*OWgV8jH-8NEH9fsNlfiIHi%s9FBIDdtJ7<`=Io`bA^S~Cc_yJ@S2o4O+i3aK>?dZ_vl`i#EHidgJWAJ7 zsrHj|D!44HDizl17WTSGY8Lu8o;RvghAabYGaugf0v!AsY)E*# zKzXoU(|(wRc;ht=2jaO&h$1I0n6WbU)1>HJl~QqZUxi#ma~Oy-q?Z$8=-9{vOuSQ> zdDY*U=;89n=_w?BNXyfZwk;qE7-QLlC0Lf+kdZwW(s(#s>Dc8jis9hA5ALsc6S;m2 zU7g5nI9)PGrl1k`u`(BusDbYfKKp*~p;6lV+g&3Y}d@RXQOM&_|ujlo@AfH7wQX~Am%tqYdklUij zW%(GptXP&aO0FeXT}I-XqUITBKjihU((QZ6#pG}?@J4au9(lzJ`*0yl!f};=31(dY zQYcOesnOur5>88j`Bbs9TRwMWX)TPd3em(@X??Wmw@WY!$R5NDX$T55@(=V(VHk@v zg#&t?JCoki$Drj3w*wrqK7{;VkQw{?3ANG!B{b-yX?8^@r=EYqyxEdsZDY{zrI-$# zG5gaBR{sSgIoeO-KJ`)Uk3h&$q!X`OeB28JNfwo>kdNPk8TX!sLP5lnZTw1^Kq(9p zAJr!TVdvvaNT`1EQv;LQ#ZaQf$1ewRV9G$#h(af(PPhVUN=?{8&y6v@c(x)I^8zoj6*|NX zIz%-U1Q#4o>uQTLpL35+NE$kCV7&psunw7gl!JY?dcWUAH9UXR&iWki$_DeTX$QYl zu4>mhCE)~Ss&uN9L5bHc;wcjW)xT@d#Dxo2(qew!gI1M1gyeizvX*Rdo%1iaO#&>j z^5*E#@S&;&HGYnoB~R?pt+PKYBJoQ&xKxgb{Zmrfz_oOTNoKZaMh?XY9hg8W%8U^p zm$Ij|VPqjq56pCyuTHBPK(_MZ~ zS?Cqt*Q7Zf=LGqJs?4<~dAkbzrMgC}F>_ggmoMf_#cqMkf3qz=XR&?;((yHGRmR38 z#JH1KD1%5dK*Oxxfv>9p--0{%0>4f(zY4;eya&l;DR1D^Q_+u-?KwUMw{~VnBfWr` zJpvV}^8=XgHOW>{pS*Y?gN18Q;S$};F-@6_0%;w0HpirjW5IHM7TR!sqRClvot#>l zQfi{GqDO|ZruxtEWnKlzWp0Vm0yiV#8}J_4dwIj+TYr4|BJz9Qff?PMd;)Z6z=IIj=eZ9b=yV5utN2aa<#7G zLHa)d+z^NljL;bQYu^~)?_Yv#XvN6ISfm0O=pfiD^0DEh$Opoi`(+A`{1VDuiueGK z*Fcq+B2ak$cY))w0s`z1v~ra1e&GHB`A{qH_2A)QU@G!r>0}c8$k8J|l)+R zYMrZ`gHFgNgz+zoX~ih;l*3AZYYA;Vi~D=lK=b~5|NUE|KE$c&cDP87`PX$bS?WhC z=EL!KomjFE%;Y9vM0Nx=LTp}M)-hZuQu;>(1wi;%PfZ6=Rq<_{sGuC@uNp`>0E7*4 z7ixq{rXL^sXO=v$tuKBpbUio!;g3+JL}28hPW3nV;9%BEaFgID9jwPBps%dL%&S z5t&83JP}TiqFzdQufs;Bl&&x|LCKb)gr#(B&L&o>kS1HgMq7|C1y`X!JwL&zA~+;Y z_dDtko{(CsI=;;IFg`3@r4n4UU%Gk$oKDvpI)PMk0uxFiS3ghk*k$1X9=AXPve!j} z3Kc&8)IzQvNC^c!S81+G7>0TpftaD4SCn!BTZ0H9U4bM*C(N3o9qzA1Z-8#zMYo6* zV_pGEtRyH=Kwxoa6C}$g=g{T6hEB#((V|)OmcU|RBGs}PLKh^}Lh}LHlHh7XxT%91 zo+6SN5p*ul`d?3{fZP^15 z3BCv`M)dJP5m=`o5?~^PE&^@`jB*$OI*vlV8tTV*GeH6ayEN%C-hO3PkUKXH3TZ{Z z#2l0XPj^0a>5AQ7-!w<~nhdQ*qv}D& zr$=gqkwv94^_WL)P!9R4rk8oHoV~?VQByRZhj0j20xCU{AVNE>KodL|vf9V8lORTl z6ebArh({um4@SE>a15NZIBWnutbmlFzr_bPD}KTq54As8oKu%KJp~Ma`wW2Oo@kcq zFhm(E!6vCe+=W$u+LNl`Z9BxiL;^diX(X<05Z5Zvt+Q(0;_FOSk-W{cce#uC=8D$Sxs`XRp?Kt+Ok8M zFrykH7r90XJ2Ar}G{cZ&lqMOgjh}ssK|^3w5@U~3fy~Lb?l%Mm4uwu_u_%hEamgej zBS*~f@-=%0Zufs%H>8ly-ppE$c}=6ORQ_AEQBAZcT(yvE zXsyf^918u+%_c%0aUb%WJ-$)hhc!j{5Z)M9Sf(MURRTSyLivR}qL>CB=nq0iIn?2? zLwB&_+swZYwGJT|q8-LxSOBKLJBeh$+Kh#E=;wk9Ta1xp66D7-A=qn+@Cm{=7!nc` z7kvZazyemrjUzQ}57edJ%gYx-VHheD#r5#u64FXEKO$nC@DD&5A~?8YBpSg4k>pLfZLFBI_sL8M%fW6s!8!C?s_F=9 zXZIxO2mO*G6L(h7fv=2GA{3Molut)d-+r=0$N(sd;mM&AeliQg-TSRc1emxeh{>^m zvq-!>A8?S7M(&K3q4|Z}B-n|ukf>6~$dRE-{A6Kb)uaJ4`}G{Ynk-}D%Q25%9ie)&dvrmUTeAd{Ht~UyyA0`jy4FL-4SC}nh zpghYap=*Dc>E)D=Hca3EjAGk zsdi~aCp}30fIxf*mT$%ay`)V2<)ikHPHSLo^!>+>BT0C>bc#-b;0`4H7sxE={a$#{ z*tWKt>#e1hP+rq{j`l%%dOCVXX@Oe3lo)O126R7}Z3(_a9yCcc$ISPZu?`Opm$}+o zwsL<7hRA~_L(qU5n+0uv!9$}nY%Z9paq3$I?{jg$MTR03o0vsytZD^oN!CRgHlZm% z8QVr|=r(CHye~TMk0>tbH8{~{Dikoz)VHuK(3&?m=}l(rSlEVb@TsHJ5h0hS&XQT8 zC4omn8e2sSevUNAntJdI&WJ>pT85Rc@$PsiEjcVX9Qq&nvzu9th`5jF#kDcDwzmDc zu*cb1VywjJF6`84aDXgxA>vuWr^f#5lSwe+oP`7Lx6(_GikGrP*vMnKSWp^_X|7HPJDCF zZ#JGzJ;N=lsA#>SetISH_u4n3D)oklaEO{8iV~BHYsUr%+bwK!p?wyX7!9U9r*$Ue zxK0!>&o}xILV7A>-l+-0xkftcZked;yB&}Y!!*o~1TdlSxI8m07D$p}@%4Dwzc1dV)CH4q{{Zhg4fivPZZXpn}vw|e?+f+l^jH#^Bb%Hr> z_NTUWTdsrLwTbug_QIXrtBfHGmP_%&Q!R%I&@;yE-@wrVrkKxv9JNoj$m|fy!W1>P zL&ejhM2st#=yb9G6Wf{0*;gAp8ZMZZEygu6d|D#U6!?CL(qq#nC{(If6>qi{!w@vM zJKNtbGp%IZ|F~1YZhQG>-T}mlFUF?llra64XSXpCv=MSH7wRG|{!8o!^bd!0*))dA z7d;ABl8c@090YnMQq`dcN`95C)=Jn8=`vXwTNqiOSPKX{Sr|+NnuI|IW|q^S|gMxxA!HtLPyN0 zOhlY7ZK=3RUS<8?{%Aqg^?4n5uOvJ$=*_hbAKRR4-i`JJ5I@|7Z}BlhW1JUR47Y!M zv4T2*Q#d^tvl+K>ws~UTE=8~X9kW~#=X3tI7jMX^QIz%IWYC3N53BVW&i^KhM$Sxc z<;?x^ta2vHMyxV>%shN&IFkG|@z?FK%fL_A7sD)xDv(>SW)fpqQP6#jl0p7_%v{u1 z1PL84SO|f!H4;~8NC;+Zlj*pSd31p?8B`i?Z z*snjS%vD(rch9z7OOhHt89soXu_F6hcP((2m@jvG zIC0~=N#s~L56T}N?&XEUd%^!AYijy3()$?HI}!5yuEgq?!#G`)m|AeWE+^^wdZ)2r zu$AHN@rh2~Xnwz|H(dHMUb)-PHCFYAb$k9q-m|EP%f9eMz?Qd6N!e__bHXs&pF9fw zvxv3yE$(0IpAas?Cy6J+gyB>k8M8LUh1K4TB*SPrx$bwOk_Nw0%_c}|yQx2k3~ytx zi=|I&IcXE&6y8*w^Kb+ReY?LT*BFu!_g%ax0*&dimON$O|Bw+2&c2Pk^-W1pCbhNH zHDosA*Y`gtj_x`(Q=V%De0A8!z;AJ1OE5`-=z?-ypP2}F7{;qJ^_?syzvNF3E4sYQ z`+Vb^yu0z*c)C!>jAQS*dUEf&JbFmhm`K~~dI>&T% z;QLD65te)Qw|VN-V&ZWDa(O?Zv$aZ`C}#7!Y}`YR@7|M+=j=gW)}zh)b>by|-_v@$ zVe9wL_K6Jq8M|{|wtwzp9eGkSz4MRnJqc^lz0EUAMlP4wuBT`oEL0vD8eh~lH z8qemhg4kVMp?2!947X4z4t)J?X4O*-%k9o(Y>Ep@3G65Pu}D`wM}B{|2dI%9jJjGz zEQn}-{GQe(!Dfu3f{LM6WEl@OKuDYECP_TF<&*z4wsVh~!9&t+>*FNC!c4=i*x`t5t^1oin1pc7!QW0nj52r*=MXPenjEmE_lUF~N^r+(GG;o_cOwu5=k)boy z&pMfEc=URuC~%xq-)!_z=gz$S(R}CjP?Tm5JWE8LC}LE);&-{4$od!j7tt2$ua-Tj zQ%7@tzPa?s`rXDA8_>7a<7xbep1a%YClW)B@Y;U)boM@i0NFSvy)Mx+sn6W+nE|!b zDI8Q?jH`x*Et8|X87%%fIPdm?tpVH%EiA=~hllpmUET_qBfkL4O`@e$m+dXbDhLd< zFm26FCBb9bwaTVGA4_%VG9_22Fa475Qy23_=|}7*1|@ev<0~}=uNPMW@%-gy;T=_J zY38#JYQpPnyE96nRYfN^l6r|-MP;*k1=X7WKAwNAoEZ}~jMU!F&w3!p)kSMl5bMn! zYEj-eyq!F8ZcKEpcAssV&URzjR#FrAsdQV}%e}(3F|zL8Q4<7so2t$(_qC+ExvnQx zKT_)K+9Cr+JiDzg2|*r{v{*iDtAVgXHS;$Bn7MWCpYW6Q`tkW z=dLpMu^1zF8Ii4@&Fk-lK@346?AU&cUR$-|Dn8zFgINd2O&j@3t4oYp__vY7#_#HSZ=rzimLp5{dVZxfH80O4FX`oulKX zMcs~GFe*>BWJIdq_U?F+MtYe`0j5*vg!TLUMaTTRhtDu#UffBm_L99YP> zh@k1wbhM{cl7cB8P}`DvT#y58%Q1QwzdJ*XxLZ}e?0aTf=Iit9wpe*}yF_a`$t!&e2G`u`9{Amx=4VFP0Fi5&8 z6n%9%#>*@25x-B--g+}};<_}H5}CfMH;%s=-J@4H5GS6!V$k4F)%aU?>sOJPDhVex z)g5*@EPE!1_o{zg8r@V~Zgq9{vL|g%LbJcl#wgsmml9w>)48}?j-=)Fq9~ig$+76p z9Z2Y0u$uKwE7&9M~gUENMYqi6R%;$!fIB`Iw$g4+JOSZxb9* zoNsv#3Xb)JGqw8&5`pN%mzG~1LOVt!`Q$mi&N8@YR#TFFGd*#GV7AuVqGayKmDQ3X z+GCwfvVQdIZ!{0OvwtmZMN7-L zmoQnKeo6U_%2J=3S{Hn;v&WJLSIQTT5tV#P$ArR=Y6WT%u3qbe@R>%MGc%n0^`r;9z<#W}oZ3XbUpReVE`2J#+V4u-{#Q9!nn`gzvmJtP9jx%H zfa_V7y+_jgpV`kkb&`kR><%@BUwj-n{a77y)7;I$dk+qWzHZFOO)8!pQk<0iJ_waf zs%f)26dA}c`^8n6VKZ@lTfz4Ra<-|PjSuxa{O;;{$Y#eC>(7a`uf-ajZVr7jcUHzG z#GrCHRrQ2XDC&btk{ImEUp;O>ucCo39By7+KE>wW0i59 zS>Hul8qgFO{>ot&ZlMP5ukAfUJEHZ=?Ar0WS0MekbBHY=)Z%K5=Po%p4t8bky*^x@ zJJQK>q%iwloq$r~Qaw&^{@8Z6oFa>gE0^0rVU6swZxK#&PnCu^>epktw9xc;MO0sP%Fcp^lu9A|xF!2|huTg$s`CSOQVkl~6=9ph>Yrbg=#nGaX_x#1J z1EgBQ&DP`f2dfP38fUXMGM<#uWgnMoO9Bhrh+=B?Ynj6ttuS*6a9b={9j z{^jlY2i)S!HG=8>Sw1B~)y@|M+M}!Qr6`J)wft> zB{&4qe?NVauH*HfC^tRxkFgTCUoc%-VpTkqWrxJw8m@iyMof;As*|+O4csXm6N{Bv zG(5$wH{9Mxlb$gHf?lNtqi%{!vyQK7eiV?+J!QJasdUXIqT7z>qnCX7sB?KGMVQ&> z;y8c(b6R}~MXWTJjGO*X548uBhL2h~;^S`XczE0We)vu<-7|7)^5(L&8!O26l1o3v zIgGeVl|YN&s^xU@+K}nS45?1XAhqRZq^`YO5pwL}UL`9Y`|vPW@?@pJ7I^cvE7IZY z8r37ABb=)bWsn+771*g0XbonWUe-g&*TDpvyk*j+HzFR~OEJrJKmYhA1vMMQd4Y#h zU8U^`$@TheQ&y|C!;8%_wSRMG#cwM+Eue0x1Rd!ZU1hpW?uab$&}4I1a^UM`Hbi>6 zsZofozNz&)iMviV6)7dIt#5754aVxNOM;EqH?+d2O_))}tPI}B}uZ>|{ zJq9Ny(FHl7q9r&Wx-8@=x6+Hsrwhljw@Q{tRdG~< zyDBopcPDEM{Lwp!bY^?%wsYK;{lO&g>iTmW^$MjLg8fUFAmjSWM2EzYD`D+^c}|vt z;|>Wf^#?+aKT&Vy7?+$ST_sGus_8kuVRaCAE-yteCHZ09Y|D=Qj-~?g1-I!)DmBU~ z(%yOGd|1WYv(WtO=R+zV56v3bJTJ?2+i-*r{3crH3x5tYE2v7NpBNMG%;|}pn|*Lh ziz_|a9xCQI_dnTs*)TtF1H8^tIN+XCl^*FRXymmQ3LbRD2TcaDck<a zYiq6OX`T66w^e1kr$RF+H6}S(4f~8;{pP6q4g^&VR?P}EN8?6r8xfv&?4JlKoB3n( zhd@nZxe4V9-z%$L9Sn9S4}vsJ2_1h^JZk?^xcJ)??v>DilF_CMS zPG4=+RPjw_1=h?VPgYGCcicPHF0e@#yggzjQL*(DBEfHK@N4KQfMj3J=%0SDQEc6$FVvT<2Tjp2Q(h*c^+x zy`$N7rEzB5ko~pTx$*JVmf2kSq~KaR`7v+Z*&l~2b!mAR9Q@_@C6wRS#WXRUmmThV zQ6VwcyP5|S?DAV0OH07eZ6*C5pQg zAm~PGpM>ARQKde+ICfLtPwmh*>{OC3$2=aY?20nCw@lBtg_l2Q1w8Hbb*(g-*Sn`S zb@u1zJR)_bw16U-T3IYo-Z=WIv!!mb!rHdvcfK6>*0jAyi*I5YIRr`R$!%YLY!`oJ z{2wrjr_K#@D|D2{wcB^;es&=*%4QCc42Ei=MJL3$XWXAV=ZH>Zd_nd|oxCOj3p1

ew$c)|^et@|#?Npm$K3O9_UHsU#+X2s(c#o70oX(@@*>&0Vfx6kw zui}kNnW_~Pc{$Hx*m~e@*TSQor&t94j)|c%vrr5CCU)RNjfXC(Z9|uzP4ne?pl*)- z=EWQ%aJql2K7*E^OV?|sR<`j3<{83@nXu^6j*et*re#HaS7Ih9vI~!u54qu+GuIQp z;Y_i8NRnK*METV7cG^d`C4)mj5YV6df>{LkP{AZBi|j&Xk-_GE&a8QXHRl7Ph1Ao zoNHo1;d)ZAE-HFNJO{_|_VEV7fH>Y>G$xKiP$9d}ovAorJTC^TfEH9(o&*)R4pbWr zfvOOt@eCJNoSDAiJ0swXpyJMA`QX4{Hk+-(hU?H7ZeS=Div>eqU>Hmr(9mWE&{$-S zHjSzJrw4s1lfv-uVR_JLpm~pEXSyGYprQhL=hx>wzci-K0x%s4-5U&C07G@);CV;D z7`K-}ck!c88AOr?g+XW1U0GGxAS*h<1q6dYvG{rYzjg57`B?A8ewWXCl8>Tsq5PGk zj~~NpAw?GonCeCKrqWnU01$KmkP8Jz0j7jSXAl>7GN<~!9e8;V%>Zf{ERYKow4X|) zfn0Swb;vp(lDWxSP=LnU!GaC=eNX=oG%&k=q5gnE4%r7l3|T-7DB*U!g=|5md;M=L zE>^?;C7|k)SyUnn0)uKppxSVV1r&yZ!f{Bn76gieK=9y2nhTaBx{HTv!2iecJn+s>0dM9?foYiBoa=aPVt+c*4_Fo-DfkXN~5Cil%$S1Mx$N@lgW8uN_qJmfqKk9rF0k~LbJmB#6lowhMYcr}V*xZ9l1;OE9D_am0gaE

zZhIl*Hx5XRof@v)i}Dt~+~dZ(Zft-%*gQx7Yt1 zj$dy6<@C1)Rvs-`lgvAGt=P-y0CkO&)EBRkH+}I@$~g?GtBf=R1V;d$e;ptc5(!6w z=C8avpuj%V^9Km%2mcg7fqkPF$zTv*Ru;(+Xvh*72Dwy*#h@1JK_O6Ju0He!g`$^W zfx?#hgCelVCALV!63kH4Qp`XI%wk)hWmtj*2E#7N7luMEi2=jTZ@>Lv9&i|Ti9a|J zwZtDBxFr|cBA}S1GB^gf$3KjLKrZD4fyOT39tl|*0|{Tk6%2yJE{*}LAJpPJ0NF?M z(9p#kAb^f{i3|>quqY1%9MJq*#$u2?yr>M|e+2xy<&OBbukp8kUyvEBw+jXVN5jxE w(p$G0m>SAR|G9`DGSdGIY~Z~Nsy}D}5_tYQ(46HBoB@(); + var firstCall = true; + streamMock + .Setup(x => x.Read(It.IsAny(), It.IsAny(), It.IsAny())) + .Callback((buffer, countToRead, bytesReadPtr) => + { + if (firstCall) + { + Array.Copy(sourceArray, 0, buffer, 0, sourceArray.Length); + Marshal.WriteInt32(bytesReadPtr, sourceArray.Length); + firstCall = false; + } + else + { + Marshal.WriteInt32(bytesReadPtr, 0); + } + }); + + return streamMock.Object; + } + } +} diff --git a/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj new file mode 100644 index 0000000000..c6360e675a --- /dev/null +++ b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/UnitTests-PdfThumbnailProvider.csproj @@ -0,0 +1,78 @@ + + + x64 + UnitTests-PdfThumbnailProvider + PowerToys UnitTests-PdfThumbnailProvider + Microsoft Corporation + Copyright (C) 2021 Microsoft Corporation + PowerToys + UnitTests-PdfThumbnailProvider + Microsoft Corporation + PowerToys + en-US + PowerToys UnitTests-PdfThumbnailProvider + Copyright (C) 2021 Microsoft Corporation + + + + {F40C3397-1834-4530-B2D9-8F8B8456BCDF} + PdfThumbnailProviderUnitTests + netcoreapp3.1 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + + + + + + + + all + + + all + + + all + + + all + + + all + + + + + + all + + + + + + + + + + + + + + + StyleCop.json + + + + + Always + + + \ No newline at end of file diff --git a/src/modules/previewpane/UnitTests-PdfThumbnailProvider/app.config b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/app.config new file mode 100644 index 0000000000..74312e4551 --- /dev/null +++ b/src/modules/previewpane/UnitTests-PdfThumbnailProvider/app.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/modules/previewpane/powerpreview/CLSID.h b/src/modules/previewpane/powerpreview/CLSID.h index 104e2d8ef8..ce6e5bc5dc 100644 --- a/src/modules/previewpane/powerpreview/CLSID.h +++ b/src/modules/previewpane/powerpreview/CLSID.h @@ -28,6 +28,9 @@ const CLSID CLSID_SHIMActivateSvgThumbnailProvider = { 0x9C723B8C, 0x4F5C, 0x414 // 36B27788-A8BB-4698-A756-DF9F11F64F84 const CLSID CLSID_SvgThumbnailProvider = { 0x36B27788, 0xA8BB, 0x4698, { 0xA7, 0x56, 0xDF, 0x9F, 0x11, 0xF6, 0x4F, 0x84 } }; +// BCC13D15-9720-4CC4-8371-EA74A274741E +const GUID CLSID_PdfThumbnailProvider = { 0xbcc13d15, 0x9720, 0x4cc4, { 0x83, 0x71, 0xea, 0x74, 0xa2, 0x74, 0x74, 0x1e } }; + // Pairs of NativeClsid vs ManagedClsid used for preview handlers. const std::vector> NativeToManagedClsid({ { CLSID_SHIMActivateMdPreviewHandler, CLSID_MdPreviewHandler }, diff --git a/src/modules/previewpane/powerpreview/Resources.resx b/src/modules/previewpane/powerpreview/Resources.resx index 7af9b5effe..203a0bfc3f 100644 --- a/src/modules/previewpane/powerpreview/Resources.resx +++ b/src/modules/previewpane/powerpreview/Resources.resx @@ -174,4 +174,7 @@ PDF Previewer + + Pdf Thumbnail Provider + \ No newline at end of file diff --git a/src/modules/previewpane/powerpreview/powerpreview.cpp b/src/modules/previewpane/powerpreview/powerpreview.cpp index 27e6a482f6..8bec06e0a3 100644 --- a/src/modules/previewpane/powerpreview/powerpreview.cpp +++ b/src/modules/previewpane/powerpreview/powerpreview.cpp @@ -50,6 +50,16 @@ PowerPreviewModule::PowerPreviewModule() : std::make_unique(), L".svg\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}")); + // PDF + m_fileExplorerModules.emplace_back(std::make_unique( + true, + L"pdf-thumbnail-toggle-setting", + GET_RESOURCE_STRING(IDS_PDF_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION), + L"{BCC13D15-9720-4CC4-8371-EA74A274741E}", + L"Pdf Thumbnail Provider", + std::make_unique(), + L".pdf\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}")); + // Initialize the toggle states for each module. init_settings(); diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerPreviewProperties.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerPreviewProperties.cs index 8a5b5f7c83..a1607b2c86 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerPreviewProperties.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/PowerPreviewProperties.cs @@ -80,6 +80,23 @@ namespace Microsoft.PowerToys.Settings.UI.Library } } + private bool enablePdfThumbnail = true; + + [JsonPropertyName("pdf-thumbnail-toggle-setting")] + [JsonConverter(typeof(BoolPropertyJsonConverter))] + public bool EnablePdfThumbnail + { + get => enablePdfThumbnail; + set + { + if (value != enablePdfThumbnail) + { + LogTelemetryEvent(value); + enablePdfThumbnail = value; + } + } + } + public PowerPreviewProperties() { } diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerPreviewViewModel.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerPreviewViewModel.cs index ea1f22ea2a..71d7112cdb 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerPreviewViewModel.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.Library/ViewModels/PowerPreviewViewModel.cs @@ -50,12 +50,14 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels _svgThumbnailIsEnabled = Settings.Properties.EnableSvgThumbnail; _mdRenderIsEnabled = Settings.Properties.EnableMdPreview; _pdfRenderIsEnabled = Settings.Properties.EnablePdfPreview; + _pdfThumbnailIsEnabled = Settings.Properties.EnablePdfThumbnail; } private bool _svgRenderIsEnabled; private bool _mdRenderIsEnabled; private bool _pdfRenderIsEnabled; private bool _svgThumbnailIsEnabled; + private bool _pdfThumbnailIsEnabled; public bool SVGRenderIsEnabled { @@ -129,6 +131,24 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels } } + public bool PDFThumbnailIsEnabled + { + get + { + return _pdfThumbnailIsEnabled; + } + + set + { + if (value != _pdfThumbnailIsEnabled) + { + _pdfThumbnailIsEnabled = value; + Settings.Properties.EnablePdfThumbnail = value; + RaisePropertyChanged(); + } + } + } + public string GetSettingsSubPath() { return _settingsConfigFileFolder + "\\" + ModuleName; diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/PowerPreview.cs b/src/settings-ui/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/PowerPreview.cs index 878069c8a9..7fc7cba302 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/PowerPreview.cs +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI.UnitTests/ViewModelTests/PowerPreview.cs @@ -60,6 +60,7 @@ namespace ViewModelTests Assert.AreEqual(originalSettings.Properties.EnablePdfPreview, viewModel.PDFRenderIsEnabled); Assert.AreEqual(originalSettings.Properties.EnableSvgPreview, viewModel.SVGRenderIsEnabled); Assert.AreEqual(originalSettings.Properties.EnableSvgThumbnail, viewModel.SVGThumbnailIsEnabled); + Assert.AreEqual(originalSettings.Properties.EnablePdfThumbnail, viewModel.PDFThumbnailIsEnabled); // Verify that the stub file was used var expectedCallCount = 2; // once via the view model, and once by the test (GetSettings) @@ -102,6 +103,24 @@ namespace ViewModelTests viewModel.SVGThumbnailIsEnabled = true; } + [TestMethod] + public void PDFThumbnailIsEnabledShouldPrevHandlerWhenSuccessful() + { + // Assert + Func sendMockIPCConfigMSG = msg => + { + SndModuleSettings snd = JsonSerializer.Deserialize>(msg); + Assert.IsTrue(snd.PowertoysSetting.FileExplorerPreviewSettings.Properties.EnablePdfThumbnail); + return 0; + }; + + // arrange + PowerPreviewViewModel viewModel = new PowerPreviewViewModel(SettingsRepository.GetInstance(mockPowerPreviewSettingsUtils.Object), SettingsRepository.GetInstance(mockGeneralSettingsUtils.Object), sendMockIPCConfigMSG, PowerPreviewSettings.ModuleName); + + // act + viewModel.PDFThumbnailIsEnabled = true; + } + [TestMethod] public void MDRenderIsEnabledShouldPrevHandlerWhenSuccessful() { diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw index d51f5eba1a..09e1f3aba8 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Strings/en-us/Resources.resw @@ -586,6 +586,10 @@ Enable SVG (.svg) thumbnails Do you want this feature on / off + + Enable PDF (.pdf) thumbnails + Do you want this feature on / off + These settings allow you to manage your Windows File Explorer custom preview handlers. @@ -1194,7 +1198,7 @@ Made with 💗 by Microsoft and the PowerToys community. FancyZones is a window manager that makes it easy to create complex window layouts and quickly position windows into those layouts. - PowerToys introduces add-ons to the Window’s File Explorer that will currently enable Markdown files (.md) and SVG icons (.svg) to be viewed in the preview pane. + PowerToys introduces add-ons to the Window’s File Explorer that will currently enable Markdown files (.md), PDF files (.pdf) and SVG icons (.svg) to be viewed in the preview pane. Image Resizer is a Windows shell extension for simple bulk image-resizing. @@ -1245,7 +1249,7 @@ Take a moment to preview the various utilities listed or view our comprehensive Open File Explorer, **select the View tab** in the File Explorer ribbon, then **select Preview Pane**. -From there, simply click on a Markdown file or SVG icon in the File Explorer and observe the content on the preview pane! +From there, simply click on a Markdown file, PDF file or SVG icon in the File Explorer and observe the content on the preview pane! How to create mappings diff --git a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerPreviewPage.xaml b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerPreviewPage.xaml index 5693f88554..04e7411a5b 100644 --- a/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerPreviewPage.xaml +++ b/src/settings-ui/Microsoft.PowerToys.Settings.UI/Views/PowerPreviewPage.xaml @@ -67,6 +67,13 @@ IsEnabled="{Binding Mode=OneWay, Path=IsElevated}"/> + + + + + + diff --git a/tools/BugReportTool/BugReportTool/RegistryUtils.cpp b/tools/BugReportTool/BugReportTool/RegistryUtils.cpp index 6acad09576..b205bb0ab4 100644 --- a/tools/BugReportTool/BugReportTool/RegistryUtils.cpp +++ b/tools/BugReportTool/BugReportTool/RegistryUtils.cpp @@ -13,6 +13,8 @@ namespace { HKEY_CLASSES_ROOT, L"CLSID\\{36B27788-A8BB-4698-A756-DF9F11F64F84}" }, { HKEY_CLASSES_ROOT, L"CLSID\\{45769bcc-e8fd-42d0-947e-02beef77a1f5}" }, { HKEY_CLASSES_ROOT, L"AppID\\{CF142243-F059-45AF-8842-DBBE9783DB14}" }, + { HKEY_CLASSES_ROOT, L"CLSID\\{07665729-6243-4746-95b7-79579308d1b2}" }, + { HKEY_CLASSES_ROOT, L"CLSID\\{BCC13D15-9720-4CC4-8371-EA74A274741E}" }, { HKEY_CLASSES_ROOT, L"CLSID\\{51B4D7E5-7568-4234-B4BB-47FB3C016A69}\\InprocServer32" }, { HKEY_CLASSES_ROOT, L"CLSID\\{0440049F-D1DC-4E46-B27B-98393D79486B}" }, { HKEY_CLASSES_ROOT, L"AllFileSystemObjects\\ShellEx\\ContextMenuHandlers\\PowerRenameExt" }, @@ -20,7 +22,8 @@ namespace { HKEY_CLASSES_ROOT, L".svg\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" }, { HKEY_CLASSES_ROOT, L".svg\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" }, { HKEY_CLASSES_ROOT, L".md\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" }, - { HKEY_CLASSES_ROOT, L".pdf\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" } + { HKEY_CLASSES_ROOT, L".pdf\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" }, + { HKEY_CLASSES_ROOT, L".pdf\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" } }; vector> registryValues = {