diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602195317_4cb29d7905174edfb63a6dc4c6665fbe.trn b/.appdata/.dotnet/TelemetryStorageService/20260602195317_4cb29d7905174edfb63a6dc4c6665fbe.trn deleted file mode 100644 index 9483985..0000000 --- a/.appdata/.dotnet/TelemetryStorageService/20260602195317_4cb29d7905174edfb63a6dc4c6665fbe.trn +++ /dev/null @@ -1,5 +0,0 @@ -https://dc.services.visualstudio.com/v2/track -Content-Type:application/x-json-stream -Content-Encoding:gzip - -H4sIAAAAAAAACpRUTW/bOhD8KwLPpsIvUaJugdPiGXltjNZoi94o7qoholAGSaUNAv/3grKLNKeHdyGIFWc5OzPUCwn2EUlPro/Hd08YciIbkv1aEkxoyjRl4sBN38iet7XkmstWfCcb4m/xmfSkVc5xZ5BK1EgVsIYOcnQUAA1nHJhoVOlpfyTSvxDra8An77Ce0xeMyc+B9OSrDzD/LHdbX7tpXqCO84S7kLINrpD5uNve0n+v94e7/flUwlTAtYdCFUTHJHR0YK2iCnVLDQdFXWMG7Zi0QpgzzIeMMdipTvDwej/MOWB2vaiFrBkVhpw2BGy2hfJgEx6ej4XFKtFNqW/W8rrtX8gTRtKLzR8xz+2u3OSvHtOw+Amuzmu26SGt62hdnuMz2ZBjnI8Ys8dVn+uU8HGYng82Pbw/nynb9O4XuiUjbOclZNITrjjZkFWgabLZz6G6cNxOHkNeP+boQ/Luv3oVf+4+V/vJ5nGOj2/8+HyWefc/VP5g3b0PWO1uSE8YRwGyQzoKrqnqwFLbSEO1lnpE7kwryiDbOWQflnlJ1S5k/BHXkUhP3tsp4ZnfdXT3PqPLSyxzftOF9z7OsLhcvXrJWc1qyVgBLfm45OoTgo/oMpYhDnG59PvyFiK0WEHbJUYMudrbfF/9Y9M96YmxnePWWGOtdm7EhuHIgFnNWkANGkEJaEEZBVoZ5rSyA1dgGz6MpUI2BEt0qjWtbByN0cxRK1tGVdc6OnSOU9N2nInOgjAlYK86VndTwVnXMYUgqcERqDLcUqOkpCAb2wo9tq0Y/5LkkgfOisCAT+d3tzLQAB2C5lQo3lBlDKedaVo6tN1gBt1h4wrnW4wBp7+E+uBdnNM85uqSkOqNdJ+WUP4d1ZqWnz7QX6tHN7N7wFgVj60P5alcbD2dTqffAAAA//8DAH1Y7jeCBAAA \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602195317_94a48c2220314ff2ae6ddfd246714781.trn b/.appdata/.dotnet/TelemetryStorageService/20260602195317_94a48c2220314ff2ae6ddfd246714781.trn deleted file mode 100644 index c76d301..0000000 --- a/.appdata/.dotnet/TelemetryStorageService/20260602195317_94a48c2220314ff2ae6ddfd246714781.trn +++ /dev/null @@ -1,5 +0,0 @@ -https://dc.services.visualstudio.com/v2/track -Content-Type:application/x-json-stream -Content-Encoding:gzip - -H4sIAAAAAAAACpSTTW/cOAyG/4qhs+Xoy7LlWzDZRQdpN4M2aIveaJHuCHXkgS2nLYL57wt5pki7t70JlEg+fF/qhUV4Itax29Ppr2eKaWElS2ELKaEsF5YL9ShdV+tONpVW2igjv7CShXv6yTrWGO+ld8Q1WeIGRc17PXiOSE4KiULVJteErwvrXhiECuk5eKqm5SPNS5gi69inEHH6nntDqPw4rVjN00j7uCSIPsP8s9/d87e3h8eHw+XVQktOrgJmVFSt0NjyXjSGG7INdxIN97XrrRcalHKXtBATzRHGasFvr/1xSpGS71SldCW4cuxcMoQEGbmHhR5/njLFJtFdjpdbeDt2L+yZZtap8peYl3I3fgw3fnp6gog3Q4hhObKSnebpRHMKtMmxTTiOkMIUi2uT3RgoJlayhw/FYYQ0TPPTHxp9uIy+/x+TvwN/DJGK/R3rmJCkULfEByUtNy0Ch1o7bq22A0nvGiVZyXZTTCGu07oU+5jo67xRso79DeNCF77b2R9DIp/WOaN/ttlr+hHSbsIcEKxkh3nC1afiVW4pKlFpkS8f1nRaU/GeMMzkE+WZHuf1Wv4/KcqqLWm3zjPFVBwgHYs3sBxZxxy0XoIDB2C9H6gWNAgUYEWDZNESGoUNGmfQGie8NdBLg1DLfsiRzJ3dLbaFGtABoTC8h6blpjaSO6uBSwutVVobkBnkVdbiYcx54FthCDV3NCA3TgJ3RmuOuoZG2aFp1PCbJFfHpch6Iz1fvsZGYBFbQiu5MrLmxjnJW1c3vG/a3vW2pdpn5nuaI42/CfUu+HlapiEV14Up/pDu/Rrz9y625fkeIv+xWXY3+W80F9lyCDFv89Xl8/l8/hcAAP//AwCN39GdJQQAAA== \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602195715_760c510e6e5c4814bb3aa8ab61f7281e.trn b/.appdata/.dotnet/TelemetryStorageService/20260602195715_760c510e6e5c4814bb3aa8ab61f7281e.trn deleted file mode 100644 index ee18a7a..0000000 --- a/.appdata/.dotnet/TelemetryStorageService/20260602195715_760c510e6e5c4814bb3aa8ab61f7281e.trn +++ /dev/null @@ -1,5 +0,0 @@ -https://dc.services.visualstudio.com/v2/track -Content-Type:application/x-json-stream -Content-Encoding:gzip - -H4sIAAAAAAAACpSUTW/cNhCG/4rAsyjzS6Som2G3qOGmWcRGW/Q25IxiIVppQVGbBob/e0HtFol7640YcIYvn3lnXtkMR2I9uz2dfjrTnFdWszzuISWU5cJyoZ6l71vXy7ZxznSik3+xmo2P9I31zJkYZfTENVniBkXLgx4iRyQvhUShWlNqwueV9a8MxgbpPEZqlvV3Suu4zKxnf4wzLl/L2zA2cVo2bNIy0cO8ZphjEfPbw90j//X28PzxcLm10lqSmxFZz8AHMN1gOanguAEgHlwAThGJWgKpTbykjXOmNMPUrPjl+/u45Jly7FWjdCO48uytZggZiuQAKz1/OxUVO6L7Eq/38H7sX9mZEutV/S/MS7mbOI036xYmOtN0grRSuonL8Qgzspqd0nKilEfasZwphWUdcyEao4OukxI7cKZ12OlWaYdaEHbCtejRgzV2ULFtBwydd2YwqKRBS8YEx2q2g5smyOMyV1ftd9NIc2Y1+/hUHSbIw5KO79A/XYg+/A+gRTbrmRatts6R0VqDt0EJQmejtSpEEG4IimQk0XrjvHRCaq+E1611nUMQvlT6APFlnKl6uGc9E5IU6o74oKTlpkPg0GrPrdV2IBm9U5LV7G6Z8zhvy7ZWD3Omz2n/L+vZzzCtdPnpbYovY6aYt1Qg/GmLGQ9pwS3m6rsBpGhEo4UoSVs+bbn6RDgmipkKjue0Xev9J0VZtSfdbSnRnKsD5JfqF1hfWM88dFGCBw9gYxyoFTQIFGCFQ7JoCY1Ch8YbtMaLaA0EaRBaGYYSYTWj4rdqtziBH2hAy8Fp4qZTinchOC6UNcHpIAWGdxyrj9PeydgJQ6i5pwG58RK4N1pz1C04ZQfn1PADkqtZpCiAkc6XYd0VWMSO0EqujGy58V7yzreOB9cFH2xHbSyaHynNNP0A6sMY07IuQ66uXqveofu0zWXhVLvvvo4z/3vv0f0Sv1CqSo9hnMt8Xdv6VrMjwbolOu77qn9lhzJc1fO+trRopNK6Zk8ZUt5O17DVjZGqfXt7e/sHAAD//wMAlFq6YfQEAAA= \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602195715_8a3ed2878b814ea6ae18986847e66634.trn b/.appdata/.dotnet/TelemetryStorageService/20260602195715_8a3ed2878b814ea6ae18986847e66634.trn deleted file mode 100644 index b768db2..0000000 --- a/.appdata/.dotnet/TelemetryStorageService/20260602195715_8a3ed2878b814ea6ae18986847e66634.trn +++ /dev/null @@ -1,5 +0,0 @@ -https://dc.services.visualstudio.com/v2/track -Content-Type:application/x-json-stream -Content-Encoding:gzip - -H4sIAAAAAAAACpSUTW/cNhCG/4rAsyjzS6Som2G3qOumXsSLtOhtSI5sIVpqQVGbBsb+94DaDRL31psw0DszfOadeSMRDkh6cns8/nLCmBdSkzxuIcGEpkxTJvbc9q3pedsYqXkn+T+kJuMjfiU9Mcp77i1SiRqpCqylTg6ehoCWMx6YaFXJCS8L6d8IjE3A0+ixmZdPmJZxjqQnf40xzF9KbRgbP81raNI84UNcMkRfmvnz4e6R/nG72z/tLn8tuBRxMwbSE7AOVDdoisIZqgCQOuOAog+ILQKXyl9kY8yYIkzNEj7/qB/mHDH7XjRCNowKS841CZChtOxgwf3XY+liQ3Rf4vUW3j77N3LCRHpRf4d5SXfjp/Emz8cJTzgdIS2Ybvx8OEAMpCbHNB8x5RE3LNtLpwnyOMfqWuxuGjFmUpOn52o3QR7mdHjH6vmC4OF/EDhhcqQnkrVSG4NKSglWO8EwGO21Fs4DM4MTyD2y1ipjuWFcWsGsbLXpTABmS6aXaXYw/b5s/KxgrgvMCC1QoRVKa+sZyg6H1iALoLXTnbdBdkaoLnQSLAC3Do232heDfAD/OkasHu5JTxhHEWSHdBBcU9UFoNBKS7WWekDurRGc1ORujnmM67wu1UPM+JI2fqQnv8K04IXcbfKvY0af11Sg/q1LsV2aw+pz9cMBnDWskYwV0ZqPa64+YhgT+owF7z6t13z/kQgtNtHdmhLGXO0gv1a/wfJaqEDnOdjyVO39gC3DgQUGmpmAOmgMSgQTlFVBK8u8VuC4CtByN5QIqQkWw1WbxwdoUXZgqJC+parVnlqwnHZdkIDGO8b9O47V07Q5w3dMYZDU4hCoshyoVVLSIFswQg/GiOEnJFfzcVYABzxdtnXrQIfQYdCcCsVbqmwpbltDnemcdbrD1peeHzFFnH4C9WH0aV7mIVdX71bv0H1cY7k41ebjL2Ok/24zup/9Z0xVmTGMsSzYdaznmhwQljXhYTtY/RvZle2q9tvdkqzhQsqaPGdIeT1ew1o2iov2fD6fvwEAAP//AwBUXko/9QQAAA== \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602195715_bb822ea47457418ebf0e3449dcadf0ca.trn b/.appdata/.dotnet/TelemetryStorageService/20260602195715_bb822ea47457418ebf0e3449dcadf0ca.trn deleted file mode 100644 index 80de38c..0000000 --- a/.appdata/.dotnet/TelemetryStorageService/20260602195715_bb822ea47457418ebf0e3449dcadf0ca.trn +++ /dev/null @@ -1,5 +0,0 @@ -https://dc.services.visualstudio.com/v2/track -Content-Type:application/x-json-stream -Content-Encoding:gzip - -H4sIAAAAAAAACpSUzW7jNhSFX0Xg2lRIiqJE7VKngxqZTIxJOi26uyKvHCIyaVBUpkGQdx9QdhBnBl10J1zx/n3nkC/Ewx5JRy4Ph9+f0KeJrEhyS0gwoShTlIl7rru66XhdtqzmrFL/kBVx1/hMOtJIY7jRSCtUSKVlNe2rwVBrUXPGLRO1zDVhN5HuhYArLT45g2WYvmGcXPCkI385b8P33BtcacYw2zKGETd+SuBNHubLZn1NP19u72+3x1MTTjm5dJZ0BHQPsh0URdE3VAIg7ZseKBqLWCPwSppjmvMJo4exnOzje38bksdkOlGKqmRUaPK6IhYS5JF7mPD++ZCnWBBd5fhqCS+f3Qt5wkg6sXqDeSx3YUZ3sZ/62Y32Ygy7nfO7dfCD280RUm68IocYDhiTwwXOb85DfP4cdrtcj3yCcUKyIvcY987DePxxhQPMY7oLc1zITPbxv85kMnMKZEUWkuO4tC1Oy6xHhz79knvW+Pau2I6QhhD3H0S6O7Lf/A/0N2AenMdic0U6wjgKW7VIB8EVla0FCnWlqVKVGpAb3QhOVmQdfHJ+DvNUbHzC3Ynah/kuo3lwCU2aY97pb5XNto3BziYV7wJzVrKyYiwnzekwp+IrWhfRJMxL3Mf5VO+nFKHEkvTJjfgLnvUcI/pUbCE9FH/A9EA6oqE1HDRoAGXMgDXDgVkGijUWlVVopbCNlVpaJTUzSkLPpYWa90OOkBXBbLJi8TUfBGhAQ3mLNZVVjxS0MLSqGylkpfUwDB/gFrfjIoppmURbUY2DpVJzoFpWFbVVDY1QQ9OI4YzTyRCcZernJvxzQnvy0pejtd92t/h0vMfLnMraFq3iVEheU6k1p62uG9o3ba971WJt8mbr4KfwBvIbxj5MLuVH5MZ5t4fx5yPvylxj9DieqXPjTAxTGFJxsmXxQa+vs8+vWLFY9Lvz9N/FGFfBPGIssrHA+TMxX19fX38AAAD//wMAr++TXgwFAAA= \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602195716_2e4dc19f1277411fa06beeccc1d82180.trn b/.appdata/.dotnet/TelemetryStorageService/20260602195716_2e4dc19f1277411fa06beeccc1d82180.trn deleted file mode 100644 index ebe6479..0000000 --- a/.appdata/.dotnet/TelemetryStorageService/20260602195716_2e4dc19f1277411fa06beeccc1d82180.trn +++ /dev/null @@ -1,5 +0,0 @@ -https://dc.services.visualstudio.com/v2/track -Content-Type:application/x-json-stream -Content-Encoding:gzip - -H4sIAAAAAAAACoxUTW/bOBD9KwLPokJS1AcF7MFwWqyRpjESd3exN4ocxkRk0aAop0GR/76gJNdO0cPehNF8vHnvDX+gXh4ANWh1PH46QR8GlKJgpxAjrMSkxITtqGiKqqFlxipOKaP/ohTZO3hDDaq4UlQJwDmUgLkmBW5zo7DWICihmrCCx57yeUDNDyRtpuFkFWRu+Av8YF2PGvS37bV7jbOlzVTnRp1518GmH4LsVQTzdbO+w19W293Dds4aYIjFmdWoQVK0ktemxMDaCnMpAbdVKzEoDVCApDlXc5ntA/hedtmgXy7ztQs9BNWwjOUZwUyg9xRpGWSE3MoBdm/HiGKi6DbG0yk8fTY/0Ak8alh6JnNud6M6e3MY2tF2+iZI/wzBeHmAV+df4CQ7lKKjd0fwwcLEzcNTcoFESUYyVjJCUIrupdrbHpLNbfLQTQurmnDQORZgNOaCSix4nmOdF7JipakqZlCK7sD30F11vbfKu8GZkCyUJx/mrF0fbD+6cUg2fYBnL8Nc91l2A6AUbce2s8P+EaR+27nHMf7rxy7ush69hz4kWxn2yZ9y2KMGCVkrKoUUUpZKGSgIGKKJLEmlodQlaM50pbnguuSCqJLLlnItC9qaGEEpehjDcQxn/r9fgdh5eziAviDYTRxvOxmM84eNhj5YY6M054zJUF03bZUsPdedhT58IBk1iFBgOq8BG0ZLzGstsSxygcsyLw1QJSpGZ8KMfR5/8kSM0Tw3RV2XrWgpAWaqmpPKtEQrkyuhixYqVpGqhlooQtqC07oVimigBddxO+/0qMKvVsgngR7HPl5nsolrv9oefy/5hZGtd8Ep10XBbAdPb0OAw+9UW7vD0Q02xP3NIu23Ae5dH/8u979wthSvXLjEIN5BMp2eriSYghdYVBIwNzVgCdzgGog2NSeEqAKl6NapF/BJNJi0/aTJ2VMPT8nKq70NoMLo4+R/pqVmOT+fT+bCR/b1027tPKyOx3SJ/nGKJM3Nzgb48K58G2L63g1xi+DHKx89QWfOuK7cpOE0v1Q2Bkuta9AlxYzTAnMhKK5FUeG2qlvRljUU6uLW5BG09aDC1G83T1uI/Z0tVz5YI1UY4u18cWpy02LPJeVXkFeq/ayeh18ptzhp6URJdOzT/G5OBvpfz+b7+/v7fwAAAP//AwB0fDGlJwYAAA== \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602195723_31c2df91fe744af1a679f29f45bab886.trn b/.appdata/.dotnet/TelemetryStorageService/20260602195723_31c2df91fe744af1a679f29f45bab886.trn deleted file mode 100644 index 3820deb..0000000 --- a/.appdata/.dotnet/TelemetryStorageService/20260602195723_31c2df91fe744af1a679f29f45bab886.trn +++ /dev/null @@ -1,5 +0,0 @@ -https://dc.services.visualstudio.com/v2/track -Content-Type:application/x-json-stream -Content-Encoding:gzip - -H4sIAAAAAAAACpRTTW/cNhD9K8KcRZmkKErUzVin6MJNvEgWadHbiBzFhGVqQVFOAmP/e0DtBk5664UgBnwz72P4CgGfCXq4PZ3evVBIC5SQ/FaSXGrGNePyKEzftL2sq7btlNT1v1CCv6fv0EOrrBXWEKtJE1OON2yoR8ucIyO4cFw2KvfELwv0r4C+cvTiLVXz8pni4ucAPfztg5u/5tnoKzvNq6viPNE+LAmDzWQ+7Hf37K/bw/HhcHm10JLBlXfQA5oBVTdqRnJomUIkNrQDMrKOqCEUtbIXmA+JYsCpWtzT23w3p0DJ9rKSdcWZNHAuwWHCTHnAhY7fT5nFZtFdrpdbebv2r/BCEXpZ/jTz0u7GTv7meRlWP7mby5lwecoqT3E+UUyeNk82mdOEyc+huE7aTZ5CghIePhWHCdM4x+ffjPp00b//H/KPefq7b2TXRG43ryFBD0I1UMJ7tI8+ULG/gx64IOnqjtgohWaqc8iwqQ3TutYjCWtaKaCE3RySD+u8LsU+JPoSNwHQwx84LXShfhvto09k0xqzqn903oVDnN1qU/Hmv+AVr2rOM2hNpzUVH8n5SDZR1neM67XffyBSyw20W2OkkIoDpsfiT1weoQeDnRVo0CBqa0dqOI3ccdS8daSdJqeka50yymlluNUKB6EcNmIYcwVKoBx3sW2YNkRcaMtka5EprQc2KNuxQQ1167BrrMzS3nwsHqYtGttxRa5mhkbHlBHIjKpr5uoGW6nHtpXjL5Zc0xc8G+zo5fJXLgyc68hpwaQSDVPGCNaZpmVD2w1m0B01NnO+pxho+sWo997GeZnHVFyXp/jNuo9ryP+92Bbpqw/s25bR3WyfKBY5Y/Qhr/c11vP5fP4BAAD//wMA//ibKjYEAAA= \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602195723_519a40f71d70420d89088e2db32dd9df.trn b/.appdata/.dotnet/TelemetryStorageService/20260602195723_519a40f71d70420d89088e2db32dd9df.trn deleted file mode 100644 index 57eb276..0000000 --- a/.appdata/.dotnet/TelemetryStorageService/20260602195723_519a40f71d70420d89088e2db32dd9df.trn +++ /dev/null @@ -1,5 +0,0 @@ -https://dc.services.visualstudio.com/v2/track -Content-Type:application/x-json-stream -Content-Encoding:gzip - -H4sIAAAAAAAACpRTwW7bOBD9FYFnUSEpihJ1C5xd1Ei7MdqgLXobcUY1UYUyKCptEfjfF5RdpN3b3ohHvpk37w1fWIAnYj27PZ3+eqaQFlay5DdICWW4MFyoR2n7pu1VXbWd6FohvrCS+Xv6yXrWaueks8RrMsQ1ioYP9eg4IlkpJArV6FwTvi6sf2HgK6Rn76ial48UFz8H1rNPPuD8PfcGX7lpXrGK80T7sCQILov5Z7+7529vD48Ph8urhZZMrjyynoEdQHej4aSGlmsA4kM7ACeHRA2BrLW70HxIFANM1YLfXvvjnAIl16tK1ZXgyrJzyRASZMkDLPT485RVbBbdZbzc4O3Yv7BniqxX5S8zL+Vu3ORv3Pz0BAFvRh/8cmQlO8X5RDF52uzYJpwmSH4OxbXJbvIUEivZw4fiMEEa5/j0h0cfLqPv/8fk78AdfaBif8d6JiQprDvio5KG6w6BQ1NbbkxtRpLOtkqyku3mkHxY53Up9iHR17ipZD37G6aFLvpuozv6RC6tMUv/bHLW9MOn3YwZEKxkhzjj6lLxarcUlahqkS8f1nRaU/Ge0EdyifJMj3G9lv8PRRm1kXZrjBRScYB0LN7AcmQ9s9A5CRYsgHFupEbQKFCAES2SQUOoFbaorUajrXBGwyA1QiOHMSNZd0632BYKjdC21cglNQPXUozcggROgMKOrXCmzYxXW4uHaYvDdUIT1tzSiFxbCdzquuZYN9AqM7atGn+z5Jq4FNlvpOfL19gUGMSO0EiutGy4tlbyzjYtH9pusIPpqHFZwT3FQNNvRr3zLs7LPKbiujDFH9a9X0P+3sW2PN994D+2yO5m941ikSMHH/I2X1M+n8/nfwEAAP//AwAfRvRKJQQAAA== \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602195723_a39970eb66004ffe861bd55d01332de4.trn b/.appdata/.dotnet/TelemetryStorageService/20260602195723_a39970eb66004ffe861bd55d01332de4.trn deleted file mode 100644 index 556b496..0000000 --- a/.appdata/.dotnet/TelemetryStorageService/20260602195723_a39970eb66004ffe861bd55d01332de4.trn +++ /dev/null @@ -1,5 +0,0 @@ -https://dc.services.visualstudio.com/v2/track -Content-Type:application/x-json-stream -Content-Encoding:gzip - -H4sIAAAAAAAACpSUwW7cNhCGX0XgeSmTFEWJuhl2gi7c1IvESIveRpxRTFimFiTlxDD23Qtqt0h8KnohiBFn+M/3D/XGAjwTG9j18fjhhUJObMey30JKKMOF4UI9SDu03aCauuta06j2b7Zj/o5e2cA67Zx0lnhDhrhG0fKxmRxHJCuFRKFaXWrCt8SGNwa+RnrxjuolfaWY/BLYwP70AZfv5W7wtZuXFeu4zLQPKUNwRcwf+5s7/vv14eH+cD6VKJXk2iMbGNgRdD8ZTmrsuAYgPnYjcHJI1BLIRrtzmg+ZYoC5Tvj0835ccqDsBlWrphZcWXbaMYQMRfIIiR5ej0XFhui2xHdbeNsOb+yFIhvU7l+Y53JXbvZXz2lc/YxX5zVDekrbOoHLS3xlO3aMy5Fi9rTxuU6Jnsf59QHS08fzmbJNH36QWzPhzbKGzAYmtWQ7tgGaZ8h+CdVF483sKeTtY44+JO/+q1bx5/5LdZghT0t8fufHlzPm/f+g/Ancow9U7W/ZwIQkhU1PfFLScN0jcGgby41pzETS2U6VRm6WkH1YlzVV+5DpW9xaYgP7CHOis77r6B59JpfXWPr8yxTdh7jg6nL100spalE3QpSkNR/XXH0m9JFcptLEQ1wv9b6+T1FGbUk3a4wUcnWA/Fj9BumRDcxC7yRYsADGuYlaQZNAAUZ0SAYNoVbYobYajbbCGQ2j1AitHKcSYTtGZXSqbVrbroHWTJr3I3VcS7QcJBreCbI4WWnHtn/HsbqfN/6uF5qw4ZYm5NpK4FY3DcemhU6ZqevU9AuSyzxIUQAjvZzf3abAIPaERnKlZcu1tZL3tu342PWjHU1PrSua7ygGmn8B9cm7uKRlytVlQqp36D6vofw7qm1avvvAf2we3S7uiWJVPAYfylO52Ho6nU7/AAAA//8DAIN+pxyCBAAA \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201259_c173522925004a88898062425f2fc884.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201259_c173522925004a88898062425f2fc884.trn new file mode 100644 index 0000000..8d9573d --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201259_c173522925004a88898062425f2fc884.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACpSTwY7cKBCGX8XibDyAMTa+jXp2ldYkO61klKz2hqkijeKBFsaTRKN+9xXujpLJLTdUUFV/fX/xQoJ5QjKS29Ppr2cMeSE1yX4LCSYUZYoy8SjYyMXY6UawXnWD+I/UxN/jdzKSXlrLrUbaokIqgXV0ap2lAKg548BEJ0tN83kh4wsxvgF89habuHzEtPgYyEg++QDxa+ltfGPnuEKT4oz7sGQTbBHzz353T9/eHh4fDpdXCy4lufFARtK1YHopGDWDslQ6ZHSYnKNKaQlKdpINcEnzIWMKZm4W+PKzP8QcMNtRNKJtGBWanGsCJpsieTILPn4/FRUborsSr7fwdhxfyDMmMor6B8xLuRs7+xsbn55MgBvng1+OpCanFE+YsscNxzbhPJvsY6iuTXazx5BJTR4+VIfZZBfT0ytGHy6j7/9g8nfGHn3Aan9HRsI4CmgHpE5wReUAhpqu1VSpVjnkVveCk5rsYsg+rHFdqn3I+DltKslI/jbzghd9t8kefUab11Sk/6uK1/jN512EEmCkJocUYbW5+ombs4Y1LSuXD2s+rbl6j+AT2oxlpse0Xsv/liKU2JJ2a0oYcnUw+Vi9McuRjESbwXKjjTZGWeuwY+gYMKNYD6hAIUgBPcgNi2ZWSTNxCabjkyuRoru4W20LNYAQnUNNBQhOJWigRrUTVQxagMG5blCvsFYPc8kzdmASoaUaHVCpuaFati2FtjO9UK7vhfsFydVxzgpvwOfL19gUKIABQXEqJO+o1JrTQXc9nfph0pMasLNF8z2mgPMvoN55m+ISXa6uC1O9Qvd+DeV7V9vyfPWBftssu4v2C6aqWG58KNt8dfl8Pp//BwAA//8DAJt2xo0lBAAA \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201259_f4fbe050463f4287be79b3201f9c61a1.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201259_f4fbe050463f4287be79b3201f9c61a1.trn new file mode 100644 index 0000000..e60c1b9 --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201259_f4fbe050463f4287be79b3201f9c61a1.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACpSTQW/cNhCF/4owZ1EmKYoSdTPWKbpwEy+SRVr0RnFGMWGZWlCUk8DY/x5Qu0Hi3noRhAEf571vhq8Q7DNBD7en07sXCmmBEpLfSpJLzbhmXB4l74XsG1NJrnSnzb9Qgr+n79BDq5wTzhCrSRNTyBs21KNjiGQEF8hlo/Kd9ssC/StYXyG9eEfVvHymuPg5QA9/+4Dz19zb+spN84pVnCfahyXZ4LKZD/vdPfvr9nB8OFxOLbRkceURemhqtK2SnNlOO6ZG4qwbxpFpbRRq1Sje4UXmQ6IY7FQt+PSrP84pUHK9rGRdcSYNnEtAm2y2PNiFjt9P2cWG6C7Xy628/fav8EIReln+hHm57sZN/uZ5GVY/4c3lm+zylFOe4nyimDxtTLaY02STn0Nx7bSbPIUEJTx8Kg6TTeMcn9+A+nTJv/8f8Y+5+7tv5NZEuJvXkKAHoTSU8N66Rx+o2N9BD1yQxLojNkqhmerQMtvUhmld65GEM60UUMJuDsmHdV6XYh8SfYlbAOjhDzstdLF+G92jT+TSGnOqf3TehUOccXWp+MVf8IpXNedZtKbTmoqPhD6SS5TzHeN6ve8/EqnlJtqtMVJIxcGmx+JPuzxCD8Z2TlhjjbXauZEaTiNHbjVvkTRqQiWxRbUhMtxpZQeh0DZiGHMFSqA87mLbMMt1I0Sj2EiNY6rtJDMGFaPREklXt13TvuFYPEybznVcEdbM0IhMGWGZUXXNsG5sK/XYtnL8Dcl1+oJnwEgvl7eyOdCIHaEWTCrRMGWMYJ1pWja03WAG3VHjsud7ioGm30C99y7Oyzym4ro8xRt0H9eQ33uxLdJXH9i3bUZ3s3uiWOQZWx/yel/Hej6fzz8AAAD//wMAR26UADYEAAA= \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201359_9784ddca25f14682abbeb92ee816f438.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201359_9784ddca25f14682abbeb92ee816f438.trn new file mode 100644 index 0000000..18b4c0b --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201359_9784ddca25f14682abbeb92ee816f438.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACpSUW2/cNhCF/4rAZ1Hm/aI3w25Rw02ziI226NuIM4qFaKWFRG0aGP7vBbVbJO5b34SBzvDwmzN8ZRMcibXs9nT66UxTXlnN8rCXlFCOC8eFelailbq1sfFGhxjsX6xmwyN9Yy3zJiWZInFNjrhBYXmn+8QRKUohUShrSk/4vLL2lcHQIJ2HRM28/k7LOswTa9kfw4Tz13I2DE0a5w2bZR7pYVozTKmY+e3h7pH/ent4/ni4/LXSWsTNgMWqtjH2aHgM0HPjlePBoeGKgk0gAgQDF9kwZVomGJsVv3w/H+c8UU6tapRuBFeRvdUMIUOx3MFKz99OxcWO6L7U6728f7av7EwLa1X9L8xLu5s0Djfr1o10pvEEy0rLTZqPR5iQ1ey0zCda8kA7ljMt3bwOuRBNyUMIUmIAb6zHoK3SHrUgDMJbjBjBGderZG2PXYje9AaVNOjImM6zmu3gxhHyME/V1fvdONCUWc0+PlWHEXI/L8d36J8uRB/+B9Bim7VMC6ud92S01hBdpwShd8k51SUQvu8UyUTCRuOj9ELqqETU1vngEURMrGYfIL0ME1UP96xlQpJCHYj3SjpuAgIHqyN3TrueZIpeSVazu3nKw7TN21o9TJk+L/t9Wct+hnGly01vl/QyZEp5WwqEP10J42GZcUu5+h4AKRrRaCGKaMunLVefCIeFUqaC43nZrv3+I1FO7aK7bVloytUB8kv1C6wvrGURQpIQIQK4lHqygnqBApzwSA4doVHo0USDzkSRnIFOGgQru75UWM2o5K3aI05Sd0II5N75npvO9DwEQh5sTFo4DWD9O47Vx7HoIAVhCDWP1CM3UQKPRmuO2oJXrvde9T8guYZFigIY6XxZ1t2BQwyETnJlpOUmRslDtJ53PnSxc4FsKp4faZlo/AHUhyEt8zr3ubpmrXqH7tM2lQen2nP3dZj43/uM7uf0hZaqzBiGqezXdaxvNTsSrNtCx/29al/ZoSxX9bw/W8o3ToZQs6cMS95O17IJjXXGvr29vf0DAAD//wMARwDop/QEAAA= \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201359_d06a62bdaf5743e597f1245d77848389.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201359_d06a62bdaf5743e597f1245d77848389.trn new file mode 100644 index 0000000..01eda5b --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201359_d06a62bdaf5743e597f1245d77848389.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACpSUTW/cNhCG/4rAsyjz+0M3w25R1029iBdp0duIHNlCtNKCojYNjP3vAbUbJO6tF0EYcGZePvMO38gEByQtuT0efznhlBdSkzxsIcGEocxQJvaCtVy22jeWScO4/ofUZHjEr6QlVoXAg0cq0SBVkWnayT7QGNFzxiMTWpWa8LKQ9o3A0EQ8DQGbefmEaRnmibTkr2GK85fSG4YmjPMamzSP+DAtGaZQxPz5cPdI/7jd7Z92l1MLLiW5GWKRKrX3fVTUO+ipssJQZ6KiAp0OwBw4BZe0YcqYJhibJX7+0T/OecIcWtEI2TAqPDnXJEKGIrmDBfdfj0XFhui+xOstvP22b+SEibSi/g7zUu4mjMNNno8jnnA8Qlow3YT5cIApkpoc03zElAfcsGw3HUfIwzxV12Z344BTJjV5eq52I+R+Tod3rJ4vCB7+B4ETpo60RDItjbWopJTgTScYRmuCMaILwGzfCeQBmfbKem4Zl14wL7WxzkZgPpCavIxzB+Pvy8bPC9a5yKwwAhV6oYzxgaF02GuLLIIxnXHBR+msUC46CR6A+w5t8CYUg3yA8DpMWD3ck5YwjiJKh7QX3FDlIlDQ0lNjpOmRB28FJzW5m6c8TOu8LtXDlPElbfxIS36FccELudsUXoeMIa+pQP3blGa7NMc15OqHAzhrWCMZK0lrPq65+ohxSBgyFrz7tF7r/SdFGLEl3a0p4ZSrHeTX6jdYXgsVcIGDL1c1IfSoGfYsMjDMRjTRYFQi2qi8ikZ5FoyCjqsImnd9iZCaYDFctXncg+5602uqZPkYgdRxzqhF7kSURnbaveNYPY0lD4JjCqOkHvtIledAvZKSRqnBCtNbK/qfkFzNx1kBHPF02dZNgYnRYTScCsU1Vd5z6ry2tLOu851xqEPR/IhpwvEnUB+GkOZl7nN19W71Dt3HdSovTrX5+Msw0X+3Gd3P4TOmqswYhqks2HWs55ocEJY14WF7sNo3sivbVe23d0vYxnDnavKcIeX1eA0r12ij9Pl8Pn8DAAD//wMAZQmTEfUEAAA= \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201359_e82aecc80fa2472aadbf4cfcdd2bd616.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201359_e82aecc80fa2472aadbf4cfcdd2bd616.trn new file mode 100644 index 0000000..26b0a0b --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201359_e82aecc80fa2472aadbf4cfcdd2bd616.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACpSUTW/jNhCG/4rAs6hQFEWJuqVOFzWy2Rgbd1v0NiJHDhGZNCgq2yDwf19QdhBnFz30Joz4zsczL/lKHOyRdOT6cPj9GV2cSE6iXUKccUmZpIxvOevKqqtV0TR1xcr2H5ITe4svpCON0LrUCmmFEqkwrKZ9NWhqDKqSlYbxWqScsJtI90rAFgafrcbCT98wTNY70pG/rDP+e6oNttCjn00R/IhrN0VwOjXzZb26pZ+vN9v7zenUhFMSF9akVqtaqcEIqloYqGi4pK00gnJsaw2shVbASWZdxOBgLCbz9F7f+Ogw6o4XvCoY5Yocc2IgQmq5hwm3L4fUxYLoJsXzJbx8dq/kGQPpeP4G85TuSo/2aj/1sx3N1eh3O+t2K+8Gu5sDxFQ4J4fgDxiixQXOb9ZBePnsd7uUj3yCcUKSky2GvXUwnn7c4ADzGB/8HBYyk3n6rzOkIzBHT3KykBzHpWx2HmY1WnTxF+1F4fuHbDNCHHzYf1jSw4n9+n+gvwP9aB1m6xvSEVYiN1WLdOClpKI1QKGuFJWykgOWWjW8JDlZeRetm/08ZWsXcXem9qG/66AfbUQd55Bm+lsms22CN7OO2fuCS1awomIsieZ4mGP2FY0NqCOmIbZhPuf7ScIlX0Sf7Ii/4FnNIaCL2QbiY/YHTI+kIwpaXYICBSC1HrBmODDDQLLGoDQSjeCmMUIJI4ViWgroS2GgLvshRUhOMJksW3zNjBiMrBQFUTMq+NDTViOjptZVrRhP4Q9ws/sx6UC3TKCpqMLBUKFKoEpUFTVVDQ2XQ9Pw4YLT2RAlS9QvTfjnhObspS8na7/NbvD5dI+XPqUxLRpZUi7KmgqlStqquqF90/aqly3WOk228m7ybyC/Yej9ZGN6RO6ss3sYfz7yvplbDA7Hi+3cWR385IeYnW2ZfdjX19mlVyxbLPrdOvrvYowbr58wZMlYYN3FMo/H4/EHAAAA//8DAHDfcRcMBQAA \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201400_598abb1d69b44fe189e68e8379183b57.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201400_598abb1d69b44fe189e68e8379183b57.trn new file mode 100644 index 0000000..ce6737c --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201400_598abb1d69b44fe189e68e8379183b57.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACpRTwW7UMBD9lcjnOLUdx4lzq7YgVgW6ohUgbrOeCWuROivHKaBq/x05uwjKjZv17Dfz5r3xMwvwSKxn18fjqycKaWYlS36FlFCGC8OFelCil7oXorJS61qpL6xk/pZ+sp612jnpLPGaDHGNouH7enAckawUEoVqdK4JX2fWPzPwFdKTd1RN80eKs58C69knH3D6nnuDr9w4LVjFaaRtmBMEl8W8325u+dvr3cPd7vxqpjmTK49Zat1YO6DmtoOB61YZ3hnUXFHXOBAddBrONB8SxQBjNeO3P/1xSoGS61Wl6kpwZdmpZAgJsuQ9zPTw85hVrBbdZLxc4fXYP7MniqxX5W8zz+Wu3Oiv3PT4CAGvBh/8fGAlO8bpSDF5Wu1YJxxHSH4KxaXJZvQUEivZ3X2xGyENU3x84dH9efTtf0z+DtzBByq2N6xnQpLCuiM+KGm47hA4NLXlxtRmIOlsqyQr2WYKyYdlWuZiGxJ9jatK1rPXMM501ncd3cEncmmJWfpnk7OmHz5tJsyAYCXbxQkXl4o/dktRiaoW+fJuScclFR8IfSSXKM/0EJdL+X8oyqiVtFlipJCKHaRD8QbmA+uZhc5JsGABjHMDNYIGgQKMaJEMGkKtsEVtNRpthTMa9lIjNHI/ZCTrzukW60KBA4GmG7hqasW1dIJ3lgyXRlmwlgwYfGFrcTeeeZ3QhDW3NCDXVgK3uq451g20ygxtq4a/LLkkLkX2G+np/DVWBQaxIzSSKy0brq2VvLNNy/dtt7d701HjsuZbioHGv4x6512c5mlIxWVhihfWfVhC/t7FujzffeA/1shuJveNYpEjBx/yNl9SPp1Op18AAAD//wMATZ4i4iUEAAA= \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201400_83f9c14c3b8e435c97c865cc3c58a9d4.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201400_83f9c14c3b8e435c97c865cc3c58a9d4.trn new file mode 100644 index 0000000..0902921 --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201400_83f9c14c3b8e435c97c865cc3c58a9d4.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACpRUwW7bOhD8FYFnU6EoihJ1C5wWz8hrY7RGW/S24q4aIgplkFTaIPC/F5RdpDk9vAtBrDjL2ZmhXpiHR2I9uz4e3z2RT5FtWHJrSQqpudBcyIMUfaV6IUojtGpq8Z1tmLulZ9azVllbWUO8Jk1coWj4UI+WI5KpRIVCNir3hB+R9S8MXIn05CyVc/xCIbrZs559dR7nn/lucKWd5gXLME+08zGBt5nMx932lv97vT/c7c+nIsUMLh1mqnVjzIiKmw5GrlqpeadRcUldY0F00Ck4w5xPFDxMZcSH1/txTp6S7WUp61JwadhpwxASZMoDRDo8HzOLVaKbXN+s5XXbv7AnCqyXmz9inttd2cldPcZhcRNendcE8SGu6wg2zeGZbdgxzEcKydGqz3WM9DhMzweID+/PZ/I2vvtFdkmE23nxifWsqg3bsFWgaYLkZl9cOG4nRz6tH1NwPjr7X72yP3efi/0EaZzD4xs/Pp9l3v0PlT+AvXeeit0N65moSGLdER9lpbnqEDg0teFa13qkyppWVmzDtrNPzi/zEoudT/QjrCOxnr2HKdKZ33Ww9y6RTUvIc37Tmfc+zLjYVLx6WYlSlLUQGbSk45KKT4QukE2UhziE5dLvy1uI1HIFbZcQyKdiD+m++AfiPeuZgc5WYMAAaGtHagSNAgVo0SJp1IRKYovKKNTKCKsVDJVCaKphzBW2YZSjU6xpbQ3JVirBqTaKq7EZuaG25dQhiU4rlKu5rzoWd1PGge2EIqy5oRG5MhVwo+qaY91AK/XYtnL8S5JLHiqRBUZ6Or+7lYFG7Ah1xaWqGq6MqXhnmpYPbTeYQXfU2MzgloKn6S+hPjgb5jiPqbgkpHgj3afF539Hsablp/P81+rRzWwfKBTZY3A+P5WLrafT6fQbAAD//wMAYoXgq4IEAAA= \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201400_9b638a79af0a457faa97fa35564ef4f0.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201400_9b638a79af0a457faa97fa35564ef4f0.trn new file mode 100644 index 0000000..20446c6 --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201400_9b638a79af0a457faa97fa35564ef4f0.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACoxUXU/lNhD9K5FfGwd/xYnzRoFVrygf2nvVVn2b2BNwCc6V48AixH9fORcK7KpSX6JobM85c+bMPJMA90g6crzfnz1gSDMpSfJrSDChKdOUiZ1gHVcdY5XhSnFp/iYl8ef4RDrSKGu5NUglaqTKsZr2crDUOTScccdErXJOuJlJ90zAVw4fvMVqmv/AOPspkI786YObHjM2+MqO0+KqOI24CXOCYDOZy83JOf39+Hp3dX24NeOcH1feZaqyNmZwipoWBqoaoWmrnaIC29oCa6FVcHjmQ8IYYKxmd/eO76YUMNlOVEJWjApDXkriIEGm3MOMu6d9ZrFKdJrj5Rpef7tn8oCRdKJ8E/OQ7siO/uh+7hc/uqP1S0qyj9MeY/K4qnG1Ld5JcFaxSmjBGCnJBdhbH7DYnBZXYy4RbMsUOkkNDo4qw4EaJSV1soZG6KFpxEBKco4x4Pgh64W3cZqnIRWvIhefcLbHJ2cB+hEzxhcYZyQl2czbBMHBOAU8+4Z2SYdcu7jk45MpJB+WaZmLTUh4E+H1/O39yRIjhlRcQ7otfoP5lnTEQGs5GDAA2toBa4YDcww0axxqp9Ep4RqnjHJaGWa1gp4rBzXvhxwhJfk1a7hdrMV5fmezmmQcVw7Fa59ORo8hfZKRdIRxFE62SAfBNVWtAwq1NFRrqQfk1jSCv8HsIN5gIh0Z2r7vmbW9UIZbEAakG5h0ejBCNA2oQdaNElrXrAHrmkZw5WSDFuQgWStISa7j5Babfmy1XBtwHad/0KYsFemIrblpWl5LUdeybViPqm6g1oyJRjPkRtZONtK5QbWmbWBwChrUqh14z4Rwb/TPwo0PeOrn/QhPH3DbSlfyFwvQ8gHeRT1c/xLhHh+neHd5sHF1ebYjJfm6hLwRik22yKMP9JvOE32xjMnvbiOCQ3cxOfzZR5jHpVgnVOZmS4V0kMJRJaSggKDpgLbFFq1xLJM/newdxiI7DHzIU/VvsqttcRztrU9o0xIzv79WHlfb4nqENEzx/tMm+VDYjwJUQnKWO+Pw4bCNVo7auRad5lQoXlNlDKetqRvaN21vet1ibbNiV0vaL6n4is5HtGmt+NWLK+bJLdq7n8V4c8GrRTnLXtsettgq7f9aYi8luUeYl4j367bunskmBIwr8ulyGMVNuPDj6Ge0U3Az6ThXuhLC6FeG/3lPMFYxWdcvLy8v3wEAAP//AwC4eGIfGwYAAA== \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201400_b432b3fc855a43a4aacf4d12fe955a64.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201400_b432b3fc855a43a4aacf4d12fe955a64.trn new file mode 100644 index 0000000..c03aa9d --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201400_b432b3fc855a43a4aacf4d12fe955a64.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACoxUTW/bOBD9KwLPokJRFCUK2IPhtFgjTWMk7u5ibxQ5jInIokFRToMi/31BSa6dooe9CaP5eO/NG/5AvTwAatDqePx0gj4MKEXBTiFKKMeEY0J3lDQ5awjJaJGXlNN/UYrsHbyhBlVMqVwJwAVwwEyTEreFUVhrEDnJNaEliz3l84CaH0jaTMPJKsjc8Bf4wboeNehv22v3GmdLm6nOjTrzroNNPwTZqwjm62Z9h7+struH7Zw1wBCLM6sj1KIUwmiGRS0NZhXluOaaYQp1qSSpZc3kXGb7AL6XXTbol8t87UIPQTU0o0VGMBXoPUVaBhkht3KA3dsxopgkuo3xdApPn80PdAKPGpqexZzb3ajO3hyGdrSdvgnSP0MwXh7g1fkXOMkOpejo3RF8sDBp8/CUXCDlJCMZ5ZQQlKJ7qfa2h2Rzmzx0kbBUNWGgCyzAaMxELrFgRYF1UcqKclNV1KAU3YHvobvqem+Vd4MzIVkkTz7MWbs+2H5045Bs+gDPXoa57rPsBkAp2o5tZ4f9I0j9tnOPY/zXj13ksh69hz4kWxn2yZ9y2KMGCVmrXAoppORKGSgJGKKJ5KTSwDUHzaiuNBNMcyaI4ky2OdOyzFsTIyhFD2M4juGs//crEDtvDwfQFwS7SeNtJ4Nx/rDR0AdrbFzNOWMyVNdNrJKl57qz0IcPIqMGkRyoLmrAhuYcs1pLLMtCYM4LbiBXoqL5LJixz+NPnYgxmhWmrGveijYnQE1VM1KZlmhlCiV02UJFK1LVUAtFSFuyvG6FIhrykunIzjs9qvCrFYppQY9jH68z2UTar7bH3zm7KLL1Ljjlurgw28HT2xDg8Lutrd3h6AYbIn+zrPbbAPeuj3+X+180W4pXLlxiEO8gmU5PStnSquW4NabFDEyBa2grXFaUGVrTquaR1a1TL+CTaDBp+2knZ089PCUrr/Y2gAqjj5P/mUjN6/x8PpmLHtnXT7u187A6HtMl+scpijQ3Oxvgw7vybYjpezdEFsGPVz56gs6ccV25ScNpfqlsDHKta9A8x5TlJWZC5LgWZYXbqm5Fy2so1cWtySNo60GFqd9unrYI+ztbrnywRqowxNv54tTkpsWeS8qvIK+29rN6Hn61ucVJS6ecRMc+ze/mZKD/9Wy+v7+//wcAAP//AwAXRjOgJwYAAA== \ No newline at end of file diff --git a/.appdata/.dotnet/TelemetryStorageService/20260602201400_b46d6a152f3c4ac0bed9eb991263027b.trn b/.appdata/.dotnet/TelemetryStorageService/20260602201400_b46d6a152f3c4ac0bed9eb991263027b.trn new file mode 100644 index 0000000..9614506 --- /dev/null +++ b/.appdata/.dotnet/TelemetryStorageService/20260602201400_b46d6a152f3c4ac0bed9eb991263027b.trn @@ -0,0 +1,5 @@ +https://dc.services.visualstudio.com/v2/track +Content-Type:application/x-json-stream +Content-Encoding:gzip + +H4sIAAAAAAAACpRTTW/cNhD9KwLPokxSFCXqZqxTdOEmXiSLtOhtxBnFhGVqQVFOAmP/e0DtBk5664UgBnwz72P4ygI8E+vZ7en07oVCWljJkt9KSijDheFCHZXope6FqKzotLLNv6xk/p6+s5612jnpLPGaDHGNouFDPTqOSFYKiUI1OveELwvrXxn4CunFO6rm5TPFxc+B9exvH3D+mmeDr9w0r1jFeaJ9WBIEl8l82O/u+V+3h+PD4fJqoSWDK4+Zat1YO6LmtoOR61YZ3hnUXFHXOBAddBouMB8SxQBTteDT23ycU6DkelWpuhJcWXYuGUKCTHmAhY7fT5nFZtFdrpdbebv2r+yFIutV+dPMS7sbN/mb52VY/YQ3lzPB8pRVnuJ8opg8bZ5sMqcJkp9DcZ20mzyFxEr28Kk4TJDGOT7/ZtSni/79/5B/zNPffSO3JsLdvIbEeiZ1zUr2HtyjD1Ts71jPhCSFdUd8VNJw3SFwaGrLjanNSNLZVklWst0ckg/rvC7FPiT6EjcBrGd/wLTQhfptdI8+kUtrzKr+MXkXDnHG1aXizX8pKlHVQmTQmk5rKj4S+kguUdZ3jOu1338gyqgNtFtjpJCKA6TH4k9YHlnPLHROggULYJwbqRE0ChRgRItk0BBqhS1qq9FoK5zRMEiN0MhhzBVWMspxF9uGDSMSNcJy0cqRa6kUt7JtuGxtO1jROqkzkTcfi4cp48B1QhPW3NKIXFsJ3Oq65lg30Coztq0af7Hkmr4U2WCkl8tf2RgYxI7QSK60bLi2VvLONi0f2m6wg+mocZnzPcVA0y9Gvfcuzss8puK6PMVv1n1cQ/7vxbZIX33g37aM7mb3RLHIGYMPeb2vsZ7P5/MPAAAA//8DANBOlYk2BAAA \ No newline at end of file diff --git a/PlotLine/Services/CoreServices.cs b/PlotLine/Services/CoreServices.cs index 2a9515d..c41dd53 100644 --- a/PlotLine/Services/CoreServices.cs +++ b/PlotLine/Services/CoreServices.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Net; using System.Text; using Microsoft.AspNetCore.Mvc.Rendering; @@ -881,7 +882,8 @@ public sealed class TimelineService( IPlotRepository plots, ILookupRepository lookups, IWarningRepository warnings, - ISceneDependencyRepository sceneDependencies) : ITimelineService + ISceneDependencyRepository sceneDependencies, + ILogger logger) : ITimelineService { private static readonly string[] DefaultGraphMetrics = ["Overall Intensity", "Tension", "Emotional Weight", "Action"]; @@ -890,29 +892,29 @@ public sealed class TimelineService( var projectId = filter.ProjectID; var bookId = filter.BookID; var selectedSceneId = filter.SelectedSceneID; - var timeline = await timelineRepository.GetByProjectAsync(projectId, bookId); + var timeline = await TimeTimelineLoadAsync("dbo.Timeline_GetByProject", () => timelineRepository.GetByProjectAsync(projectId, bookId), projectId, bookId); if (timeline.Project is null) { return null; } - var allBooks = await books.ListByProjectAsync(projectId); - var lookupData = await lookups.GetAllAsync(); - var assetLookupData = await assets.GetLookupsAsync(); - var characterLookupData = await characters.GetLookupsAsync(); - var locationLookupData = await locations.GetLookupsAsync(); - var plotLines = await plots.ListPlotLinesAsync(projectId); - var plotThreads = await plots.ListPlotThreadsByProjectAsync(projectId); - var allAssets = await assets.ListAssetsAsync(projectId); - var allCharacters = await characters.ListCharactersAsync(projectId); - var allLocations = await locations.ListByProjectAsync(projectId); - var warningLookups = await warnings.GetLookupsAsync(); + var allBooks = await TimeTimelineLoadAsync("dbo.Book_ListByProject", () => books.ListByProjectAsync(projectId), projectId, bookId); + var lookupData = await TimeTimelineLoadAsync("dbo.Lookup_All", lookups.GetAllAsync, projectId, bookId); + var assetLookupData = await TimeTimelineLoadAsync("dbo.AssetLookup_All", assets.GetLookupsAsync, projectId, bookId); + var characterLookupData = await TimeTimelineLoadAsync("dbo.CharacterLookup_All", characters.GetLookupsAsync, projectId, bookId); + var locationLookupData = await TimeTimelineLoadAsync("dbo.LocationLookup_All", locations.GetLookupsAsync, projectId, bookId); + var plotLines = await TimeTimelineLoadAsync("dbo.PlotLine_ListByProject", () => plots.ListPlotLinesAsync(projectId), projectId, bookId); + var plotThreads = await TimeTimelineLoadAsync("dbo.PlotThread_ListByProject", () => plots.ListPlotThreadsByProjectAsync(projectId), projectId, bookId); + var allAssets = await TimeTimelineLoadAsync("dbo.StoryAsset_ListByProject", () => assets.ListAssetsAsync(projectId), projectId, bookId); + var allCharacters = await TimeTimelineLoadAsync("dbo.Character_ListByProject", () => characters.ListCharactersAsync(projectId), projectId, bookId); + var allLocations = await TimeTimelineLoadAsync("dbo.Location_ListByProject", () => locations.ListByProjectAsync(projectId), projectId, bookId); + var warningLookups = await TimeTimelineLoadAsync("dbo.WarningLookup_All", warnings.GetLookupsAsync, projectId, bookId); var chaptersByBook = timeline.Chapters.GroupBy(x => x.BookID).ToDictionary(x => x.Key, x => x.ToList()); var scenesByChapter = timeline.Scenes.GroupBy(x => x.ChapterID).ToDictionary(x => x.Key, x => x.ToList()); var purposeLabelsByScene = timeline.PurposeLabels.GroupBy(x => x.SceneID).ToDictionary(x => x.Key, x => x.OrderBy(p => p.SortOrder).ToList()); var orderedScenes = timeline.Scenes.ToList(); - var warningCounts = (await warnings.GetSceneCountsAsync(projectId, bookId)).ToDictionary(x => x.SceneID, x => x.WarningCount); - var dependencyCounts = (await sceneDependencies.GetCountsAsync(projectId, bookId)).ToDictionary(x => x.SceneID, x => x.DependencyCount); + var warningCounts = (await TimeTimelineLoadAsync("dbo.ContinuityWarning_SceneCounts", () => warnings.GetSceneCountsAsync(projectId, bookId), projectId, bookId)).ToDictionary(x => x.SceneID, x => x.WarningCount); + var dependencyCounts = (await TimeTimelineLoadAsync("dbo.SceneDependency_Counts", () => sceneDependencies.GetCountsAsync(projectId, bookId), projectId, bookId)).ToDictionary(x => x.SceneID, x => x.DependencyCount); foreach (var scene in orderedScenes) { @@ -921,16 +923,18 @@ public sealed class TimelineService( scene.DependencyCount = dependencyCounts.GetValueOrDefault(scene.SceneID); } - var assetTimeline = await assets.GetTimelineAsync(projectId, bookId); - var characterTimeline = await characters.GetTimelineAsync(projectId, bookId); + var assetTimeline = await TimeTimelineLoadAsync("dbo.AssetTimeline_GetByProject", () => assets.GetTimelineAsync(projectId, bookId), projectId, bookId); + var characterTimeline = await TimeTimelineLoadAsync("dbo.CharacterTimeline_GetByProject", () => characters.GetTimelineAsync(projectId, bookId), projectId, bookId); var scenePovLabels = characterTimeline.Appearances .Where(x => x.RoleInSceneTypeName?.Contains("POV", StringComparison.OrdinalIgnoreCase) == true) .GroupBy(x => x.SceneID) .ToDictionary(x => x.Key, x => x.First().CharacterName); - var matchingSceneIds = await BuildMatchingSceneIdsAsync(filter, orderedScenes, timeline.ThreadEvents, assetTimeline.Events, characterTimeline.Appearances, projectId, bookId); - var focusSceneIds = await BuildFocusSceneIdsAsync(filter, orderedScenes, timeline.ThreadEvents, assetTimeline.Events, characterTimeline.Appearances, projectId, bookId); + var matchingSceneIds = await TimeTimelineLoadAsync("TimelineService.BuildMatchingSceneIds", () => BuildMatchingSceneIdsAsync(filter, orderedScenes, timeline.ThreadEvents, assetTimeline.Events, characterTimeline.Appearances, projectId, bookId), projectId, bookId); + var focusSceneIds = await TimeTimelineLoadAsync("TimelineService.BuildFocusSceneIds", () => BuildFocusSceneIdsAsync(filter, orderedScenes, timeline.ThreadEvents, assetTimeline.Events, characterTimeline.Appearances, projectId, bookId), projectId, bookId); var focusLabel = BuildFocusLabel(filter, plotLines, plotThreads, allAssets, allCharacters, allLocations); - var selectedScene = selectedSceneId.HasValue ? await scenes.GetEditAsync(selectedSceneId.Value) : null; + var selectedScene = selectedSceneId.HasValue + ? await TimeTimelineLoadAsync("SceneService.GetEditAsync", () => scenes.GetEditAsync(selectedSceneId.Value), projectId, bookId) + : null; if (selectedScene is not null) { selectedScene.ReturnProjectID = projectId; @@ -974,7 +978,7 @@ public sealed class TimelineService( WarningTypeOptions = warningLookups.WarningTypes.Select(x => new SelectListItem(x.TypeName, x.WarningTypeID.ToString(), x.WarningTypeID == filter.WarningTypeID)).ToList(), RevisionStatusOptions = lookupData.RevisionStatuses.Select(x => new SelectListItem(x.StatusName, x.RevisionStatusID.ToString(), x.RevisionStatusID == filter.RevisionStatusID)).ToList(), ScenePurposeOptions = lookupData.ScenePurposeTypes.Select(x => new SelectListItem(x.PurposeName, x.ScenePurposeTypeID.ToString(), x.ScenePurposeTypeID == filter.ScenePurposeTypeID)).ToList(), - ViewPresets = await presets.ListAsync(projectId, bookId), + ViewPresets = await TimeTimelineLoadAsync("dbo.TimelineViewPreset_List", () => presets.ListAsync(projectId, bookId), projectId, bookId), Books = timeline.Books.Select(book => new BookTimelineViewModel { Book = book, @@ -1002,6 +1006,25 @@ public sealed class TimelineService( public Task ArchivePresetAsync(int timelineViewPresetId) => presets.ArchiveAsync(timelineViewPresetId); + private async Task TimeTimelineLoadAsync(string operationName, Func> operation, int projectId, int? bookId) + { + var stopwatch = Stopwatch.StartNew(); + try + { + return await operation(); + } + finally + { + stopwatch.Stop(); + logger.LogInformation( + "Timeline load operation {OperationName} completed in {ElapsedMilliseconds} ms for ProjectID {ProjectID}, BookID {BookID}.", + operationName, + stopwatch.ElapsedMilliseconds, + projectId, + bookId); + } + } + public async Task MoveSceneByDropAsync(TimelineSceneDropMoveViewModel model) { if (model.SceneID == model.AnchorSceneID) @@ -1188,14 +1211,14 @@ public sealed class TimelineService( if (filter.CharacterID.HasValue) Intersect(characterAppearances.Where(x => x.CharacterID == filter.CharacterID).Select(x => x.SceneID)); if (filter.LocationID.HasValue) { - var locationScenes = (await locations.ListScenesByLocationAsync(filter.LocationID.Value)).Select(x => x.SceneID); - var characterLocationScenes = (await locations.ListCharactersByLocationAsync(filter.LocationID.Value)).Select(x => x.SceneID); - var assetLocationScenes = (await locations.ListAssetsByLocationAsync(filter.LocationID.Value)).Select(x => x.SceneID); + var locationScenes = (await TimeTimelineLoadAsync("dbo.LocationScene_ListByLocation", () => locations.ListScenesByLocationAsync(filter.LocationID.Value), projectId, bookId)).Select(x => x.SceneID); + var characterLocationScenes = (await TimeTimelineLoadAsync("dbo.LocationCharacter_ListByLocation", () => locations.ListCharactersByLocationAsync(filter.LocationID.Value), projectId, bookId)).Select(x => x.SceneID); + var assetLocationScenes = (await TimeTimelineLoadAsync("dbo.SceneAssetLocation_ListByLocation", () => locations.ListAssetsByLocationAsync(filter.LocationID.Value), projectId, bookId)).Select(x => x.SceneID); Intersect(locationScenes.Concat(characterLocationScenes).Concat(assetLocationScenes)); } if (filter.WarningSeverityID.HasValue || filter.WarningTypeID.HasValue || filter.ShowWarningsOnly) { - var warningScenes = (await warnings.ListAsync(projectId, bookId, null, filter.WarningTypeID, filter.WarningSeverityID, null, filter.IncludeDismissedWarnings, filter.IncludeIntentionalWarnings)) + var warningScenes = (await TimeTimelineLoadAsync("dbo.ContinuityWarning_List", () => warnings.ListAsync(projectId, bookId, null, filter.WarningTypeID, filter.WarningSeverityID, null, filter.IncludeDismissedWarnings, filter.IncludeIntentionalWarnings), projectId, bookId)) .Where(x => x.SceneID.HasValue) .Select(x => x.SceneID!.Value); Intersect(warningScenes); @@ -1225,9 +1248,9 @@ public sealed class TimelineService( "asset" => assetEvents.Where(x => x.StoryAssetID == filter.FocusID).Select(x => x.SceneID).ToHashSet(), "plotline" => threadEvents.Where(x => x.PlotLineID == filter.FocusID).Select(x => x.SceneID).ToHashSet(), "plotthread" => threadEvents.Where(x => x.PlotThreadID == filter.FocusID).Select(x => x.SceneID).ToHashSet(), - "location" => (await locations.ListScenesByLocationAsync(filter.FocusID.Value)).Select(x => x.SceneID) - .Concat((await locations.ListCharactersByLocationAsync(filter.FocusID.Value)).Select(x => x.SceneID)) - .Concat((await locations.ListAssetsByLocationAsync(filter.FocusID.Value)).Select(x => x.SceneID)) + "location" => (await TimeTimelineLoadAsync("dbo.LocationScene_ListByLocation", () => locations.ListScenesByLocationAsync(filter.FocusID.Value), projectId, bookId)).Select(x => x.SceneID) + .Concat((await TimeTimelineLoadAsync("dbo.LocationCharacter_ListByLocation", () => locations.ListCharactersByLocationAsync(filter.FocusID.Value), projectId, bookId)).Select(x => x.SceneID)) + .Concat((await TimeTimelineLoadAsync("dbo.SceneAssetLocation_ListByLocation", () => locations.ListAssetsByLocationAsync(filter.FocusID.Value), projectId, bookId)).Select(x => x.SceneID)) .ToHashSet(), "scene" => orderedScenes.Where(x => x.SceneID == filter.FocusID).Select(x => x.SceneID).ToHashSet(), _ => new HashSet() diff --git a/PlotLine/Sql/023_TimelinePerformanceIndexes.sql b/PlotLine/Sql/023_TimelinePerformanceIndexes.sql new file mode 100644 index 0000000..a40f8c2 --- /dev/null +++ b/PlotLine/Sql/023_TimelinePerformanceIndexes.sql @@ -0,0 +1,142 @@ +SET ANSI_NULLS ON; +GO +SET QUOTED_IDENTIFIER ON; +GO + +/* + Timeline performance pass for imported/large projects. + + Focus: + - Keep indexes narrow. + - Support the actual timeline/project load path. + - Avoid duplicating existing core indexes on Books, Chapters, Scenes, + PlotLines, StoryAssets, SceneCharacters(SceneID), AssetEvents(SceneID), + and ContinuityWarnings(ProjectID, BookID, SceneID...). +*/ + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_ThreadEvents_PlotThreadID_SceneID' AND object_id = OBJECT_ID(N'dbo.ThreadEvents')) +BEGIN + -- Supports plot-thread filters and thread-event reads starting from a thread. + CREATE INDEX IX_ThreadEvents_PlotThreadID_SceneID + ON dbo.ThreadEvents(PlotThreadID, SceneID, EventTypeID); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_AssetEvents_StoryAssetID_SceneID' AND object_id = OBJECT_ID(N'dbo.AssetEvents')) +BEGIN + -- Supports asset focus/filter lanes and asset-event reads starting from an asset. + CREATE INDEX IX_AssetEvents_StoryAssetID_SceneID + ON dbo.AssetEvents(StoryAssetID, SceneID, AssetEventTypeID); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneCharacters_CharacterID_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneCharacters')) +BEGIN + -- Supports character focus/filter lanes and character detail appearance lookups. + CREATE INDEX IX_SceneCharacters_CharacterID_SceneID + ON dbo.SceneCharacters(CharacterID, SceneID, RoleInSceneTypeID); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Characters_ProjectID_Importance_Name' AND object_id = OBJECT_ID(N'dbo.Characters')) +BEGIN + -- Supports CharacterTimeline_GetByProject ordering by importance, then name. + CREATE INDEX IX_Characters_ProjectID_Importance_Name + ON dbo.Characters(ProjectID, IsArchived, CharacterImportance DESC, CharacterName); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Locations_Project_Parent_Name' AND object_id = OBJECT_ID(N'dbo.Locations')) +BEGIN + -- Supports project location lists and LocationPaths roots by project. + CREATE INDEX IX_Locations_Project_Parent_Name + ON dbo.Locations(ProjectID, IsArchived, ParentLocationID, LocationName); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Locations_ParentLocationID' AND object_id = OBJECT_ID(N'dbo.Locations')) +BEGIN + -- Supports recursive LocationPaths expansion from parent to child locations. + CREATE INDEX IX_Locations_ParentLocationID + ON dbo.Locations(ParentLocationID, IsArchived, LocationName); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneCharacters_LocationID_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneCharacters')) +BEGIN + -- Supports timeline location filters that include character appearances at a location. + CREATE INDEX IX_SceneCharacters_LocationID_SceneID + ON dbo.SceneCharacters(LocationID, SceneID, CharacterID) + WHERE LocationID IS NOT NULL; +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneAssetLocations_LocationID_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneAssetLocations')) +BEGIN + -- Supports timeline location filters that include assets placed at a location. + CREATE INDEX IX_SceneAssetLocations_LocationID_SceneID + ON dbo.SceneAssetLocations(LocationID, SceneID, StoryAssetID); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneAssetLocations_SceneID_LocationID' AND object_id = OBJECT_ID(N'dbo.SceneAssetLocations')) +BEGIN + -- Supports scene-level location/asset reads from the scene inspector and timeline focus. + CREATE INDEX IX_SceneAssetLocations_SceneID_LocationID + ON dbo.SceneAssetLocations(SceneID, LocationID, StoryAssetID); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_ContinuityWarnings_ActiveSceneCounts' AND object_id = OBJECT_ID(N'dbo.ContinuityWarnings')) +BEGIN + -- Supports active warning counts shown on timeline scene cards. + CREATE INDEX IX_ContinuityWarnings_ActiveSceneCounts + ON dbo.ContinuityWarnings(ProjectID, BookID, SceneID) + WHERE SceneID IS NOT NULL AND IsDismissed = 0 AND IsIntentional = 0; +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneDependencies_Project_SourceScene' AND object_id = OBJECT_ID(N'dbo.SceneDependencies')) +BEGIN + -- Supports dependency counts and source-scene dependency lookups. + CREATE INDEX IX_SceneDependencies_Project_SourceScene + ON dbo.SceneDependencies(ProjectID, IsArchived, SourceSceneID, TargetSceneID); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneDependencies_Project_TargetScene' AND object_id = OBJECT_ID(N'dbo.SceneDependencies')) +BEGIN + -- Supports dependency counts and target-scene dependency lookups. + CREATE INDEX IX_SceneDependencies_Project_TargetScene + ON dbo.SceneDependencies(ProjectID, IsArchived, TargetSceneID, SourceSceneID); +END; +GO + +CREATE OR ALTER PROCEDURE dbo.SceneDependency_Counts + @ProjectID int, + @BookID int = NULL +AS +BEGIN + SET NOCOUNT ON; + + ;WITH DependencyScenes AS + ( + SELECT sd.SceneDependencyID, sd.SourceSceneID AS SceneID + FROM dbo.SceneDependencies sd + WHERE sd.ProjectID = @ProjectID AND sd.IsArchived = 0 + + UNION ALL + + SELECT sd.SceneDependencyID, sd.TargetSceneID AS SceneID + FROM dbo.SceneDependencies sd + WHERE sd.ProjectID = @ProjectID + AND sd.IsArchived = 0 + AND sd.TargetSceneID <> sd.SourceSceneID + ) + SELECT scene.SceneID, COUNT(*) AS DependencyCount + FROM dbo.NarrativeSceneOrder scene + INNER JOIN DependencyScenes dependencyScene ON dependencyScene.SceneID = scene.SceneID + WHERE scene.ProjectID = @ProjectID AND (@BookID IS NULL OR scene.BookID = @BookID) + GROUP BY scene.SceneID; +END; +GO diff --git a/PlotLine/Sql/024_CharacterTimelinePerformance.sql b/PlotLine/Sql/024_CharacterTimelinePerformance.sql new file mode 100644 index 0000000..52666d5 --- /dev/null +++ b/PlotLine/Sql/024_CharacterTimelinePerformance.sql @@ -0,0 +1,151 @@ +SET ANSI_NULLS ON; +GO +SET QUOTED_IDENTIFIER ON; +GO + +/* + Focused optimisation for dbo.CharacterTimeline_GetByProject. + + Diagnosis: + - The timeline timing showed this procedure as the clear bottleneck. + - The original appearance query joined SceneCharacters to Characters, Scenes, + Chapters, Books, and the recursive LocationPaths view three times. + - Filtering the project/book scene set once gives SQL Server a small driving + set before joining appearances. + - Materialising project location paths once avoids repeated recursive view + expansion for location, entry location, and exit location labels. +*/ + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Characters_ProjectID_Importance_Name' AND object_id = OBJECT_ID(N'dbo.Characters')) +BEGIN + -- Supports CharacterTimeline_GetByProject character list ordering. + CREATE INDEX IX_Characters_ProjectID_Importance_Name + ON dbo.Characters(ProjectID, IsArchived, CharacterImportance DESC, CharacterName); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_SceneCharacters_CharacterID_SceneID' AND object_id = OBJECT_ID(N'dbo.SceneCharacters')) +BEGIN + -- Supports appearance lookups when the optimizer starts from project characters. + CREATE INDEX IX_SceneCharacters_CharacterID_SceneID + ON dbo.SceneCharacters(CharacterID, SceneID, RoleInSceneTypeID); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Locations_Project_Parent_Name' AND object_id = OBJECT_ID(N'dbo.Locations')) +BEGIN + -- Supports project-scoped LocationPaths materialisation. + CREATE INDEX IX_Locations_Project_Parent_Name + ON dbo.Locations(ProjectID, IsArchived, ParentLocationID, LocationName); +END; +GO + +IF NOT EXISTS (SELECT 1 FROM sys.indexes WHERE name = N'IX_Locations_ParentLocationID' AND object_id = OBJECT_ID(N'dbo.Locations')) +BEGIN + -- Supports recursive LocationPaths expansion from parent to child locations. + CREATE INDEX IX_Locations_ParentLocationID + ON dbo.Locations(ParentLocationID, IsArchived, LocationName); +END; +GO + +CREATE OR ALTER PROCEDURE dbo.CharacterTimeline_GetByProject + @ProjectID int, + @BookID int = NULL +AS +BEGIN + SET NOCOUNT ON; + + CREATE TABLE #TimelineScenes + ( + SceneID int NOT NULL PRIMARY KEY, + SceneNumber decimal(9,2) NOT NULL, + SceneTitle nvarchar(200) NOT NULL, + ChapterNumber decimal(9,2) NOT NULL, + BookTitle nvarchar(200) NOT NULL, + BookSortOrder int NOT NULL, + ChapterSortOrder int NOT NULL, + SceneSortOrder int NOT NULL + ); + + INSERT #TimelineScenes (SceneID, SceneNumber, SceneTitle, ChapterNumber, BookTitle, BookSortOrder, ChapterSortOrder, SceneSortOrder) + SELECT s.SceneID, s.SceneNumber, s.SceneTitle, ch.ChapterNumber, b.BookTitle, b.SortOrder, ch.SortOrder, s.SortOrder + FROM dbo.Books b + INNER JOIN dbo.Chapters ch ON ch.BookID = b.BookID + INNER JOIN dbo.Scenes s ON s.ChapterID = ch.ChapterID + WHERE b.ProjectID = @ProjectID + AND b.IsArchived = 0 + AND ch.IsArchived = 0 + AND s.IsArchived = 0 + AND (@BookID IS NULL OR b.BookID = @BookID); + + CREATE TABLE #TimelineCharacters + ( + CharacterID int NOT NULL PRIMARY KEY, + ProjectID int NOT NULL, + CharacterName nvarchar(200) NOT NULL, + ShortName nvarchar(100) NULL, + Sex nvarchar(50) NULL, + BirthDate date NULL, + AgeAtSeriesStart int NULL, + AgeReferenceSceneID int NULL, + Height nvarchar(50) NULL, + EyeColour nvarchar(50) NULL, + CharacterImportance int NULL, + DefaultDescription nvarchar(max) NULL, + CreatedDate datetime2 NOT NULL, + UpdatedDate datetime2 NOT NULL, + IsArchived bit NOT NULL + ); + + INSERT #TimelineCharacters (CharacterID, ProjectID, CharacterName, ShortName, Sex, BirthDate, AgeAtSeriesStart, AgeReferenceSceneID, Height, EyeColour, CharacterImportance, DefaultDescription, CreatedDate, UpdatedDate, IsArchived) + SELECT CharacterID, ProjectID, CharacterName, ShortName, Sex, BirthDate, AgeAtSeriesStart, AgeReferenceSceneID, + Height, EyeColour, CharacterImportance, DefaultDescription, CreatedDate, UpdatedDate, IsArchived + FROM dbo.Characters + WHERE ProjectID = @ProjectID AND IsArchived = 0; + + CREATE TABLE #ProjectLocationPaths + ( + LocationID int NOT NULL PRIMARY KEY, + LocationName nvarchar(200) NOT NULL, + LocationPath nvarchar(max) NOT NULL + ); + + ;WITH ProjectLocationTree AS + ( + SELECT LocationID, LocationName, CAST(LocationName AS nvarchar(max)) AS LocationPath + FROM dbo.Locations + WHERE ProjectID = @ProjectID AND ParentLocationID IS NULL AND IsArchived = 0 + + UNION ALL + + SELECT child.LocationID, child.LocationName, CAST(parent.LocationPath + N' > ' + child.LocationName AS nvarchar(max)) AS LocationPath + FROM dbo.Locations child + INNER JOIN ProjectLocationTree parent ON parent.LocationID = child.ParentLocationID + WHERE child.ProjectID = @ProjectID AND child.IsArchived = 0 + ) + INSERT #ProjectLocationPaths (LocationID, LocationName, LocationPath) + SELECT LocationID, LocationName, LocationPath + FROM ProjectLocationTree; + + SELECT CharacterID, ProjectID, CharacterName, ShortName, Sex, BirthDate, AgeAtSeriesStart, AgeReferenceSceneID, + Height, EyeColour, CharacterImportance, DefaultDescription, CreatedDate, UpdatedDate, IsArchived + FROM #TimelineCharacters + ORDER BY ISNULL(CharacterImportance, 0) DESC, CharacterName; + + SELECT sc.SceneCharacterID, sc.SceneID, sc.CharacterID, c.ProjectID, c.CharacterName, c.ShortName, c.BirthDate, c.AgeAtSeriesStart, + sc.RoleInSceneTypeID, role.TypeName AS RoleInSceneTypeName, sc.PresenceTypeID, presence.TypeName AS PresenceTypeName, + sc.LocationID, location.LocationName, location.LocationPath, sc.EntryLocationID, entry.LocationName AS EntryLocationName, + sc.ExitLocationID, exitLocation.LocationName AS ExitLocationName, sc.AppearanceNotes, sc.OutfitDescription, + sc.PhysicalCondition, sc.EmotionalState, sc.KnowledgeNotes, s.SceneNumber, s.SceneTitle, s.ChapterNumber, s.BookTitle, + sc.CreatedDate, sc.UpdatedDate + FROM #TimelineScenes s + INNER JOIN dbo.SceneCharacters sc ON sc.SceneID = s.SceneID + INNER JOIN #TimelineCharacters c ON c.CharacterID = sc.CharacterID + LEFT JOIN dbo.CharacterRoleInSceneTypes role ON role.CharacterRoleInSceneTypeID = sc.RoleInSceneTypeID + LEFT JOIN dbo.PresenceTypes presence ON presence.PresenceTypeID = sc.PresenceTypeID + LEFT JOIN #ProjectLocationPaths location ON location.LocationID = sc.LocationID + LEFT JOIN #ProjectLocationPaths entry ON entry.LocationID = sc.EntryLocationID + LEFT JOIN #ProjectLocationPaths exitLocation ON exitLocation.LocationID = sc.ExitLocationID + ORDER BY s.BookSortOrder, s.ChapterSortOrder, s.SceneSortOrder, c.CharacterName; +END; +GO diff --git a/PlotLine/Views/Shared/_Layout.cshtml b/PlotLine/Views/Shared/_Layout.cshtml index ea33941..61f7212 100644 --- a/PlotLine/Views/Shared/_Layout.cshtml +++ b/PlotLine/Views/Shared/_Layout.cshtml @@ -1,9 +1,22 @@  - + @ViewData["Title"] - PlotLine + @@ -12,7 +25,7 @@
-