Timeline settings
This commit is contained in:
parent
2ad5865c58
commit
69fb21c5eb
@ -1,5 +0,0 @@
|
|||||||
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
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
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=
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
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=
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
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=
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
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
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
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=
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
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=
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
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==
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
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==
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
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
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUTW/cNhCG/4owZ1HmlyhRN2OdoAs39SJZpEFuFDmKCcvUgqScGIb/e0HtFo5PRS8EMeIM33nmpV4gmEeEAa5Ppw9PGHKCGrLfQpxyRagiVBypHmg3MNX0VAql+Xeowd/iMwzQSWuZ1UgEKiTS0ZaMYrLEOdSMMkd5K0tN8yPB8ALGNw6fvMVmSV8xJr8EGOBvH9zys9xtfGPnZXVNXGbch5RNsEXMX/vdLfnz+nC8O5xPJUwlufEOBjBUWWaoJq0YOyJ7y0iv+olYzTrLrZxGPZ7TfMgYg5mb5B7e7ndLDpjtwBsuGkq4htcanMmmSB5NwuPzqajYEN2UeL2Ft+3wAk8YYeD1vzDP5a7s7K8e07j62V2d12zSQ9rWydi8xGeo4RSXE8bsceNznRI+jvPz0aSHj+czZZs+/EK7ZnS7ZQ0ZBhAcatj4zLPJfgnVReJu9hjy9jFHH5K3/1VKQQ13X6rDbPK0xMd34/hyprz/H5A/GXvvA1b7GxiAMuRO9EgmzhSRvTPEtEITpYSakFndcQY17JaQfViXNVX7kPFH3FqCAT6aOeFZ33W09z6jzWssfX5TxVaHuLjV5uptlIw2tBGUlqQ1n9ZcfUbnI9qMpYljXC/1vr5P4YpvSbs1Rgy5Oph8X/1h0j0MoE1vmdFGG6OsnbClOFFHjaKdQ+UUOsld56SWTklNrZJmZNKZlo1TiUANWJxTbWYVSnV0YiPRWnEiBUWiOycIFZ1go9SMTqW1N47V3bzxtz2V6ATRODkiNTNESyGIE63puJq6jk+/Ibn4gdEC2OHT+dltCpRzPTrFCJesJVJrRnrddmTs+lGPqsfWFs23GAPOv4H65G1c0jLl6uKQ6h26z2sov45qc8tPH8ivbUY3i33AWJUZGx/KS7mM9fX19fUfAAAA//8DAEdV7PeBBAAA
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpRTTW/cNhD9K8KcRZmkKErUzVin6MJNvEgWadEbxRnFhGVqQVFOAmP/e0DtBol764UgBnwz72P4CsE+E/Rwezq9e6GQFigh+a0kudSMa8brIzc9b3uhq47rzsj2XyjB39N36KFVzglniNWkiSnkDRvq0TFEMoIL5LJRuaf9skD/CtZXSC/eUTUvnykufg7Qw98+4Pw1z7a+ctO8YhXnifZhSTa4TObDfnfP/ro9HB8Ol1cLLRlceYQeLNdOWG5YUw8tU50TrNPdyJwRrZNOjYMZLjAfEsVgp2rBp1/zcU6BkutlJeuKM2ngXALaZDPlwS50/H7KLDaL7nK93MrbtX+FF4rQy/KnmZd2N27yN8/LsPoJby5nsstTVnmK84li8rR5ssmcJpv8HIrrpN3kKSQo4eFTcZhsGuf4/MaoTxf9+/8h/5inv/tGbk2Eu3kNCXqoOyjhvXWPPlCxv4MeuCCJdUdslEIz1aFltqkN07rWIwlnWimghN0ckg/rvC7FPiT6Ejf+0MMfdlrowvw2ukefyKU1ZlH/6LwKhzjj6lLxy37BK17VnGfQmk5rKj4S+kguUZZ3jOu1338gUssNtFtjpJCKg02PxZ92eYQejO2csMYaa7VzIzWcRo7cat4iadSESmKLyijUynCnlR2EQtuIYcwVKIFy2sW2YE42DUeNDK0bmFLWsc7ZkbVSDY1tVKMGfONj8TBtybiOK8KaGRqRKSMsM6quGdaNbaUe21aOv1lyDV/wbDDSy+WrbAw0YkeoBZNKNEwZI1hnmpYNbTeYQXfUuMz5nmKg6Tej3nsX52UeU3HdneKNdR/XkL97se3RVx/Yty2ju9k9USxyxtaHvN3XWM/n8/kHAAAA//8DAC/YO0o1BAAA
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSTT2/cIBDFv4rF2TiAMQbfok2rrtI0q2bVVr1hGGdRvLDCOH8U7Xev8G6VpLferCfPzJvfG16R13tAHbo8HD49gk8TKlFyi8QIE5gITOotUR1pOyoqSWStSPMblchdwwvqUMuNoUYBrkEA5pY0uK8Hg60FRQm1hDU899T3E+pekXaVhUdnoArTD4iTCx516KfzNjzl2dpVZgyzrWIYYe2npL3JZr6tV9f46+Vme7s5/TXBlIsrZ1GHNBGGaqJwU/ct5tJQLIUcsFG0NczwoVf9qcz5BNHrsZrsw9t8G5KHZDpWsboimCl0LJHVSWfLvZ5g+3LILhZEV1kvF3n57F7RI0TUsfIvzFO7CzO6CxP2e+3txeC8m3aoRIcYDhCTgwXHsuE46uSCL85DVqMDn1CJbu+KzajTEOL+A6O70+rr/9j8Rpud81Csr1CHCAVmawl4YFRgLq3GuqkVFqIWA1CjWkZRiVbBJ+fnME/F2ie4j4tL1KHPepzg5O8ymp1LYNIcs/VfImcNzy6tgs1C7rOJwc4mFW+4KalIVROSe8zpMKfiO1gXwSTIO23jfG7/TwkTbClazTGCT8VGp13xRU871CGlpaFaaaW1MGaAhsBALNGCtBaEFWA5s63lilvBFTGC655yqxvaD1nJvnO6xXJQvdSKG2NwL5nEXDGOe1FT3LYDAdEPLWvlB6zF7bjEYSThYGusYLCYK6qx4nWNbd3olomhbdnwDsk5cUoyJwuPp6exOBDWSrCCYsZpg7lSFEvVtLhvZa96IaEx2fM1RA/jO1A3zsQwhSEV54MpPqD7Pvv8vIvleJ6cx89LZFfBPEAscuTa+XzN55SPx+PxDwAAAP//AwCX2JfEJQQAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUTW/cNhCG/4rAsyjzS/zQzbBb1HVTL+JFWvRGcUa2EC21oKhNA2P/e0DtBol7600YaGZePvPOvJHoD0g6cns8/nLCmBdSkzxuIcGEpkxTJvfMdcx0vG2ctqJ19h9Sk/ERv5KOGBUCDw6pRI1UAWtpL4dAAdBxxoGJVpWa/mUh3RvxYwN4GgM28/IJ0zLOkXTkrzHC/KX09mMTpnmFJs0TPsQl+xiKmD8f7h7pH7e7/dPu8teCS0luRiAd8UwH7pmjrewNVTZwarUdaHDcBBHU0Lv+kjbGjCn6qVng84/+MOeIOXSiEbJhVDhyrgn47Ivk3i+4/3osKjZE9yVeb+Hts3sjJ0ykE/V3mJdyN2Eab/J8nPCE09GnBdNNmA8HH4HU5JjmI6Y84oZle+k0+TzOsbo2u5tGjJnU5Om52k0+D3M6vGP1fEHw8D8InDD1RSCgBwTrwaJSTspBOtRGeGutBuV6z5mRFoztATl3vRjQBBlEO0BQUAb6Ms29n35fNn5OsN4CM0ILVOiE0toFhtLi0Bpk4LXutQ0OpDVCWbDSO++569EEp0Op98GH1zFi9XBPOsI4CpAW6SC4psqCp76Vjmot9YA8OCM4qcndHPMY13ldqoeY8SVt/EhHfvXTghdytym8jhlDXlOB+rcuzXZphjXk6ocDOGtYIxkrSWs+rrn6iDAmDBkL3n1ar/X+kyK02JLu1pQw5mrn82v1m19eCxVvA/euPFWHMGDLcGDAvGYGUINGUAIMKKdAK8eCVr7nCnzL+6FESE2wGK7aPC697h0TjgbjFFUYBuqk81RDGwwXrZBGvuNYPU2bM4JlCkFShwNQ5binTklJQbbeCD0YI4afkFzNx1kBDHi6bOumQANYBM2pULylyjlOrWsN7Y3tXa8ttqFofsQUcfoJ1IcxpHmZh1xdvVu9Q/dxjeXiVJuPv4yR/rvN6H4OnzFVZcZ+jGXBrmM91+SAflkTHraD1b2RXdmuar/dLSGblnNdk+fsU16P17BUDTdWn8/n8zcAAAD//wMA7yR7Y/UEAAA=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUW2/cNhCF/4rAZ1HmTbzozbBb1HDTLGKjLfo24oxiIVppQVGbBob/e0HtBqn71jdhoMM58/FwXtkMR2Iduz2dfjrTnFdWszzuJSWU5cJyoZ9F6ITrpG2EMNK58Ber2fhI31jHnIlRxkBckyVuULS810PkiBSkkChUa8qZ8Hll3SuDsUE6j5GaZf2d0jouM+vYH+OMy9fSG8YmTsuGTVomepjXDHMsZn57uHvkv94enj8eLn+ttBZxMyLrGAgbJYjAW907bnyU3Fs/8BikiyqaoQ/9RTbOmdIMU7Pilx/9cckz5dipRulGcBXYW80QMhTLPaz0/O1UXOyI7ku93sv7Z/fKzpRYp+rvMC/H3cRpvFm3fqIzTSdIK6WbuByPMCOr2SktJ0p5pB3LmVK/rGMuRGN04L2U6MGZ1qHXrdIOtSD0wrUYMIA1dlCxbQfsfXBmMKikQUvG9I7VbAc3TZDHZa6u3u+mkebMavbxqTpMkIclHd+hf7oQffgfQIvtMi8SIKEH9GRM0HrQgaxT4L23aEIPUjjt0fkeScrQq4Fc1FG1A0aDJR8fIL6MM1UP96xjQpJC7YkPSlpuPAKHVgdurbYDyRickqxmd8ucx3lbtrV6mDN9Tvu8rGM/w7TSZdLbFF/GTDFvqUD405Zmh7TgFnP1IwBSNKLRQhTRlk9brj4RjolipoLjOW3X8/4jUVbtorstJZpzdYD8Uv0C6wvrWAAfJQQIADbGgVpBg0ABVjgki5bQKHRogkFrgojWQC8NQiv7oVRYzajkrbpE3LQmgHM8IAVuhjjwAFryFtANJCVCGN5xrD5Ouy56YQg1DzQgN0ECD0ZrjroFp+zgnCq670iuYZGiAEY6Xx7r7sAiekIruTKy5SYEyX1oHe+d70NvPbWxeH6kNNP0L1AfxpiWdRlydc1a9Q7dp20uC6fac/d1nPnf+x3dL/ELparcMYxzeV/Xa32r2ZFg3RId933VvbJDeVzV8762lG5aKW3NnjKkvJ2uZW0a6bx9e3t7+wcAAP//AwCJe8b/9AQAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpRU0W7jKBT9FYtn4wLG2Pitm+5oo06n0TQ7u9o3DNcpqgMR4M5WVf59hJOq6Yz2Yd+sa869555z4BU5tQfUo+vD4fdncCmiEiW7lBhhAhOBSb0lsidtX5OKMdoxUf+DSmRv4QX1qOVaUy0B1yAAc0MaPNSjxsaApIQawhqee6pdRP0rUrYy8Gw1VD5+gxCtd6hHf1ln/Pc8W9lKT342VfATrF1MyulM5st6dYs/X2+295vTqQgxgytrUI9GzrkikuOaqg7zZhiwasSIa01BUyoEYe0JZl2C4NRURfP0Pt/45CDpnlWsrghmEh1LZFRSmfKgImxfDpnFItFNrpdLefnsX9EzBNSz8k3MU7srPdmrfRxmO5mrye921u1W3o12NweV8uASHYI/QEgWFnF+s06Fl89+t8v90Cc1RUAl2kLYW6em048bGNU8pQc/h0WZaJ7+6wzqkZqTRyValJymZWxxXmY1WXDpF+zF4PuHYjOpNPqw/2DSw0n79f+Q/k7pR+ugWN+gHhEKzNQd4JFRgXlnFFZNLbEQtRiBatkyikq08i5ZN/s5FmuXYHdW7QO/66AfbQKd5pB3+lvksG2CN7NOxbvBlFSkqgnJoDkd5lR8BWMD6AR5iW2Yz/1+gjDBFtAnO8Ev8qzmEMClYqPSY/GHio+oR1J1miqppFJC6xEaAiMxRAnSGhBGgOHMtIZLbgSXRAuuBsqNaugw5goqEeSQFUuuB9WNrBs6THndYC6ZxB0FgrlgQzt0YyO0/CBucT9lnNId4WBqLGE0mEuqsOR1jU3dqJaJsW3ZeKHTORCUZNUvQ/hnBHPO0pdTtN92N/B8uscLT2FMB0ZQzDjNPCXFnWxaPLTdIAfRQbPwXHkX/ZuQ3yAMPtqUH5E76+xeTT8feXfmFoKD6cKdO6uDj35MxTmWxQe/vs4uv2LFEtHv1uF/l2DceP0EocjBUtZdmHk8Ho8/AAAA//8DANuwUiYMBQAA
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUTW/cNhCG/4rAsyjzS/zQzbBb1HVTL+JFWvQ2JEe2EK20oKhNA2P/e0DtBol7600Y6J0ZPvPOvJEJDkg6cns8/nLCKS+kJnnYQoIJTZmmTO6Z65jpJGu4skwY9w+pyfCIX0lHjAqBB4dUokaqImupl32gMaLjjEcmWlVywstCujcCQxPxNARs5uUTpmWYJ9KRv4Ypzl9KbRiaMM5rbNI84sO0ZJhCaebPh7tH+sftbv+0u/y14FLEzRBJR3qlFDCnqORgqWq9p9DqnsrAMXCuNRPmIhumjGmCsVni5x/145wnzKETjZANo8KRc00iZCgte1hw//VYutgQ3Zd4vYW3z+6NnDCRTtTfYV7S3YRxuMnzccQTjkdIC6abMB8OMEVSk2Oaj5jygBuW7aXjCHmYp+pa7G4ccMqkJk/P1W6E3M/p8I7V8wXBw/8gcMLkSUda3XqUvRXaa4jgpO05oHQxeKlbtN5Ei8ZIISG0gVkeuOEtONO2RkvBSU1extnD+Puy8XOCeRuZEVqgQieU1i4wlBb71iCLoLXXNrgorRHKRivBAXDn0QSnQzHIBwivw4TVwz3pCOMoorRIe8E1VTYChVY6qrXUPfLgzNbD3TzlYVrndakepowvaeNHOvIrjAteyN2m8DpkDHlNBerfuhTbpTmuIVc/HMBZwxrJWBGt+bjm6iPGIWHIWPDu03rN9x+J0GIT3a0p4ZSrHeTX6jdYXgsVsIGDK0/VIfTYMuxZZKCZiaijxqhENFE5FbVyLGgFnqsILfd9iZCaYDFctXncYXDRy5aythdUKTTUe6upNRpYtMCNNe84Vk9j0UGwTGGU1GEfqXIcqFNS0ihbMEL3xoj+JyRX83FWAEc8XbZ160DHaDFqToXiLVXOcWpda6g31juvLbah9PyIacLxJ1AfhpDmZe5zdfVu9Q7dx3UqF6fafPxlmOi/24zu5/AZU1VmDMNUFuw61nNNDgjLmvCwHazujezKdlX77W4J3WinVE2eM6S8Hq9hqRujLT+fz+dvAAAA//8DAAhT0Xb1BAAA
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUT2/cNhDFv4rAsyjzP0XdDLtFF27qRbxog95G5DAWopUWFLVpYOx3L6jdInFvuQkDveHjb97wjUxwRNKR+9PplzNOeSE1ycNWEkwYygxl8sBcx2wnWcNbZbV2f5OaDE/4jXTEKu+5d0glGqQqME17GT0NAR1nPDChVekJnxfSvREYmoDnwWMzL39iWoZ5Ih35a5jC/LWcDUPjx3kNTZpH3E1LhskXM3/sHp7o7/f7w/P++teCSxE3QyAdiUopYE5RyaGlSvc9BW0ilZ6j59wYJuxVNkwZ0wRjs4Qv388Pc54w+040QjaMCkcuNQmQoVjuYcHDt1NxsSF6LPV6K2+f3Rs5YyKdqP+DeW1358fhbln7Ec84niAtmO78fDzCFEhNTmk+YcoDbljOmPp5GXIhKvreSyOcUkq1MUQbDRqjnYkgdRSM8dBrJXvXCo6tMYDKe4hGCQjOcE1qsoEbR8jDPFU37w/jgFMmNXl+qfYj5Din4zv0L1eiu58AWmyTjmije5SxFaY3EMDJNnJA6YLvpdHY9ja0aK0UErz2rOWeW67BWa2tkYKTmnwA/zpMWO0eSUcYRxFkizQKbqhqA1DQ0lFjpInIvbOb5mGe8jCt87pUuynj57Tdl3TkVxgXvN70PvnXIaPPayoQPpkSxn2aw+pz9T0AnDWskYwV0ZpPa64+YhgS+owFxyGtt37/kwgjNtHDmhJOudpDfq1+g+WVdMRB6zk4cADG+4iaYWSBgWE2oAkGgxLBBuVUMMoxbxT0XAXQvI+lQmqCJW/VFnHXIyBGRq12nirnLXWCSYqaxT5E3zLw7zhWz2PRgW+ZwiCpwxiochyoU1LSIDVYYaK1Iv6A5BYWzgrggOfrsm4OTAgtBsOpUFxT5RynrdOW9rbtXW9a1L54fsI04fgDqA+DT/Myx1zdsla9Q/dxncqDU225+zpM9J9tRo+z/4KpKjOGYSr7dRvrpSZHhGVNeNzeq+6N7MtyVYft2RKmMU6pmrxkSHk93crSNNa0/HK5XP4FAAD//wMApDY/gfQEAAA=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACoxUS2/jNhD+KwLPokJKFCUK6MFwdlEjm42ReNuiN4ocxkRk0qAoZ4NF/ntB2V472x56E0bz+h7DH8jJHaAOLfb7TwdwcUQ5inYOlaTkmHBMqg0RHWm6ihRt3VS8Kf9GObJ38IY61DClqBKAK+CAmSY17iujsNYgKKGalDVLPeXziLofSNpCw8EqKPz4B4TReoc69Kd12r+m2dIWavCTLoIfYOXGKJ1Ky3xdLe/wl8V687A+Zo0wpuLCatQhwxiTRDBcUdliVvc9ljU3uFIUFKWck7I5llkXITg5FKN+uczXPjqIqiuLsioILgV6z5GWUaaVeznC5m2ftpgpuk3xfA7Pn90PdICAujI/k3lsd6MGe7Mb+8kO+ibK8AzRBLmDVx9e4CAHlKN98HsI0cLMzcNTdlmJkoIUJS8JQTm6l2prHWSr2+xhSIClagkDXWEBRmMmqMSCVRXWVS2bkpumKQ3K0R0EB8NV13urgh+9idmJ8uzDnKV30brJT2O2chGeg4zHus9yGAHlaD31gx23jyD128Y/Tumfm4aEZTmFAC5maxm32e9y3KIOCdkqKoUUUnKlDNQEDNFEctJo4JqDZqVuNBNMcyaI4kz2lGlZ096kCMrRwxT3Uzzz//1qiU2wux3oywabmeP1IKPxYbfS4KI1NklzzpgNNQwzquzUczlYcPEDyahDhEKpqxawKSnHrNUSy7oSmPOKG6BKNCU9Embs8/STJ2KMZpWp25b3oqcEStO0jDSmJ1qZSgld99CUDWlaaIUipK8ZbXuhiAZaM53QBa8nFX+1QjUL9Di5dJ3ZKsF+tQ5/5+zCyDr46JUfLoD/pdfS7/Z+tDEhNydRv41w7136e7r8j8ULHy8xSBeQzUfHpGa9YoAVJQIzAjVuRUuwVr2o2jrp2qMc3Xr1AiFL1pLWzWqc3fTwlC2C2toIKk4hTf5rhnMU8vP5WC5MFF8/bZY+wGK/z0/R3w6JnmOzs/QfXpRvY0rf+jGhiGG6ctATDOa815WPNByOb5RNQa51C5pTXDJaYyYExa2oG9w3bS963kKtLj7NHkHbACrO/TbHaSdi/8uQixCtkSqO6Wq+eDX76GTMU8qvS16p9rP6OPxKuZOHTp0oSV59Or6Ys3X+14P5/v7+/g8AAAD//wMA9GOVPyEGAAA=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpRVTW/jNhD9KwKvtbT8kChKwB5Sx9sa28RBbHSL3kbkKGYjkwZFZTcN8t8LSXbj7KKHXiRqSM48Pr55eiEODkhqcnU8rp7QxZ4sSLRTiFMuUypTKna0qmlZC5ZRrpjKiz/JgtjP+ExqUuZaM11hKlBimhtapI1odWoMVowyQ3mRjznhoSf1CwGbGXyyGjPf/46ht96RmnyxzvivY22wme78YLLgO1y7PoLTI5jb9fJz+tvV3W5zN6/qsR83Z9aQmrR5ngOt8lQwUGleNE0KhWxToRlqxqSkvJy3WRcxOOiy3jy+1Tc+Ooy65hkXGU15RV4XxECEEXIDPe6ejyOKiaLrMb6YwtOwfiFPGEjNF2cy53QfdGc/HPpmsJ35MD3JghyDP2KIFic2NtvkDQSjGc245JSSBbkBvbcOk/V1sunGI4JWNEcj0gpbk+YVg7TKhUiNKKDksi1L3pIF+YzBYXeR9cbq4HvfxuREcvKuzvZquXLQdDjW+ARdj2RB1v02gjPQeYerb6iHOOfahWGcXnoXrRv80CdrF/EhwGn+vH85hIAuJncQ98mv0O9JTSpQmkEFFYDUusWCYksNBUlLg9JINDk3pcmr3Mi8olrm0LDcQMGadoyQBfl55HA7aI19f4l2VEnXTSCS00UtO4suvuOR1IQy5EYoTFvOZJorAykUokqlFLJFpquSs3OdHYQHjKQmhSwaFK3ispFgoBKqZYCiMroRskDVlEZhWQouQBeaKqZZyQqoyqIopZgS3gVvBh2/v2sx3cBd8H+hjiNXpCaipMB5aRiYXBWCKsWhKvKmUK2UpmlBy0pX2Oi2BVGaEhvFuJCMlkyJSqoz/JV7sA6vbX/s4PmirspkJn7SAIq18MbqvPxTgAN+9eHxdtZxdrvakQW5H9xoCcl61MhX69Jvcmzpm6GLdrcPCAbNjTf4o5Bw7JdkalHOheJU6ZQXSoz6lWlFyyYtZSFaU1JjKk0W5NrrRwzJKDGwbmyrf5NttslV0HsbUcchjPj+mHBstsldB7H14fDOSi4O9j0BGReMcrIgBp9mO5owSmMUGslSnrMizauKpaoqyrQpVVM1UmGhR8Y2QzwOMblHYwPqOJ341BqfwHZDwCVEfPBh9MdN3GM4o1nuUT/+SNNZHyfxMjqKZjsb3Pp/+NsqBB+WfhhtvL78WrvWJy/J0h+OtsOQfEwWyU0/QfoFHQboLkOrJ+iGuZ0uo2cjeLc7wHE/BXbQP06DrXm8x953Txj6KXCLcWvmudvhF4zT6I2OeQKifcKd953eg51LLL3BKwfdc2/nRPfwt5+xfzm20/uqP96eEk48Jx8TlryO5n1A6IeAh+mXVr+QtXMYpqLXw+xXa3dju872qL0zPakVyzNV5vnpqv5zWUkzmfPy9fX19R8AAAD//wMAv9ZPsz4HAAA=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpRTS2/cNhD+KwLPosy3RN2MdYou3MSLZJEWvY3IUUxYphYU5SQw9r8H1G7gpLdeCGLAmflefCURnpH05PZ0eveCMS+kJjlsJcGEocxQJo/M9qztJW+YUEq35l9Sk3CP30lPWuUcdxapRINUeabpIEdHvUfLGfdMaFVmwpeF9K8EQuPxJThs5uUzpiXMkfTk7xD9/LXshtC4aV59k+YJ93HJEF0B82G/u6d/3R6OD4fLqwWX0twET3oyKqWAWUUlh44qPQwUtBmpdBwd58Yw0V7aQsyYIkzN4p/e9vs5R8yuF42QDaPCknNNPGQokAdY8Pj9VFBsEt2Ver2Vt2v/Sl4wkV7UP8W8jLtxU7h5XoY1TP7mcmZYngrLU5pPmHLATZON5jRBDnOsrpt2U8CYSU0ePlWHCfI4p+ffhPp04b//H/SPZfu7b+jWjH43rzEX/xipyXtwjyFitb8jPWEchZcd0lFwQ1XngYKWlhojzYjc2VZwUpPdHHOI67wu1T5m/JI2/KQnf8C04AX5bXKPIaPLayqk/jElCoc0+9Xl6k1+zhrWSFaQPKz5tObqI/qQ0GUs9I5pvc77T4swYmvarSlhzNUB8mP1JyyPpCcWOsfBggUwzo2oGY7MMzCs9Wi8Qa+Eb72yyhtlmTMKBq48aD6MpUJqgsXtaguYMpIPppVUGtBUDVpQi3qgoxNacS61FiUTbzpWD1PpA9cxhV5Si6OnynKgVklJvdTQCjO2rRh/keRqPmdFYI8vl6+yITDed+gNp0JxTZW1nHZWt3Rou8EOpkPtCuZ7TBGnX4R6H1yal3nM1TU71W/SfVxj+e7VlqOvIdJvm0d3s3vCVBWPIcSS7qut5/P5/AMAAP//AwCRcyO5NQQAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpRTTW/UMBT8K5HP69RfceLcqi2IVYGuaAWIm+P3wlqk9spxCqja/46cXVTgxi0aZebNm3l+JsE+IunJ9fH46glDnsmGZL9CgglNmaZMPjDTs7aXvGaiER1TX8iG+Fv8SXrSKue4M0glaqQKWEMHOToKgIYzDkw0qmjarzPpn4n1NeCTd1jH+SOm2cdAevLJB4jfy2zrazfFBeoUJ9yFOdvgipn3u+0tfXu9f7jbn/+acS7k2gPpyaiUsswoKrntqGqGgdpGj1Q6jo5zrZlozzQfMqZgp3qGby/zIeaA2fWiFrJmVBhy2hCw2RbLg53x4eexuFgjuin4ZoXXz/6ZPGEivdj8DvMsd+Umf+Xi46MNcDX64OcD2ZBjikdM2eMax7rhNNnsY6guQ7aTx5DJhtzdV/vJ5jGmx78yuj+vvvuPzd9Zd/ABq90N6QnjKEB2SEfBNVUdWGobaajWUo/InWkFJxuyjSH7sMRlrnYh49e0uiQ9eW2nGc/+rpM7+IwuL6lY/6xL1/jD522EAhSdfYqwuFy9xM1ZzWrJWNFY8nHJ1QcEn9BlLDs9pOUi/w9FaLGStktKGHK1t/lQvbHzgfTE2M5xa6yxVjs3YsNwZMCsZi2gBo2gBLSgjAKtDHNa2YErsA0fxoIU36Xdaj0oq6HVAoHyFgeqpOnooMxAOzZKaKTRXBeLL7FWd9PKcx1TCJIaHIEqwy01SkoKsrGt0GPbivGPSC6Nc1ZyAnw6P43VgQboEDSnQvGGKmM47UzT0qHtBjPoDhtXPN9iCjj9EdQ771Kc45iry8FUf0X3YQnleVfr8Xz3gf5YK7uJ7humqlRufSjXfGn5dDqdfgEAAP//AwDbxUFEJQQAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpRUwW7cIBT8FYuzcQBjbHyLNo26Stus2lVb9fYMzwmKg1eA00bR/nuFd6s0p6oXhJ6Zx7yZwS/EwyOSnlweDu+e0KdISpLcWhJMKMoUZfWe6Z61fc0rJgTjXP8gJXE3+Ex60kpjuNFIa1RIpWUNHerRUGtRc8YtE43MPeEukv6FgKssPjmD1Ry/Yohu9qQn35y38898N7jKTPNiqzBPuPUxgTeZzKft5oZ+uNztb3enUxFjBlfOkp6MUkpgWtKaQ0dlMwwUGjXS2nA0nCvFRHuCOZ8weJiqaB9e77dz8phMLypRV4wKTY4lsZAgUx4g4v75kFmsEl3lermW123/Qp4wkF6Uf8Q8tbswk7t4jMPiJntxWhPEh7iuI5g0h2dSkkOYDxiSw1WfyxjxcZie9xAfrk9n8ja++4VmSWg38+IT6YmqSUlWfaYJkpt9caa4mRz6tH5MwfnozL9aZWVuvxS7CdI4h8c3dnw5qbz9D5E/grl3HovtFekJ4yhs3SEdBVdUdhYoNLWmStVqRG50KzgpyWb2yfllXmKx9QnvwjoS6ck1TBFP/C6DuXcJTVpCnvO7yrHahdkuJhWvVnJWsapmLIOWdFhS8RmtC2gS5iH2YTn3+/oWIpRYQZslBPSp2EG6L95DvCc90dAZDho0gDJmxIbhyCwDxVqLyiq0UtjWSi2tkpoZJWHg0kLDhzFXSEkwJ6dYw8rHViq0DbVSCSqZkBTqbqRK2ZZJI0GP2dxXHYvbKePAdEyiranG0VKpOVAt65rauoFWqLFtxfiXJOc8cJYFtvh0enYrA2Vth1ZxKiRvqNSa0043LR3abtCD6rAxmfMNBo/TX0J9dCbMcR5TcU5I8Ua6z4vPv45iTctP5+mv1aOr2TxgKLLH4Hx+KWdbj8fj8TcAAAD//wMAk61HJIEEAAA=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUTW/jNhCG/4rAs6hQFEWJuqVOFzWy2Rgbd1v0NiJHDhGZNCgq2yDwf19QdhBnFz30Joz4zsczL/lKHOyRdOT6cPj9GV2cSE6iXUKccUmZpKzaMtWxphOskKKquGT/kJzYW3whHWmE1qVWSCuUSIVhNe2rQVNjUJWsNIzXIuWE3US6VwK2MPhsNRZ++oZhst6RjvxlnfHfU22whR79bIrgR1y7KYLTqZkv69Ut/Xy92d5vTqcmnJK4sIZ0hMm6kbrmVBuFVNRS0haloYKV2pQN9Iqpk8y6iMHBWEzm6b2+8dFh1B0veFUwyhU55sRAhNRyDxNuXw6piwXRTYrnS3j57F7JMwbS8fwN5indlR7t1X7qZzuaq9HvdtbtVt4NdjcHiKlwTg7BHzBEiwuc36yD8PLZ73YpH/kE44QkJ1sMe+tgPP24wQHmMT74OSxkJvP0X2dIR2COnuRkITmOS9nsPMxqtOjiL9qLwvcP2WaEOPiw/7CkhxP79f9Afwf60TrM1jdJUyI3VYt04KWkojVAoa4UlbKSA5ZaNbwkOVl5F62b/Txlaxdxd6b2ob/roB9tRB3nkGb6WyazbYI3s47Z+4JLVrCiYiyJ5niYY/YVjQ2oI6YhtmE+5/tJwiVfRJ/siL/gWc0hoIvZBuJj9gdMj6QjClpdggIFILUesGY4MMNAssagNBKN4KYxQgkjhWJaCuhLYaAu+yFFSE4wmSxbfF0L0DAAUlNJSYVmDYWWM2q4qnXbt2D64QPc7H5MOtAtE2gqqnAwVKgSqBJVRU1VQ8Pl0DR8uOB0NkTJEvVLE/45oTl76cvJ2m+zG3w+3eOlT2lMi0aWlIuypkKpkraqbmjftL3qZYu1TpOtvJv8G8hvGHo/2ZgekTvr7B7Gn4+8b+YWg8PxYjt3Vgc/+SFmZ1tmH/b1dXbpFcsWi363jv67GOPG6ycMWTIWWHexzOPxePwBAAD//wMATqNAzAwFAAA=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACoxUTW/jNhD9KwLPpkJKFCUa6MFwdlEjm42ReNuiN4ozjInIokFRzgaL/PeCsr12tj30Jozm4703b/iD9HqHZE4W+/2nA/ZxIDMS3RQqWCEpk5SVG6bmrJ4LlqtK8FI2f5MZcXf4RuakFsZwo5CWKJEKYBVtS2soACrOOLCiEqmnfh7I/AfRLgc8OIO5H/7AMDjfkzn50/XgX9Ns7XLT+RHy4Dtc9UPUvUlgvq6Wd/TLYr15WB+zBhxSce6AzAmTVS1NVVADCqmopKQNSqCCcQO81q1i6ljm+oih110+wMtlPvjYYzTzIi/KnNFCkfcZAR11gtzqATdv+4Rikug2xWdTePqc/yAHDGRezM5iHtvdmM7d7IZ2dB3cRB2eMdqgd/jqwwsedEdmZB/8HkN0OGnz8JRdIHGWs7yQBWNkRu612boes9Vt9tAlwto0TCCUVKEFKhTXVImypFBWui6krevCkhm5w9Bjd9X13pngB29jdpI8+zBn6fvo+tGPQ7bqIz4HHY91n3U3IJmR9dh2btg+ooa3jX8c079+7BKX5RgC9jFb67jNftfDlsyJ0o3hWmmltTTGYsXQMmBashpQgkQQBdQglAApFDNS6JYL0BVvbYqQGXkY436MZ/2/X4HYBLfbIVwQbCaN152O1ofdCrCPzrq0mnPGZKium1hlp57LzmEfP4icHMWxgLJBagsuqWhAU12VikpZSovcqLrgR8Gsex5/6sSsBVHaqmlkq1rOsLB1I1htWwbGlkZB1WJd1KxusFGGsbYSvGmVYYC8EpDYBQ+jib9aoZwW9Dj26TqzVaL96nr6XYqLIuvgoze+uxD+176Wfrf3g4uJuT0t9duA975Pf0+X/7F44eMlhukCsunoFGt5Ky3QAkqggitGNXBGoQKsoKhlrRLkW29eMGTJWtr10zbObnp4yhbBbF1EE8eQJv810Tku8vP5WC5K5F8/bZY+4GK/n52ivx2SPMdm59V/eFG+DSl964d4RflE7Qk7ewZ2ZSTAw/GRcikoARoEyWkheEWFUpw2qqppWzetamWDlbkYNXtEcAFNnPptwpimnZT9L0cuQnRWmziks/nizWSkkzNPKb+CvFrbz+rj8KvVnUx06sRZMuvT8cmcvPO/Xsz39/f3fwAAAP//AwBL4gnFIgYAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSU227cNhCGX0XgtSjzfNCdYbeo66ZexIu06B3FGdlCtNKCojYNjH33gNoNEveud8JA/xy++YdvZAoHJC25PR5/OeGUF1KTPGwhwYShzFAm98y3zLaKNVo774z8h9RkeMSvpCVWxcijRyrRIFXANO1kHykAes44MKFVyRleFtK+kTA0gKchYjMvnzAtwzyRlvw1TDB/KbXD0MRxXqFJ84gP05LDFEszfz7cPdI/bnf7p93lrwWXIm4GIC1hRlsTtaARPFKljaEODVDFeARuQ+eZv8iGKWOawtgs8PlHfZjzhDm2ohGyYVR4cq4JhBxKy11YcP/1WLrYEN2XeL2Ft8/2jZwwkVbU32Fe0t3EcbjJ83HEE47HkBZMN3E+HMIEpCbHNB8x5QE3LNuk4xjyME/VtdjdOOCUSU2enqvdGHI/p8M7Vs8XBA//g8AJU0daIpmWxlpUUsrgTScYgjXRGNHFwGzfCeQRmfbKem4Zl14wL7WxzkJgPpKavIxzF8bfl42fF6xzwKwwAhV6oYzxkaF02GuLDIIxnXHRg3RWKAdOBh8C9x3a6E0sBvkQ4uswYfVwX6bhKEA6pL3ghioHgQYtPTVGmh559FZwUpO7ecrDtM7rUj1MGV/Sxo+05NcwLnghd5vi65Ax5jUVqH+bUmyXZlhjrn44gLOGNZKxIlrzcc3VR4QhYcxY8O7Tes33H4kwYhPdrSnhlKtdyK/Vb2F5LVSCizz4MqqJsUfNsGfAgmEW0IBBUAIsKK/AKM+iUaHjCoLmXV8ipCZYDFdtHu8tOGRBUs1YpAoDo05xT5V2PWjGRQB4x7F6GosuRMcUgqQee6DK80C9kpKC1MEK01sr+p+QXM3HWQEMeLpc69aBAXAIhlOhuKbKe06d15Z21nW+Mw51LD0/Yppw/AnUhyGmeZn7XF29W71D93GdyotTbT7+Mkz0321H93P8jKkqOw7DVA7sutZzTQ4YljXhYXuw2jeyK9dV7bd3S7hGeiZr8pxDyuvxGpa6Uc7r8/l8/gYAAP//AwBRUmUl9QQAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUTW/cRgyG/4owZ4083x+6GXaLLtzUi3jRBr2NhlQsRCstRqNNA2P/ezHaLRL3lptAiOQ7D1/yjUzhiKQl96fTL2ec8kJqkoctJJgwlBnK5IH5ltlWscYwY7jzf5OaDE/4jbTEqhh59EglGqQKmKad7CMFQM8ZBya0KjXD54W0byQMDeB5iNjMy5+YlmGeSEv+GiaYv5beYWjiOK/QpHnE3bTkMMUi5o/dwxP9/X5/eN5f/1pwKcnNAKQlzGhrohY0gkeqtDHUoQGqGI/Abeg889e0YcqYpjA2C3z53h/mPGGOrWiEbBgVnlxqAiGHIrkLCx6+nYqKDdFjiddbePts38gZE2lF/R/Ma7m7OA53y9qNeMbxFNKC6S7Ox2OYgNTklOYTpjzghuWMqZuXIReiMdrgHOfgglXagpNaSAuSIThmNXjwwSjTi6h1D53zVvUKBFdgUKnOkpps4MYx5GGeqpv2h3HAKZOaPL9U+zHkfk7Hd+hfrkR3PwG0yCYtkUxLYy0qKWXwphMMwZpojOhiYLbvBPKITHtlPbeMSy+Yl9pYZyEwH0lNPoT4OkxY7R5Ld44CpEPaC26ochBo0NJTY6TpkUdvBSc1eZinPEzrvC7Vbsr4OW3vJS35NYwLXl96n+LrkDHmNRUIn0wx4z7NsMZcfTcAZw1rJGMlac2nNVcfEYaEMWPBcUjrrd7/UoQRW9LDmhJOudqH/Fr9FpZX0hIfXOTBBx+CibFHzbBnwIJhFtCAQVACLCivwCjPolGh4wqC5l1fIqQmWPxWbRbnSoFzzFLJdEdVFxztugAUle95X4gqfMexeh5LXoiOKQRJPfZAleeBeiUlBamDFaa3VvQ/ILmZhbMCGPB8XdZNgQFwCIZTobimyntOndeWdtZ1vjMOdSyanzBNOP4A6sMQ07zMfa5uXqveofu4TuXgVJvvvg4T/Web0eMcv2CqyozDMJX9uo31UpMjhmVNeNzuVftG9mW5qsN2toRrpGeyJi85pLyebmGpG+W8vlwul38BAAD//wMAv7X+fPQEAAA=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUQW/cNhCF/4rAsyiTEkWJuhnrBF24qRfJIi16G3FGMWGZWpCUE8PY/15Qu0Hq3nohiAHf8PGbJ70xD8/EBnZ7On14IZ8iK1lyW6kWteZCc9EchRlENyhZCSN6bdq/WcncPb2ygXXKWmkN8YY0cYWi5WMzWY5IRgqJom5V7gnfIhveGLgK6cVZqpb4lUJ0i2cD+9N5XL7nu8FVdl5WrMIy097HBN5mM3/sd/f899vD8eFwORUpZnHlkA1M6LbTtq25RUNctVrznjRyJaRF2cFohLnInE8UPMxVxKdf9+OSPCU71FXdVILXhp1LhpAgWx4h0vH1lF1siO5yvdzK23Z4Yy8U2FCXP2Fe2t3Y2d08x3F1M95c1gTxKW7rBDYt4ZWV7BSWE4XkaONzGyM9j/PrEeLTx8uZvI0ffpBdE+FuWX3Kw9GsZBufeYbkFl9cLe5mRz6xkj18KQ4zpGkJz+8If7mA2/8Pbp/APjpPxf4uayTV2PTEp1pqrnoEDm1juNaNnkha09WSlWy3+OT8uqyx2PtE38Lmkg3sI8yRLv5ug310iWxaQ7b+l85JOYQFV5uKX9ORohJVI0QWrem0puIzoQtkE+VHHMN67fcfSa3rTbRbQyCfigOkx+I3iI9sYAZ6K8GAAdDWTtQKmgQK0KJD0qgJVY0dKqNQKyOsVjBKhdDKccoVVjLKYSi2/GndKTGS5K0G4GrsJj5aMfHWdL1RBJOqp3cci4c568D2QhE23NCEXBkJ3Kim4di00NV66rpN9xPJdcRSZMBIL5cv6eIAsSfUktdKtlwZI3lv2o6PXT+aUffU2uz5noKn+V+gPjkblrhMqbgmpHiH7vPq89+g2NLy3Xn+Y5vR3WKfKBR5xuB8Dv91rOfz+fwPAAAA//8DAIvqMrtUBAAA
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpRVTW/jNhD9KwKvtbT8kChRQA+p42yNNE4QG92itxE5itnIpEFR2U2D/PeCctIku+ihF4l6JGceH2eenoiDA5KWnB2Pqwd0cSQLEu0MccplTmVOxY6qltZtyQqqZCWr5k+yIPYSH0lL6lJrphXmAiXmpaFV3ole58agYpQZyqsyxYS7kbRPBGxh8MFqLPz4O4bRekda8sU647+m3GALPfjJFMEPuHZjBKcTmc16eZn/dnazu745rRpxTJsLa0hLqKxqqSuea6MwLysp8walyUvKtGE1dIqq0zbrIgYHQzGa+7f8xkeHUbe84KKgOVfkeUEMREiUOxhx93hMLGaJzhO+mOF52D6RBwyk5YtXMU/hPunBfjqM3WQH82l+kgU5Bn/EEC3OalxvszcSjBa04JJTShbkCvTeOszW59n1kI4IuqElGpEr7E1eKga5KoXIjaig5rKva96TBbnE4HB4F/XK6uBH38fsReTsQ57t2XLloBsw5biAYUSyIOtxG8EZGLzD1TfUUzzF2oUpTS+9i9ZNfhqztYt4F+Bl/nX/cgoBXcxuIO6zX2Hck5YoaDQDBQpAat1jRbGnhoKktUFpJJqSm9qUqjSyVFTLEjpWGqhY1yeELMgvScPtpDWO43u2qUqGYSaRvVzUcrDo4gcdU5kw5EY0mPecybxsDORQCZVLKWSPTKuas9c8Owh3GElL+qbrOqp1x0vFNHAFwvRUGNkrzusayl5UdcmlrGgN2tQ1Z6URNWoQvaANJwtyE7yZdPz+rsV8AzfB/4U6Jq1IS0RNgfPaMDBlUwnaNBxUVXZV00tpuh60VFphp/seRG1q7BrGhWS0Zo1Qsnmlv3J31uG5HY8DPL7L2xSyED9pgIb18KbqaflFgAN+9eF+c6rjYrPakQW5nVyyhGydauSrdfk3mVr6ahqi3e0DgkFz5Q3+WEiY+iWbW5R3otMaRF7XAvKyqkXeAYNcAAWtWc+rWapzr+8xZKnEwLrUVv8Gu95mZ0HvbUQdp5D4/THzuN5mNwPE3ofDByt5d7DvBSi4YDSlM/hwsqOZozSmQSNZzktW5aVSLG9UVedd3XSqkw1WOil2PcXjFLNbNDagjvOJX1rjAuwwBVxCxDsfkj9uVrvt+eUrneUe9f2POr0WyEv1MprKcHtyuPX/MLhVCD4s/ZR8vH3/tXa9z56ypT8c7YAh+zlbZFfjTOkzOgwwvIdWDzBMp356j746wYfdAY77GdjBeD8Ptub+Fkc/PGAYZ2CDcWvSHFtkm+kzxhl90+O0CKJ9wJ33g96DPeVYeoNnDobH0Z4i3cLf/kT+y7Gf32fjcfMS8Dru55Nlz8m9DwjjFPAw/9PaJ7J2DsOc83w6GdbaXdlhsCNq78xI2lKKQnBav1zVfy2reFOwiqvn5+fnfwAAAP//AwAe2YZzPwcAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpRTS2/cIBD+KxZn4wDG2PgWbVJ1laZZJau26g0z4yyKg1cY56Fo/3uFd6skvfWC0Ihv5nsMb8SbRyQtOd/vL5/Qx4nkJLqlJJhQlCnKyi3TLatbyQumy5JX4jfJibvCV9KSWlrLrUZaokIqgVW0K3tLAVBzxoGJSqae5n4i7RsxrgB8chaLcfqBYXKjJy356TyMz2m2cYUdxhmKMA649lM03iYy39erK/rtfLO92RxfTTglcOGAtISpqla2EtSCRiorpWiDCqhk3AKvTaeZPsKcjxi8GYoJHt7nwxg9RtuKQpQFo0KTQ07ARJMod2bC7es+sVgsukj1fCkv1/aNPGEgrcj/mnlsd2YHd/Y4dbMb4Ox4RjM9JJX7MO4xRIeLJ4vMYTDRjT47TVoNDn0kObm5yzaDif0YHj8ZdXfUv/4P+ds0/fIF7RwRVuPsY0pZkZxcG7tzHrP1RerGUUDZIO0FV1Q2YKipSk2VKlWP3OpacJKT1eij8/M4T9naR7wPC3/Ski9mmPDI/DzYnYto4xySqF8qrcImjDDbmL3bz1nBipKxBJrjfo7ZLYILaCMmedswn/r9AxFKLKDVHAL6mG1M3GVfzbQjLdGmsdxoo41R1vZYMewZMKNYDahAIUgBNUgtQUnNrJKm4xJMxbs+VUhOMKWdLQsmUKtai55aoSWVVc9op3RNe1tWsuF13WjxycfsZkg4YxsmEUqqsQcqNTdUy7KkUFamFqqva9F/sOQUPmfJYMCn41dZGCiABkFxKiSvqNSa00ZXNe3qptOdarCyifMVBo/DB6OunQ3jNPYxO+1O9sm629mn754te/TsPH1ZMroY7QOGLGVsnE/bfYr1cDgc/gAAAP//AwB2v0bKNQQAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUTW/cRgyG/4owZ408X5oP3Qy7RQ039SI20qI3akjFQrTSYjTaNDD834vROkjcW28CIXJePnzJFzbDkVjHrk+nX84055XVLI97SAllubBc6CcROik65RobWum8/ZvVbLynb6xjzsQoYyCuyRI3KFre6yFyRApSSBSqNaUmfF5Z98JgbJDOY6RmWT9RWsdlZh37c5xx+VrehrGJ07Jhk5aJ7uY1wxyLmD/ubu7579eHp4fD5a+V1pLcjMg65sHbaAC56annRvSKgzaCezkMXrbGKxCXtHHOlGaYmhW//HgflzxTjp1qlG4EV4G91gwhQ5Hcw0pP305FxY7otsTrPbx/di/sTIl1qv4O81LuKk7j1br1E51pOkFaKV3F5XiEGVnNTmk5Ucoj7VjOlPplHXMhGqMD76VED860Dr1ulXaoBaEXrsWAAayxg4ptO2DvgzODQSUNWjKmd6xmO7hpgjwuc/Wm/WYaac6sZg+P1WGCPCzp+A7944Xo3f8AWmSzjmnRauscGa01BNsrQehstFb1EYQbekUykmiDcUE6IXVQIujWOu8QRIisZh8gPo8zVXe3rGNCkkLtiQ9KWm48AodWB26ttgPJGJySrGY3y5zHeVu2tbqbM31Oe7+sY7/CtNKl0+sUn8dMMW+pQPjLFjMe0oJbzNUPA0jRiEaL0tPDlk9brj4SjolipoLjKW1v9f6Toqzak262lGjO1QHyc/UbrM+sYwF8lBAgANgYB2oFDQIFWOGQLFpCo9ChCQatCSJaA700CK3shxJhNaPit2q3uNRWuwiKg5GSm6h67i0Al85q3WOMPbp3HKuHqeRB9MIQah5oQG6CBB6M1hx1C07ZwTk1/ITkzSxSFMBI58uy7gosoie0kisjW25CkNyH1vHe+T701lMbi+Z7SjNNP4H6MMa0rMuQqzevVe/QfdzmcnCq3Xdfx5n/s8/odolfKFVlxjDOZb/exvpasyPBuiU67veqe2GHslzV0362tGyEsG3NHjOkvJ2+h0MjbWhfX19f/wUAAP//AwCh5ahd9AQAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUwW7jNhCGX0XgWVQoiqJE3VKnixrZbIyNuy16G5Ejh4hMGhSVbRD43ReUHcTZRQ+9CSPOzD/f/OQrcbBH0pHrw+H3Z3RxIjmJdglxxiVlkrJqy1RXso43RcMV56z5h+TE3uIL6UgjtC61QlqhRCoMq2lfDZoag6pkpWG8Fqkm7CbSvRKwhcFnq7Hw0zcMk/WOdOQv64z/nnqDLfToZ1MEP+LaTRGcTmK+rFe39PP1Znu/OZ2acErJhTWkIy20UgswVPTYU8F6TqESjLblMLRlLVoO7JRmXcTgYCwm8/Te3/joMOqOF7wqGOWKHHNiIEKS3MOE25dDUrEguknxfAkvn90recZAOp6/wTyVu9KjvdpP/WxHczX63c663cq7we7mADE1zskh+AOGaHGB85t1EF4++90u1SOfYJyQ5GSLYW8djKcfNzjAPMYHP4eFzGSe/usM6QjM0ZOcLCTHcWmbnYdZjRZd/CX3ovH9Q7YZIQ4+7D8s6eHEfv0/0N+BfrQOs/UN6QgrkZuqRTrwUlLRGqBQV4pKWckBS60aXpKcrLyL1s1+nrK1i7g7U/ug7zroRxtRxzmkmf6WyWyb4M2sY/a+4JIVrKhYUnI/x8Mcs69obEAdMQ2xDfO53k8pXPIl6ZMd8Rc8qzkEdDHbQHzM/oDpkXREQatLUKAApNYD1gwHZhhI1hiURqIR3DRGKGGkUExLAX0pDNRlP6QIyQkmk2WLr43UdTm0FW1YX1GhuKSgeqBYNaYyqGrZfISb3Y8pD3TLBJqKKhwMFaoEqkRVUVPV0HA5NA0fLjidDVGyRP3ShH9OaM5e+nKy9tvsBp9P93jRKY1p0ciSclHWVChV0lbVDe2btle9bLHWabKVd5N/A/kNQ+8nG9Mjcmed3cP485H3zdxicDhebOfO6uAnP8TsbMvsw76+zi69Ytli0e/W0X8XY9x4/YQhS8YC6y6WeTwejz8AAAD//wMABJlj+QwFAAA=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUTW/kNgyG/4qhs+Xoy/rwLUhaNE23GWwGbdEbLdGJsR55IMuzXQTz3xfyTLBNb70ZhF+SeviSbyTCAUlHbo/Hn04Y80JqksctJJjQlGnK5J65jrNOmEYrq6Wxf5OajI/4jXTEKO+5d0glaqQqsJb2cvA0BHSc8cBEq0pOeFlI90ZgbAKeRo/NvPyBaRnnSDry5xjD/LXUhrHx07yGJs0TPsQlQ/Slmd8f7h7pb7e7/dPu8teCSxE3YyAdsWC1VxCo6rGnivWCglSMWj4MlrfKCmAX2RgzpghTs4QvP+qHOUfMvhONkA2jwpFzTQJkKC33sOD+27F0sSG6L/F6C2+f3Rs5YSKdqN9hXtLd+Gm8yfNxwhNOR0gLphs/Hw4QA6nJMc1HTHnEDcv20mmCPM6xuha7m0aMmdTk6bnaTZCHOR0+sHq+IHj4HwROmHrSEclaqY1BJaUEp3vBMBjttRa9B2aGXiD3yFqnjOOGcekEc7LVxpoAzHlSk5dp7mH6ddn4OcF6G5gRWqBCJ5TWzjOUFofWIAugda+td0FaI5QNVoID4K5H4532xSCfwL+OEauHe9IRxlEEaZEOgmuqbAAKrXRUa6kH5N4ZwUlN7uaYx7jO61I9xIwvaeNHOvIzTAteyN0m/zpm9HlNBepfuhTbpTmsPlc/HMBZwxrJCqOnNR/XXH3GMCb0GQvefVqv+f4jEVpsors1JYy52kF+rX6B5bVQAes5uPJU7f2ALcOBBQaamYA6aAxKBBOUU0Erx7xW0HMVoOX9UCKkJlgMV20ex4IU5EAtKk5VKxi1zGqqHfOSYVDKDR84Vk9T0YG3TGGQ1OEQqHIcqFNS0iBbMEIPxoiie0dyNR9nBXDA02Vbtw50CBaD5lQo3lLlHKfWtYb2xvau1xZbX3p+xBRx+heoT6NP8zIPubp6t/qA7vMay8WpNh9/HSP9Z5vR/ey/YKrKjGGMZcGuYz3X5ICwrAkP28Hq3siubFe13+6W5A1juq3Jc4aU1+N72DVcu/Z8Pp+/AwAA//8DANkq8Dj1BAAA
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSTwW7cOAyGX8XQ2XIkWZYt34JJFzvIthm0g+5ib7RIN0IceSDLaYtg3r2QZ4o2e9uLIBAi+f8fqVcW4JlYz25Pp3cvFNLCSpb8FlJCGS4MF/VR2F6KXnVVq422TfsvK5m/p++sZ612TjpLvCZDXKNo+FCPjiOSlUKiUI3ONeHLwvpXBr5CevGOqnn5THHxc2A9+9sHnL/m3uArN80rVnGeaB+WBMFlMR/2u3v+1+3h+HC4vFpoycmVR9azDjrjNCDXAw1ci0FxqLXgnRzHTja6UyAuaT4kigGmasGnX/1xToGS61Wl6kpwZdm5ZAgJsuQBFjp+P2UVG6K7HC+38HbtX9kLRdar8ifMS7kbN/mb52VY/YQ3lzPB8pRdnuJ8opg8bUw2m9MEyc+huHbaTZ5CYiV7+FQcJkjjHJ/fgPp08b//H/aPufu7b+TWRLib15BYz2TdsZK9B/foAxX7O9YzIUlh3REflTRcdwgcmtpyY2ozknS2VZKVbDeH5MM6r0uxD4m+xM0A69kfMC10kX4b3aNP5NIas6t/TN6FQ5xxdan4xV+KSlS1yCIf1nRaU/GR0EdyibK/Y1yv9f6ToozaknZrjBRScYD0WPwJyyPrmYXOSbBgAYxzIzWCRoECjGiRDBpCrbBFbTUabYUzGgapERo5jDnCSkZ53MW2YUPbDqMQLVfgGq4zHWix49hJa9DV1I1vORYPU84D1wlNWHNLI3JtJXCr65pj3UCrzNi2avwNyXX6UmTASC+Xv7IpMIgdoZFcadlwba3knW1aPrTdYAfTUeOy5nuKgabfQL33Ls7LPKbiujzFG3Qf15D/e7Et0lcf+LdtRneze6JY5BmDD3m9r2M9n8/nHwAAAP//AwD5p65GNgQAAA==
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACoxUS2/bOBD+KwLPpkJS1IMC9mA4LWqkaYzE3V30RpHDmIgsGhTlNAj83xeU5NopetibMJrX9xi+o07uAdVoeTh8OkIXerRAwY4hRliBSYFJtiWipqRmVUrzSgia/0ALZO/gDdWo5EpRJQBnUADmmuS4yYzCWoOghGrCch57yuce1e9I2lTD0SpIXf83+N66DtXoH9tp9xpnS5uq1g069a6FddcH2am4zLf16g5/XW62D5spq4c+FqdWoxpVsioUlxrzBhrMScOwzDjBFTWmojmvmCRTme0C+E62aa9fLvO1Cx0EVbOUZSnBTKDTAmkZZFy5kT1s3w5xi5Gi2xhfjOHxs35HR/CoZoszmVO7G9Xam33fDLbVN0H6ZwjGyz28Ov8CR9miBTp4dwAfLIzcPDwll5UoSUnKCkbi4vdS7WwHyfo2eWgjYKkqwkFnWIDRmAsqseBZhnWWy5IVpiyZQQt0B76D9qrrvVXe9c6EZKY8+TBn5bpgu8ENfbLuAjx7Gaa6z7LtAS3QZmha2+8eQeq3rXsc4r9uaCOW1eA9dCHZyLBLvsh+h2okZKWoFFJIWShlICdgiCayIKWGQhegOdOl5oLrgguiCi4byrXMaWNiBC3QwxAOQzjz//Nqia23+z3oywbbkeNNK4Nxfr/W0AVrbJTmnDEaqm1HVMncc9Va6MIHklGNCAWmswqwYbTAvNISyzwTuCiywgBVomR0IszY5+EXT8QYzTOTV1XRiIYSYKasOClNQ7QymRI6b6BkJSkrqIQipMk5rRqhiAaacx3ReacHFX63QjYK9Dh08TqTdYT9ajv8s+AXRjbeBadcGwWzLTy99QH2f1Jt5fYH19sQ8ZtZ2u893Lsu/p3vf+ZsLl66cIlBvINkPD3FlWImp1jSTGGuhMSSEIEBKNECJMlVlPHWqRfwSTSYtN2oydlTD0/J0qudDaDC4OPkf0dQk5yfzydz4SP99mm7ch6Wh8Nijv51jCRNzc4G+PCufO9j+s714QryDO0JWnNe7MpOGo7TU2VjsNC6Al1QzDjNMReC4krkJW7KqhFNUcGEc7Jr8gjaelBh7Lf1Q5w2M/snXy59sEaq0Mfj+erUaKfZn3PK70teyfarehp+Jd1spbkTJdGyT9PDOTrof72bp9Pp9B8AAAD//wMAqlPlEigGAAA=
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACpSUXW/cKhCG/4rFtXH4MgbfRZtWZ5XTZtWu2qp3GMYNioNXgNNG0f73CnurNFdH5wahMTO888yLX1Awj4B6dH06vXuCkBOqUfZriBEmMZGY8CPRPSU9U00nuOKafUc18rfwjHrUCWup1YA5SMDCkRYPfLTYOdCUUEdYK0pN8yOh/gUZ3zh48haaOX2BmPwcUI+++uDmn+Vu4xs7zYtr4jzBPqRsgi1iPu53t/jf68Px7rCdSpBKcuMd6pEySlphHBYDDFiQgWHDBcGKjqOirVDMkC3NhwwxmKlJ7uH1fjfnANn2rGG8IZhpdK6RM9kUyYNJcHw+FRUropsSr9fwuu1f0BNE1LP6D8yt3JWd/NVjGhY/uattzSY9pHUdjc1zfEY1OsX5BDF7WPlcpwSPw/R8NOnh/XambNO7X2CXDG43LyGjHlHeohqtgKbJZD+H6qJxN3kIef2Yow/J2/+qxVGN7j5Xh8nkcY6Pb+bxecO8/x+UPxh77wNU+xvUI0KBOa4Aj4xKLJQz2LRcYym5HIFa3TGKarSbQ/ZhmZdU7UOGH3FtCfXovZkSbPquo733GWxeYunzmyy+OsTZLTZXr7OkpCENJ0XJ3ZJPS64+gfMRbIbSxDEul3pf3qYwydak3RIjhFwdTL6v/jHpHvVIG2Wp0UYbI60doSUwEkeMJJ0D6SQ4wVznhBZOCk2sFGagwpmWDmOJoBpBsU61utV2rCVikJirocOiHThWrpXYqlFyqkZGSWHyyrG6m0qesYoIcBxrGB0WmhqsBefY8dZ0TI5dx8a/kFz8sBVz8LS9u1WBdE6BkxQzQVsstKZY6bbDQ6cGPUgFrS2abyEGmP4C9cHbOKd5zNXFIdUbdJ+WUP4d1eqWnz7gX+uMbmb7ALEqMzY+lKdyGev5fD7/BgAA//8DAG6oGh2CBAAA
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
https://dc.services.visualstudio.com/v2/track
|
||||||
|
Content-Type:application/x-json-stream
|
||||||
|
Content-Encoding:gzip
|
||||||
|
|
||||||
|
H4sIAAAAAAAACoxUy27kNhD8FYHXiDJfokjdHNuLDBw/sDNIgtxaZMtmLFMDirJ3YfjfA2ns9WMRIBdBaJJd1dXV/UQi3CNpyfF+f/aAMU+kJDmsIcGEpkxTJnfMtpy1wlRNzWwt+N+kJOEcv5OWNMo57ixSiRqp8qymnewd9R4tZ9wzUaslJ9xMpH0iECqPD8FhNU5/YJrCGElL/gzRj48LNoTKDePsqzQOuIlThugWMpebk3P6+/H17ur6cGvCaXlcBU9aYsBop8BT1WFHFesEBakYNbzvDa+VEcAOz0LMmCIM1eTv3vD9mCNm14pKyIpRYclzSTxkWCh3MOHu+35hsUp0usTLNbz+tk/kARNpRfkq5iHdkRvC0f3UzWHwR+uXlGSfxj2mHHBV42pbvJHgrGKV0IItVC/A3YaIxea0uBqWEsEZptBLarH3VFkO1CopqZc1NEL3TSN6UpJzTBGHd1kvgkvjNPa5eBG5+ICzPT45i9ANuGB8gWFCUpLNtM0QPQxjxLNv6OZ8yLVL83J8MsYc4jzOU7GJGW8SvJy/vj+ZU8KYi2vIt8VvMN2SllgwjoMFC6Cd67Fm2DPPQLPGo/YavRK+8coqr5VlTivouPJQ865fIqQkvy4abmfncJre2KwmGYaVQ/HSp5MhYMwfZCQtYRyFlwZpL7imynigUEtLtZa6R+5sI/grzA7SDWbSkt50Xcec64Sy3IGwIH3PpNe9FaJpQPWybpTQumYNON80gisvG3Qge8mMICW5TqOfXf7cark24DqN/6DLi1SkJZrVtXHQdUIrbsAaVFwroy02VvXAlHQd8NpA13EGNXPWCAdcW1Cdr/sfKp3FmxDxNEz7Ab6/wzWVruQvDsDwHtSn618S3OPjmO4uDzauLs92pCRf57hshGKzWOQxRPpNLxN9MQ857G4Tgkd/MXr82Ue4jEuxTihzxmrtBXW6Bqp0banltaK175VBY503DSnJ6ejuMBWLwyDEZap+JLvaFsfJ3YaMLs9p4ffXyuNqW1wPkPsx3X/YJO8K+yxAJSRnS2c8Phy20cpRe2/Qa06F4jVV1nJqbN3QrjGd7bTB2i2KXc15P+fiK/qQ0OW14hcvrpgnt+jufhbj1QUvFuVs8dr2sMVWaf/XEnsuyT3CNCe8X7d1+0Q2MWJakU/nwyhu4kUYhjChG6OfSMuZZJU0jXxh+N/3rKxs3Zjn5+fnfwEAAP//AwCrQngFGwYAAA==
|
||||||
File diff suppressed because one or more lines are too long
28
.appdata/SqlRunner/Program.cs
Normal file
28
.appdata/SqlRunner/Program.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using Microsoft.Data.SqlClient;
|
||||||
|
|
||||||
|
var connectionString = "Server=localhost;Database=PlotLine;User Id=PlotLineApp;Password=t6eb1cvd9bNB27czde#h9r;MultipleActiveResultSets=true;Encrypt=false;";
|
||||||
|
var scriptPath = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "..", "PlotLine", "Sql", "026_TimelineConfigurationSettings.sql"));
|
||||||
|
var script = await File.ReadAllTextAsync(scriptPath);
|
||||||
|
var batches = Regex.Split(script, @"^\s*GO\s*$", RegexOptions.Multiline | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
await using var connection = new SqlConnection(connectionString);
|
||||||
|
await connection.OpenAsync();
|
||||||
|
|
||||||
|
var count = 0;
|
||||||
|
foreach (var batch in batches)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(batch))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await using var command = new SqlCommand(batch, connection);
|
||||||
|
command.CommandTimeout = 120;
|
||||||
|
await command.ExecuteNonQueryAsync();
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine($"Applied {count} SQL batches.");
|
||||||
14
.appdata/SqlRunner/SqlRunner.csproj
Normal file
14
.appdata/SqlRunner/SqlRunner.csproj
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\PlotLine\PlotLine.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -8,78 +8,44 @@
|
|||||||
".NETCoreApp,Version=v10.0": {
|
".NETCoreApp,Version=v10.0": {
|
||||||
"PlotLine/1.0.0": {
|
"PlotLine/1.0.0": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Dapper": "2.1.66",
|
"Dapper": "2.1.79",
|
||||||
"Microsoft.Data.SqlClient": "6.1.3"
|
"Microsoft.Data.SqlClient": "7.0.1"
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"PlotLine.dll": {}
|
"PlotLine.dll": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Azure.Core/1.47.1": {
|
"Dapper/2.1.79": {
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.Bcl.AsyncInterfaces": "8.0.0",
|
|
||||||
"System.ClientModel": "1.5.1",
|
|
||||||
"System.Memory.Data": "8.0.1"
|
|
||||||
},
|
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net8.0/Azure.Core.dll": {
|
"lib/net10.0/Dapper.dll": {
|
||||||
"assemblyVersion": "1.47.1.0",
|
|
||||||
"fileVersion": "1.4700.125.36505"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Azure.Identity/1.14.2": {
|
|
||||||
"dependencies": {
|
|
||||||
"Azure.Core": "1.47.1",
|
|
||||||
"Microsoft.Identity.Client": "4.73.1",
|
|
||||||
"Microsoft.Identity.Client.Extensions.Msal": "4.73.1"
|
|
||||||
},
|
|
||||||
"runtime": {
|
|
||||||
"lib/net8.0/Azure.Identity.dll": {
|
|
||||||
"assemblyVersion": "1.14.2.0",
|
|
||||||
"fileVersion": "1.1400.225.36004"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Dapper/2.1.66": {
|
|
||||||
"runtime": {
|
|
||||||
"lib/net8.0/Dapper.dll": {
|
|
||||||
"assemblyVersion": "2.0.0.0",
|
"assemblyVersion": "2.0.0.0",
|
||||||
"fileVersion": "2.1.66.48463"
|
"fileVersion": "2.1.79.29349"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.Bcl.AsyncInterfaces/8.0.0": {
|
"Microsoft.Bcl.Cryptography/9.0.13": {
|
||||||
"runtime": {
|
|
||||||
"lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll": {
|
|
||||||
"assemblyVersion": "8.0.0.0",
|
|
||||||
"fileVersion": "8.0.23.53103"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Microsoft.Bcl.Cryptography/9.0.4": {
|
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net9.0/Microsoft.Bcl.Cryptography.dll": {
|
"lib/net9.0/Microsoft.Bcl.Cryptography.dll": {
|
||||||
"assemblyVersion": "9.0.0.4",
|
"assemblyVersion": "9.0.0.13",
|
||||||
"fileVersion": "9.0.425.16305"
|
"fileVersion": "9.0.1326.6317"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.Data.SqlClient/6.1.3": {
|
"Microsoft.Data.SqlClient/7.0.1": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Azure.Core": "1.47.1",
|
"Microsoft.Bcl.Cryptography": "9.0.13",
|
||||||
"Azure.Identity": "1.14.2",
|
"Microsoft.Data.SqlClient.Extensions.Abstractions": "1.0.0",
|
||||||
"Microsoft.Bcl.Cryptography": "9.0.4",
|
"Microsoft.Data.SqlClient.Internal.Logging": "1.0.0",
|
||||||
"Microsoft.Data.SqlClient.SNI.runtime": "6.0.2",
|
"Microsoft.Data.SqlClient.SNI.runtime": "6.0.2",
|
||||||
"Microsoft.IdentityModel.JsonWebTokens": "7.7.1",
|
"Microsoft.IdentityModel.JsonWebTokens": "8.16.0",
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "7.7.1",
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "8.16.0",
|
||||||
"Microsoft.SqlServer.Server": "1.0.0",
|
"Microsoft.SqlServer.Server": "1.0.0",
|
||||||
"System.Configuration.ConfigurationManager": "9.0.4"
|
"System.Configuration.ConfigurationManager": "9.0.13"
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net9.0/Microsoft.Data.SqlClient.dll": {
|
"lib/net9.0/Microsoft.Data.SqlClient.dll": {
|
||||||
"assemblyVersion": "6.0.0.0",
|
"assemblyVersion": "7.0.0.0",
|
||||||
"fileVersion": "6.13.25316.3"
|
"fileVersion": "7.0.1.26114"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"resources": {
|
"resources": {
|
||||||
@ -127,14 +93,33 @@
|
|||||||
"runtimes/unix/lib/net9.0/Microsoft.Data.SqlClient.dll": {
|
"runtimes/unix/lib/net9.0/Microsoft.Data.SqlClient.dll": {
|
||||||
"rid": "unix",
|
"rid": "unix",
|
||||||
"assetType": "runtime",
|
"assetType": "runtime",
|
||||||
"assemblyVersion": "6.0.0.0",
|
"assemblyVersion": "7.0.0.0",
|
||||||
"fileVersion": "6.13.25316.3"
|
"fileVersion": "7.0.1.26114"
|
||||||
},
|
},
|
||||||
"runtimes/win/lib/net9.0/Microsoft.Data.SqlClient.dll": {
|
"runtimes/win/lib/net9.0/Microsoft.Data.SqlClient.dll": {
|
||||||
"rid": "win",
|
"rid": "win",
|
||||||
"assetType": "runtime",
|
"assetType": "runtime",
|
||||||
"assemblyVersion": "6.0.0.0",
|
"assemblyVersion": "7.0.0.0",
|
||||||
"fileVersion": "6.13.25316.3"
|
"fileVersion": "7.0.1.26114"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Data.SqlClient.Extensions.Abstractions/1.0.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.Data.SqlClient.Internal.Logging": "1.0.0"
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/Microsoft.Data.SqlClient.Extensions.Abstractions.dll": {
|
||||||
|
"assemblyVersion": "1.0.0.0",
|
||||||
|
"fileVersion": "1.0.0.26076"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.Data.SqlClient.Internal.Logging/1.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/Microsoft.Data.SqlClient.Internal.Logging.dll": {
|
||||||
|
"assemblyVersion": "1.0.0.0",
|
||||||
|
"fileVersion": "1.0.0.26076"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -157,90 +142,67 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.Identity.Client/4.73.1": {
|
"Microsoft.IdentityModel.Abstractions/8.16.0": {
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.IdentityModel.Abstractions": "7.7.1"
|
|
||||||
},
|
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net8.0/Microsoft.Identity.Client.dll": {
|
"lib/net10.0/Microsoft.IdentityModel.Abstractions.dll": {
|
||||||
"assemblyVersion": "4.73.1.0",
|
"assemblyVersion": "8.16.0.0",
|
||||||
"fileVersion": "4.73.1.0"
|
"fileVersion": "8.16.0.26043"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.Identity.Client.Extensions.Msal/4.73.1": {
|
"Microsoft.IdentityModel.JsonWebTokens/8.16.0": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.Identity.Client": "4.73.1",
|
"Microsoft.IdentityModel.Tokens": "8.16.0"
|
||||||
"System.Security.Cryptography.ProtectedData": "9.0.4"
|
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net8.0/Microsoft.Identity.Client.Extensions.Msal.dll": {
|
"lib/net10.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
|
||||||
"assemblyVersion": "4.73.1.0",
|
"assemblyVersion": "8.16.0.0",
|
||||||
"fileVersion": "4.73.1.0"
|
"fileVersion": "8.16.0.26043"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.IdentityModel.Abstractions/7.7.1": {
|
"Microsoft.IdentityModel.Logging/8.16.0": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.IdentityModel.Abstractions": "8.16.0"
|
||||||
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net8.0/Microsoft.IdentityModel.Abstractions.dll": {
|
"lib/net10.0/Microsoft.IdentityModel.Logging.dll": {
|
||||||
"assemblyVersion": "7.7.1.0",
|
"assemblyVersion": "8.16.0.0",
|
||||||
"fileVersion": "7.7.1.50719"
|
"fileVersion": "8.16.0.26043"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.IdentityModel.JsonWebTokens/7.7.1": {
|
"Microsoft.IdentityModel.Protocols/8.16.0": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Tokens": "7.7.1"
|
"Microsoft.IdentityModel.Tokens": "8.16.0"
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
|
"lib/net10.0/Microsoft.IdentityModel.Protocols.dll": {
|
||||||
"assemblyVersion": "7.7.1.0",
|
"assemblyVersion": "8.16.0.0",
|
||||||
"fileVersion": "7.7.1.50719"
|
"fileVersion": "8.16.0.26043"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.IdentityModel.Logging/7.7.1": {
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect/8.16.0": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Abstractions": "7.7.1"
|
"Microsoft.IdentityModel.Protocols": "8.16.0",
|
||||||
|
"System.IdentityModel.Tokens.Jwt": "8.16.0"
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net8.0/Microsoft.IdentityModel.Logging.dll": {
|
"lib/net10.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll": {
|
||||||
"assemblyVersion": "7.7.1.0",
|
"assemblyVersion": "8.16.0.0",
|
||||||
"fileVersion": "7.7.1.50719"
|
"fileVersion": "8.16.0.26043"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.IdentityModel.Protocols/7.7.1": {
|
"Microsoft.IdentityModel.Tokens/8.16.0": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.Tokens": "7.7.1"
|
"Microsoft.IdentityModel.Logging": "8.16.0"
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net8.0/Microsoft.IdentityModel.Protocols.dll": {
|
"lib/net10.0/Microsoft.IdentityModel.Tokens.dll": {
|
||||||
"assemblyVersion": "7.7.1.0",
|
"assemblyVersion": "8.16.0.0",
|
||||||
"fileVersion": "7.7.1.50719"
|
"fileVersion": "8.16.0.26043"
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect/7.7.1": {
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.IdentityModel.Protocols": "7.7.1",
|
|
||||||
"System.IdentityModel.Tokens.Jwt": "7.7.1"
|
|
||||||
},
|
|
||||||
"runtime": {
|
|
||||||
"lib/net8.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll": {
|
|
||||||
"assemblyVersion": "7.7.1.0",
|
|
||||||
"fileVersion": "7.7.1.50719"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Microsoft.IdentityModel.Tokens/7.7.1": {
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.IdentityModel.Logging": "7.7.1"
|
|
||||||
},
|
|
||||||
"runtime": {
|
|
||||||
"lib/net8.0/Microsoft.IdentityModel.Tokens.dll": {
|
|
||||||
"assemblyVersion": "7.7.1.0",
|
|
||||||
"fileVersion": "7.7.1.50719"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -252,53 +214,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"System.ClientModel/1.5.1": {
|
"System.Configuration.ConfigurationManager/9.0.13": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"System.Memory.Data": "8.0.1"
|
"System.Security.Cryptography.ProtectedData": "9.0.13"
|
||||||
},
|
|
||||||
"runtime": {
|
|
||||||
"lib/net8.0/System.ClientModel.dll": {
|
|
||||||
"assemblyVersion": "1.5.1.0",
|
|
||||||
"fileVersion": "1.500.125.36405"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Configuration.ConfigurationManager/9.0.4": {
|
|
||||||
"dependencies": {
|
|
||||||
"System.Security.Cryptography.ProtectedData": "9.0.4"
|
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net9.0/System.Configuration.ConfigurationManager.dll": {
|
"lib/net9.0/System.Configuration.ConfigurationManager.dll": {
|
||||||
"assemblyVersion": "9.0.0.0",
|
"assemblyVersion": "9.0.0.0",
|
||||||
"fileVersion": "9.0.425.16305"
|
"fileVersion": "9.0.1326.6317"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"System.IdentityModel.Tokens.Jwt/7.7.1": {
|
"System.IdentityModel.Tokens.Jwt/8.16.0": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.IdentityModel.JsonWebTokens": "7.7.1",
|
"Microsoft.IdentityModel.JsonWebTokens": "8.16.0",
|
||||||
"Microsoft.IdentityModel.Tokens": "7.7.1"
|
"Microsoft.IdentityModel.Tokens": "8.16.0"
|
||||||
},
|
},
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net8.0/System.IdentityModel.Tokens.Jwt.dll": {
|
"lib/net10.0/System.IdentityModel.Tokens.Jwt.dll": {
|
||||||
"assemblyVersion": "7.7.1.0",
|
"assemblyVersion": "8.16.0.0",
|
||||||
"fileVersion": "7.7.1.50719"
|
"fileVersion": "8.16.0.26043"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"System.Memory.Data/8.0.1": {
|
"System.Security.Cryptography.ProtectedData/9.0.13": {
|
||||||
"runtime": {
|
|
||||||
"lib/net8.0/System.Memory.Data.dll": {
|
|
||||||
"assemblyVersion": "8.0.0.1",
|
|
||||||
"fileVersion": "8.0.1024.46610"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Security.Cryptography.ProtectedData/9.0.4": {
|
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"lib/net9.0/System.Security.Cryptography.ProtectedData.dll": {
|
"lib/net9.0/System.Security.Cryptography.ProtectedData.dll": {
|
||||||
"assemblyVersion": "9.0.0.0",
|
"assemblyVersion": "9.0.0.0",
|
||||||
"fileVersion": "9.0.425.16305"
|
"fileVersion": "9.0.1326.6317"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,47 +253,40 @@
|
|||||||
"serviceable": false,
|
"serviceable": false,
|
||||||
"sha512": ""
|
"sha512": ""
|
||||||
},
|
},
|
||||||
"Azure.Core/1.47.1": {
|
"Dapper/2.1.79": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-oPcncSsDHuxB8SC522z47xbp2+ttkcKv2YZ90KXhRKN0YQd2+7l1UURT9EBzUNEXtkLZUOAB5xbByMTrYRh3yA==",
|
"sha512": "sha512-8YijbzgTfmqmQOnVNorYM6K++pxqnW3nJ4aC1sRHzxUA2CcuoJ9gsTem3kgBnPRMc38zZHl4Esb6hAezXIEEuw==",
|
||||||
"path": "azure.core/1.47.1",
|
"path": "dapper/2.1.79",
|
||||||
"hashPath": "azure.core.1.47.1.nupkg.sha512"
|
"hashPath": "dapper.2.1.79.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Azure.Identity/1.14.2": {
|
"Microsoft.Bcl.Cryptography/9.0.13": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-YhNMwOTwT+I2wIcJKSdP0ADyB2aK+JaYWZxO8LSRDm5w77LFr0ykR9xmt2ZV5T1gaI7xU6iNFIh/yW1dAlpddQ==",
|
"sha512": "sha512-5T+bH3Lb1nEe8Hf/ixMxLmhlrx5wRi53wv7OhVwG2F1ZviW1ejFRS1NHur3uqPpJRGtkQwUchtY6zhVK2R+v+w==",
|
||||||
"path": "azure.identity/1.14.2",
|
"path": "microsoft.bcl.cryptography/9.0.13",
|
||||||
"hashPath": "azure.identity.1.14.2.nupkg.sha512"
|
"hashPath": "microsoft.bcl.cryptography.9.0.13.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Dapper/2.1.66": {
|
"Microsoft.Data.SqlClient/7.0.1": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-/q77jUgDOS+bzkmk3Vy9SiWMaetTw+NOoPAV0xPBsGVAyljd5S6P+4RUW7R3ZUGGr9lDRyPKgAMj2UAOwvqZYw==",
|
"sha512": "sha512-9jZFXAJ2ThNYK7lhj2RhH7klXVNaWSvZpQncq3bPIOjmHBrdjwgeO4c8wucUVxQwFT8rAA13Z2F2jzoYR7ICDw==",
|
||||||
"path": "dapper/2.1.66",
|
"path": "microsoft.data.sqlclient/7.0.1",
|
||||||
"hashPath": "dapper.2.1.66.nupkg.sha512"
|
"hashPath": "microsoft.data.sqlclient.7.0.1.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Microsoft.Bcl.AsyncInterfaces/8.0.0": {
|
"Microsoft.Data.SqlClient.Extensions.Abstractions/1.0.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==",
|
"sha512": "sha512-rlnxc0KfwDSbE8ZHntFnl8SCgOa9QtJZblMv2zXLhRwl1Je7fsdsVzxSjzzC4JMsfAK+jXJWyezRB8SxUY4BdA==",
|
||||||
"path": "microsoft.bcl.asyncinterfaces/8.0.0",
|
"path": "microsoft.data.sqlclient.extensions.abstractions/1.0.0",
|
||||||
"hashPath": "microsoft.bcl.asyncinterfaces.8.0.0.nupkg.sha512"
|
"hashPath": "microsoft.data.sqlclient.extensions.abstractions.1.0.0.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Microsoft.Bcl.Cryptography/9.0.4": {
|
"Microsoft.Data.SqlClient.Internal.Logging/1.0.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-YgZYAWzyNuPVtPq6WNm0bqOWNjYaWgl5mBWTGZyNoXitYBUYSp6iUB9AwK0V1mo793qRJUXz2t6UZrWITZSvuQ==",
|
"sha512": "sha512-Kue/7CF8KNT9zozfr30C94dMZVZml3atqWZvQemSXvTau76tRdypzeKiBKXadqgbOME0UiQIyVTNo5WxCRNVNg==",
|
||||||
"path": "microsoft.bcl.cryptography/9.0.4",
|
"path": "microsoft.data.sqlclient.internal.logging/1.0.0",
|
||||||
"hashPath": "microsoft.bcl.cryptography.9.0.4.nupkg.sha512"
|
"hashPath": "microsoft.data.sqlclient.internal.logging.1.0.0.nupkg.sha512"
|
||||||
},
|
|
||||||
"Microsoft.Data.SqlClient/6.1.3": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-ys/z8Tx8074CDU20EilNvBRJuJdwKSthpHkzUpt3JghnjB6GjbZusoOcCtNbhPCCWsEJqN8bxaT7HnS3UZuUDQ==",
|
|
||||||
"path": "microsoft.data.sqlclient/6.1.3",
|
|
||||||
"hashPath": "microsoft.data.sqlclient.6.1.3.nupkg.sha512"
|
|
||||||
},
|
},
|
||||||
"Microsoft.Data.SqlClient.SNI.runtime/6.0.2": {
|
"Microsoft.Data.SqlClient.SNI.runtime/6.0.2": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
@ -359,61 +295,47 @@
|
|||||||
"path": "microsoft.data.sqlclient.sni.runtime/6.0.2",
|
"path": "microsoft.data.sqlclient.sni.runtime/6.0.2",
|
||||||
"hashPath": "microsoft.data.sqlclient.sni.runtime.6.0.2.nupkg.sha512"
|
"hashPath": "microsoft.data.sqlclient.sni.runtime.6.0.2.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Microsoft.Identity.Client/4.73.1": {
|
"Microsoft.IdentityModel.Abstractions/8.16.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-NnDLS8QwYqO5ZZecL2oioi1LUqjh5Ewk4bMLzbgiXJbQmZhDLtKwLxL3DpGMlQAJ2G4KgEnvGPKa+OOgffeJbw==",
|
"sha512": "sha512-gSxKLWRZzBpIsEoeUPkxfywNCCvRvl7hkq146XHPk5vOQc9izSf1I+uL1vh4y2U19QPxd9Z8K/8AdWyxYz2lSg==",
|
||||||
"path": "microsoft.identity.client/4.73.1",
|
"path": "microsoft.identitymodel.abstractions/8.16.0",
|
||||||
"hashPath": "microsoft.identity.client.4.73.1.nupkg.sha512"
|
"hashPath": "microsoft.identitymodel.abstractions.8.16.0.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Microsoft.Identity.Client.Extensions.Msal/4.73.1": {
|
"Microsoft.IdentityModel.JsonWebTokens/8.16.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-xDztAiV2F0wI0W8FLKv5cbaBefyLD6JVaAsvgSN7bjWNCzGYzHbcOEIP5s4TJXUpQzMfUyBsFl1mC6Zmgpz0PQ==",
|
"sha512": "sha512-prBU72cIP4V8E9fhN+o/YdskTsLeIcnKPbhZf0X6mD7fdxoZqnS/NdEkSr+9Zp+2q7OZBOMfNBKGbTbhXODO4w==",
|
||||||
"path": "microsoft.identity.client.extensions.msal/4.73.1",
|
"path": "microsoft.identitymodel.jsonwebtokens/8.16.0",
|
||||||
"hashPath": "microsoft.identity.client.extensions.msal.4.73.1.nupkg.sha512"
|
"hashPath": "microsoft.identitymodel.jsonwebtokens.8.16.0.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Microsoft.IdentityModel.Abstractions/7.7.1": {
|
"Microsoft.IdentityModel.Logging/8.16.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-S7sHg6gLg7oFqNGLwN1qSbJDI+QcRRj8SuJ1jHyCmKSipnF6ZQL+tFV2NzVfGj/xmGT9TykQdQiBN+p5Idl4TA==",
|
"sha512": "sha512-MTzXmETkNQPACR7/XCXM1OGM6oU9RkyibqeJRtO9Ndew2LnGjMf9Atqj2VSf4XC27X0FQycUAlzxxEgQMWn2xQ==",
|
||||||
"path": "microsoft.identitymodel.abstractions/7.7.1",
|
"path": "microsoft.identitymodel.logging/8.16.0",
|
||||||
"hashPath": "microsoft.identitymodel.abstractions.7.7.1.nupkg.sha512"
|
"hashPath": "microsoft.identitymodel.logging.8.16.0.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Microsoft.IdentityModel.JsonWebTokens/7.7.1": {
|
"Microsoft.IdentityModel.Protocols/8.16.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-3Izi75UCUssvo8LPx3OVnEeZay58qaFicrtSnbtUt7q8qQi0gy46gh4V8VUTkMVMKXV6VMyjBVmeNNgeCUJuIw==",
|
"sha512": "sha512-UFrU7d46UTsPQTa2HIEIpB9H1uJe1BW9FLw5uhEJ2ZuKdur8bcUA/bO5caq5dlBt5gNJeRIB3QQXYNs5fCQCZA==",
|
||||||
"path": "microsoft.identitymodel.jsonwebtokens/7.7.1",
|
"path": "microsoft.identitymodel.protocols/8.16.0",
|
||||||
"hashPath": "microsoft.identitymodel.jsonwebtokens.7.7.1.nupkg.sha512"
|
"hashPath": "microsoft.identitymodel.protocols.8.16.0.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Microsoft.IdentityModel.Logging/7.7.1": {
|
"Microsoft.IdentityModel.Protocols.OpenIdConnect/8.16.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-BZNgSq/o8gsKExdYoBKPR65fdsxW0cTF8PsdqB8y011AGUJJW300S/ZIsEUD0+sOmGc003Gwv3FYbjrVjvsLNQ==",
|
"sha512": "sha512-h4yVXyJsEBBX5lg2G5ftMsi5JzcNEGAzrNphA6DQ6eOd8P0s+cDCOyPwVTYLePZvJL5unbPvYIvzrbTXzFjXnQ==",
|
||||||
"path": "microsoft.identitymodel.logging/7.7.1",
|
"path": "microsoft.identitymodel.protocols.openidconnect/8.16.0",
|
||||||
"hashPath": "microsoft.identitymodel.logging.7.7.1.nupkg.sha512"
|
"hashPath": "microsoft.identitymodel.protocols.openidconnect.8.16.0.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"Microsoft.IdentityModel.Protocols/7.7.1": {
|
"Microsoft.IdentityModel.Tokens/8.16.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-h+fHHBGokepmCX+QZXJk4Ij8OApCb2n2ktoDkNX5CXteXsOxTHMNgjPGpAwdJMFvAL7TtGarUnk3o97NmBq2QQ==",
|
"sha512": "sha512-rtViGJcGsN7WcfUNErwNeQgjuU5cJNl6FDQsfi9TncwO+Epzn0FTfBsg3YuFW1Q0Ch/KPxaVdjLw3/+5Z5ceFQ==",
|
||||||
"path": "microsoft.identitymodel.protocols/7.7.1",
|
"path": "microsoft.identitymodel.tokens/8.16.0",
|
||||||
"hashPath": "microsoft.identitymodel.protocols.7.7.1.nupkg.sha512"
|
"hashPath": "microsoft.identitymodel.tokens.8.16.0.nupkg.sha512"
|
||||||
},
|
|
||||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect/7.7.1": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-yT2Hdj8LpPbcT9C9KlLVxXl09C8zjFaVSaApdOwuecMuoV4s6Sof/mnTDz/+F/lILPIBvrWugR9CC7iRVZgbfQ==",
|
|
||||||
"path": "microsoft.identitymodel.protocols.openidconnect/7.7.1",
|
|
||||||
"hashPath": "microsoft.identitymodel.protocols.openidconnect.7.7.1.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"Microsoft.IdentityModel.Tokens/7.7.1": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-fQ0VVCba75lknUHGldi3iTKAYUQqbzp1Un8+d9cm9nON0Gs8NAkXddNg8iaUB0qi/ybtAmNWizTR4avdkCJ9pQ==",
|
|
||||||
"path": "microsoft.identitymodel.tokens/7.7.1",
|
|
||||||
"hashPath": "microsoft.identitymodel.tokens.7.7.1.nupkg.sha512"
|
|
||||||
},
|
},
|
||||||
"Microsoft.SqlServer.Server/1.0.0": {
|
"Microsoft.SqlServer.Server/1.0.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
@ -422,40 +344,26 @@
|
|||||||
"path": "microsoft.sqlserver.server/1.0.0",
|
"path": "microsoft.sqlserver.server/1.0.0",
|
||||||
"hashPath": "microsoft.sqlserver.server.1.0.0.nupkg.sha512"
|
"hashPath": "microsoft.sqlserver.server.1.0.0.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"System.ClientModel/1.5.1": {
|
"System.Configuration.ConfigurationManager/9.0.13": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-k2jKSO0X45IqhVOT9iQB4xralNN9foRQsRvXBTyRpAVxyzCJlG895T9qYrQWbcJ6OQXxOouJQ37x5nZH5XKK+A==",
|
"sha512": "sha512-GbBrJq9S/gYpHzm7Pxx6Y5tDyfSfyxW6tlP5oiKJV38uf19Wp+GIIAnWfyL1zmNiz1+EjwVapw2WkBFvvqKQzg==",
|
||||||
"path": "system.clientmodel/1.5.1",
|
"path": "system.configuration.configurationmanager/9.0.13",
|
||||||
"hashPath": "system.clientmodel.1.5.1.nupkg.sha512"
|
"hashPath": "system.configuration.configurationmanager.9.0.13.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"System.Configuration.ConfigurationManager/9.0.4": {
|
"System.IdentityModel.Tokens.Jwt/8.16.0": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-dvjqKp+2LpGid6phzrdrS/2mmEPxFl3jE1+L7614q4ZChKbLJCpHXg6sBILlCCED1t//EE+un/UdAetzIMpqnw==",
|
"sha512": "sha512-rrs2u7DRMXQG2yh0oVyF/vLwosfRv20Ld2iEpYcKwQWXHjfV+gFXNQsQ9p008kR9Ou4pxBs68Q6/9zC8Gi1wjg==",
|
||||||
"path": "system.configuration.configurationmanager/9.0.4",
|
"path": "system.identitymodel.tokens.jwt/8.16.0",
|
||||||
"hashPath": "system.configuration.configurationmanager.9.0.4.nupkg.sha512"
|
"hashPath": "system.identitymodel.tokens.jwt.8.16.0.nupkg.sha512"
|
||||||
},
|
},
|
||||||
"System.IdentityModel.Tokens.Jwt/7.7.1": {
|
"System.Security.Cryptography.ProtectedData/9.0.13": {
|
||||||
"type": "package",
|
"type": "package",
|
||||||
"serviceable": true,
|
"serviceable": true,
|
||||||
"sha512": "sha512-rQkO1YbAjLwnDJSMpRhRtrc6XwIcEOcUvoEcge+evurpzSZM3UNK+MZfD3sKyTlYsvknZ6eJjSBfnmXqwOsT9Q==",
|
"sha512": "sha512-t8S9IDpjJKsLpLkeBdW8cWtcPyYqrGu93Dej1RO6WwuL/lkFSqWlan3rMJfortqz1mRIh+sys2AFsSA6jWJ3Jg==",
|
||||||
"path": "system.identitymodel.tokens.jwt/7.7.1",
|
"path": "system.security.cryptography.protecteddata/9.0.13",
|
||||||
"hashPath": "system.identitymodel.tokens.jwt.7.7.1.nupkg.sha512"
|
"hashPath": "system.security.cryptography.protecteddata.9.0.13.nupkg.sha512"
|
||||||
},
|
|
||||||
"System.Memory.Data/8.0.1": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-BVYuec3jV23EMRDeR7Dr1/qhx7369dZzJ9IWy2xylvb4YfXsrUxspWc4UWYid/tj4zZK58uGZqn2WQiaDMhmAg==",
|
|
||||||
"path": "system.memory.data/8.0.1",
|
|
||||||
"hashPath": "system.memory.data.8.0.1.nupkg.sha512"
|
|
||||||
},
|
|
||||||
"System.Security.Cryptography.ProtectedData/9.0.4": {
|
|
||||||
"type": "package",
|
|
||||||
"serviceable": true,
|
|
||||||
"sha512": "sha512-o94k2RKuAce3GeDMlUvIXlhVa1kWpJw95E6C9LwW0KlG0nj5+SgCiIxJ2Eroqb9sLtG1mEMbFttZIBZ13EJPvQ==",
|
|
||||||
"path": "system.security.cryptography.protecteddata/9.0.4",
|
|
||||||
"hashPath": "system.security.cryptography.protecteddata.9.0.4.nupkg.sha512"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -18,6 +18,54 @@ public sealed class TimelineController(ITimelineService timeline) : Controller
|
|||||||
return model is null ? NotFound() : View(model);
|
return model is null ? NotFound() : View(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<IActionResult> Settings(int projectId)
|
||||||
|
{
|
||||||
|
var model = await timeline.GetSettingsAsync(projectId);
|
||||||
|
return model is null ? NotFound() : View(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[ValidateAntiForgeryToken]
|
||||||
|
public async Task<IActionResult> Settings(TimelineSettingsViewModel model)
|
||||||
|
{
|
||||||
|
if (model.ShowMetricShape && !model.SelectedMetricTypeIDs.Any())
|
||||||
|
{
|
||||||
|
ModelState.AddModelError(nameof(model.SelectedMetricTypeIDs), "Select at least one metric or disable Metric Shape.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var current = await timeline.GetSettingsAsync(model.ProjectID);
|
||||||
|
if (current is null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
current.ShowSceneCards = model.ShowSceneCards;
|
||||||
|
current.ShowMetricShape = model.ShowMetricShape;
|
||||||
|
current.ShowPlotLines = model.ShowPlotLines;
|
||||||
|
current.ShowStoryAssets = model.ShowStoryAssets;
|
||||||
|
current.ShowCharacterAppearances = model.ShowCharacterAppearances;
|
||||||
|
current.ShowWarnings = model.ShowWarnings;
|
||||||
|
current.SelectedMetricTypeIDs = model.SelectedMetricTypeIDs;
|
||||||
|
current.MetricOptions = current.MetricOptions
|
||||||
|
.Select(x => new TimelineMetricSettingOptionViewModel
|
||||||
|
{
|
||||||
|
MetricTypeID = x.MetricTypeID,
|
||||||
|
MetricName = x.MetricName,
|
||||||
|
Description = x.Description,
|
||||||
|
SortOrder = x.SortOrder,
|
||||||
|
IsSelected = model.SelectedMetricTypeIDs.Contains(x.MetricTypeID)
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
return View(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
await timeline.SaveSettingsAsync(model);
|
||||||
|
TempData["TimelineSettingsMessage"] = "Timeline settings saved.";
|
||||||
|
return RedirectToAction(nameof(Settings), new { projectId = model.ProjectID });
|
||||||
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ValidateAntiForgeryToken]
|
[ValidateAntiForgeryToken]
|
||||||
public async Task<IActionResult> SavePreset(TimelinePresetSaveViewModel model)
|
public async Task<IActionResult> SavePreset(TimelinePresetSaveViewModel model)
|
||||||
|
|||||||
@ -51,7 +51,7 @@ public interface ILookupRepository
|
|||||||
|
|
||||||
public interface ITimelineRepository
|
public interface ITimelineRepository
|
||||||
{
|
{
|
||||||
Task<TimelineData> GetByProjectAsync(int projectId, int? bookId);
|
Task<TimelineData> GetByProjectAsync(int projectId, int? bookId, bool includeMetrics, IEnumerable<int> metricTypeIds, bool includePlotLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ITimelinePresetRepository
|
public interface ITimelinePresetRepository
|
||||||
@ -62,6 +62,14 @@ public interface ITimelinePresetRepository
|
|||||||
Task ArchiveAsync(int timelineViewPresetId);
|
Task ArchiveAsync(int timelineViewPresetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ITimelineSettingsRepository
|
||||||
|
{
|
||||||
|
Task<ProjectTimelineSettings?> GetAsync(int projectId);
|
||||||
|
Task<IReadOnlyList<SceneMetricType>> ListMetricTypesAsync(int projectId);
|
||||||
|
Task<IReadOnlyList<ProjectTimelineMetricSetting>> ListMetricSettingsAsync(int projectId);
|
||||||
|
Task SaveAsync(ProjectTimelineSettings settings, IEnumerable<int> metricTypeIds);
|
||||||
|
}
|
||||||
|
|
||||||
public interface IPlotRepository
|
public interface IPlotRepository
|
||||||
{
|
{
|
||||||
Task<PlotLookupData> GetLookupsAsync();
|
Task<PlotLookupData> GetLookupsAsync();
|
||||||
@ -1353,12 +1361,20 @@ public sealed class LookupRepository(ISqlConnectionFactory connectionFactory) :
|
|||||||
|
|
||||||
public sealed class TimelineRepository(ISqlConnectionFactory connectionFactory) : ITimelineRepository
|
public sealed class TimelineRepository(ISqlConnectionFactory connectionFactory) : ITimelineRepository
|
||||||
{
|
{
|
||||||
public async Task<TimelineData> GetByProjectAsync(int projectId, int? bookId)
|
public async Task<TimelineData> GetByProjectAsync(int projectId, int? bookId, bool includeMetrics, IEnumerable<int> metricTypeIds, bool includePlotLines)
|
||||||
{
|
{
|
||||||
using var connection = connectionFactory.CreateConnection();
|
using var connection = connectionFactory.CreateConnection();
|
||||||
|
var selectedMetricIds = string.Join(',', metricTypeIds.Where(id => id > 0).Distinct());
|
||||||
using var result = await connection.QueryMultipleAsync(
|
using var result = await connection.QueryMultipleAsync(
|
||||||
"dbo.Timeline_GetByProject",
|
"dbo.Timeline_GetByProject",
|
||||||
new { ProjectID = projectId, BookID = bookId },
|
new
|
||||||
|
{
|
||||||
|
ProjectID = projectId,
|
||||||
|
BookID = bookId,
|
||||||
|
IncludeMetrics = includeMetrics,
|
||||||
|
SelectedMetricTypeIDs = selectedMetricIds,
|
||||||
|
IncludePlotLines = includePlotLines
|
||||||
|
},
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
var project = await result.ReadSingleOrDefaultAsync<Project>();
|
var project = await result.ReadSingleOrDefaultAsync<Project>();
|
||||||
@ -1386,6 +1402,57 @@ public sealed class TimelineRepository(ISqlConnectionFactory connectionFactory)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class TimelineSettingsRepository(ISqlConnectionFactory connectionFactory) : ITimelineSettingsRepository
|
||||||
|
{
|
||||||
|
public async Task<ProjectTimelineSettings?> GetAsync(int projectId)
|
||||||
|
{
|
||||||
|
using var connection = connectionFactory.CreateConnection();
|
||||||
|
return await connection.QuerySingleOrDefaultAsync<ProjectTimelineSettings>(
|
||||||
|
"dbo.ProjectTimelineSettings_Get",
|
||||||
|
new { ProjectID = projectId },
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IReadOnlyList<SceneMetricType>> ListMetricTypesAsync(int projectId)
|
||||||
|
{
|
||||||
|
using var connection = connectionFactory.CreateConnection();
|
||||||
|
var rows = await connection.QueryAsync<SceneMetricType>(
|
||||||
|
"dbo.ProjectTimelineSettings_MetricTypes",
|
||||||
|
new { ProjectID = projectId },
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
return rows.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IReadOnlyList<ProjectTimelineMetricSetting>> ListMetricSettingsAsync(int projectId)
|
||||||
|
{
|
||||||
|
using var connection = connectionFactory.CreateConnection();
|
||||||
|
var rows = await connection.QueryAsync<ProjectTimelineMetricSetting>(
|
||||||
|
"dbo.ProjectTimelineMetricSettings_List",
|
||||||
|
new { ProjectID = projectId },
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
return rows.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveAsync(ProjectTimelineSettings settings, IEnumerable<int> metricTypeIds)
|
||||||
|
{
|
||||||
|
using var connection = connectionFactory.CreateConnection();
|
||||||
|
await connection.ExecuteAsync(
|
||||||
|
"dbo.ProjectTimelineSettings_Save",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
settings.ProjectID,
|
||||||
|
settings.ShowSceneCards,
|
||||||
|
settings.ShowMetricShape,
|
||||||
|
settings.ShowPlotLines,
|
||||||
|
settings.ShowStoryAssets,
|
||||||
|
settings.ShowCharacterAppearances,
|
||||||
|
settings.ShowWarnings,
|
||||||
|
MetricTypeIDs = string.Join(',', metricTypeIds.Where(id => id > 0).Distinct())
|
||||||
|
},
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class TimelinePresetRepository(ISqlConnectionFactory connectionFactory) : ITimelinePresetRepository
|
public sealed class TimelinePresetRepository(ISqlConnectionFactory connectionFactory) : ITimelinePresetRepository
|
||||||
{
|
{
|
||||||
public async Task<IReadOnlyList<TimelineViewPreset>> ListAsync(int projectId, int? bookId)
|
public async Task<IReadOnlyList<TimelineViewPreset>> ListAsync(int projectId, int? bookId)
|
||||||
|
|||||||
@ -183,6 +183,28 @@ public sealed class TimelineViewPreset
|
|||||||
public bool IsArchived { get; set; }
|
public bool IsArchived { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class ProjectTimelineSettings
|
||||||
|
{
|
||||||
|
public int ProjectTimelineSettingsID { get; set; }
|
||||||
|
public int ProjectID { get; set; }
|
||||||
|
public bool ShowSceneCards { get; set; } = true;
|
||||||
|
public bool ShowMetricShape { get; set; } = true;
|
||||||
|
public bool ShowPlotLines { get; set; } = true;
|
||||||
|
public bool ShowStoryAssets { get; set; } = true;
|
||||||
|
public bool ShowCharacterAppearances { get; set; } = true;
|
||||||
|
public bool ShowWarnings { get; set; } = true;
|
||||||
|
public DateTime CreatedDate { get; set; }
|
||||||
|
public DateTime UpdatedDate { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ProjectTimelineMetricSetting
|
||||||
|
{
|
||||||
|
public int ProjectID { get; set; }
|
||||||
|
public int MetricTypeID { get; set; }
|
||||||
|
public string MetricName { get; set; } = string.Empty;
|
||||||
|
public int SortOrder { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class PlotLineType
|
public sealed class PlotLineType
|
||||||
{
|
{
|
||||||
public int PlotLineTypeID { get; set; }
|
public int PlotLineTypeID { get; set; }
|
||||||
|
|||||||
@ -25,6 +25,7 @@ public class Program
|
|||||||
builder.Services.AddScoped<ILookupRepository, LookupRepository>();
|
builder.Services.AddScoped<ILookupRepository, LookupRepository>();
|
||||||
builder.Services.AddScoped<ITimelineRepository, TimelineRepository>();
|
builder.Services.AddScoped<ITimelineRepository, TimelineRepository>();
|
||||||
builder.Services.AddScoped<ITimelinePresetRepository, TimelinePresetRepository>();
|
builder.Services.AddScoped<ITimelinePresetRepository, TimelinePresetRepository>();
|
||||||
|
builder.Services.AddScoped<ITimelineSettingsRepository, TimelineSettingsRepository>();
|
||||||
builder.Services.AddScoped<IPlotRepository, PlotRepository>();
|
builder.Services.AddScoped<IPlotRepository, PlotRepository>();
|
||||||
builder.Services.AddScoped<IAssetRepository, AssetRepository>();
|
builder.Services.AddScoped<IAssetRepository, AssetRepository>();
|
||||||
builder.Services.AddScoped<ICharacterRepository, CharacterRepository>();
|
builder.Services.AddScoped<ICharacterRepository, CharacterRepository>();
|
||||||
|
|||||||
@ -136,6 +136,8 @@ public interface ICharacterService
|
|||||||
public interface ITimelineService
|
public interface ITimelineService
|
||||||
{
|
{
|
||||||
Task<TimelineViewModel?> GetAsync(TimelineFilterViewModel filter);
|
Task<TimelineViewModel?> GetAsync(TimelineFilterViewModel filter);
|
||||||
|
Task<TimelineSettingsViewModel?> GetSettingsAsync(int projectId);
|
||||||
|
Task SaveSettingsAsync(TimelineSettingsViewModel model);
|
||||||
Task<int> SavePresetAsync(TimelinePresetSaveViewModel model);
|
Task<int> SavePresetAsync(TimelinePresetSaveViewModel model);
|
||||||
Task<TimelineViewPreset?> GetPresetAsync(int timelineViewPresetId);
|
Task<TimelineViewPreset?> GetPresetAsync(int timelineViewPresetId);
|
||||||
Task ArchivePresetAsync(int timelineViewPresetId);
|
Task ArchivePresetAsync(int timelineViewPresetId);
|
||||||
@ -874,6 +876,8 @@ public sealed class SceneService(
|
|||||||
public sealed class TimelineService(
|
public sealed class TimelineService(
|
||||||
ITimelineRepository timelineRepository,
|
ITimelineRepository timelineRepository,
|
||||||
ITimelinePresetRepository presets,
|
ITimelinePresetRepository presets,
|
||||||
|
ITimelineSettingsRepository timelineSettings,
|
||||||
|
IProjectRepository projects,
|
||||||
IBookRepository books,
|
IBookRepository books,
|
||||||
ISceneService scenes,
|
ISceneService scenes,
|
||||||
IAssetRepository assets,
|
IAssetRepository assets,
|
||||||
@ -885,14 +889,32 @@ public sealed class TimelineService(
|
|||||||
ISceneDependencyRepository sceneDependencies,
|
ISceneDependencyRepository sceneDependencies,
|
||||||
ILogger<TimelineService> logger) : ITimelineService
|
ILogger<TimelineService> logger) : ITimelineService
|
||||||
{
|
{
|
||||||
private static readonly string[] DefaultGraphMetrics = ["Overall Intensity", "Tension", "Emotional Weight", "Action"];
|
|
||||||
|
|
||||||
public async Task<TimelineViewModel?> GetAsync(TimelineFilterViewModel filter)
|
public async Task<TimelineViewModel?> GetAsync(TimelineFilterViewModel filter)
|
||||||
{
|
{
|
||||||
var projectId = filter.ProjectID;
|
var projectId = filter.ProjectID;
|
||||||
var bookId = filter.BookID;
|
var bookId = filter.BookID;
|
||||||
var selectedSceneId = filter.SelectedSceneID;
|
var selectedSceneId = filter.SelectedSceneID;
|
||||||
var timeline = await TimeTimelineLoadAsync("dbo.Timeline_GetByProject", () => timelineRepository.GetByProjectAsync(projectId, bookId), projectId, bookId);
|
var settings = await TimeTimelineLoadAsync("dbo.ProjectTimelineSettings_Get", () => timelineSettings.GetAsync(projectId), projectId, bookId);
|
||||||
|
if (settings is null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var selectedMetricIds = (await TimeTimelineLoadAsync("dbo.ProjectTimelineMetricSettings_List", () => timelineSettings.ListMetricSettingsAsync(projectId), projectId, bookId))
|
||||||
|
.OrderBy(x => x.SortOrder)
|
||||||
|
.Select(x => x.MetricTypeID)
|
||||||
|
.ToList();
|
||||||
|
var needsPlotTimelineData = settings.ShowPlotLines || filter.PlotLineID.HasValue || filter.PlotThreadID.HasValue || filter.FocusType is "plotline" or "plotthread";
|
||||||
|
var needsMetricTimelineData = settings.ShowMetricShape && selectedMetricIds.Any();
|
||||||
|
var needsAssetTimelineData = settings.ShowStoryAssets || filter.StoryAssetID.HasValue || filter.FocusType == "asset";
|
||||||
|
var needsCharacterTimelineData = settings.ShowCharacterAppearances || filter.CharacterID.HasValue || filter.FocusType == "character";
|
||||||
|
var needsWarnings = settings.ShowWarnings || filter.WarningSeverityID.HasValue || filter.WarningTypeID.HasValue || filter.ShowWarningsOnly;
|
||||||
|
|
||||||
|
var timeline = await TimeTimelineLoadAsync(
|
||||||
|
"dbo.Timeline_GetByProject",
|
||||||
|
() => timelineRepository.GetByProjectAsync(projectId, bookId, needsMetricTimelineData, selectedMetricIds, needsPlotTimelineData),
|
||||||
|
projectId,
|
||||||
|
bookId);
|
||||||
if (timeline.Project is null)
|
if (timeline.Project is null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@ -913,7 +935,9 @@ public sealed class TimelineService(
|
|||||||
var scenesByChapter = timeline.Scenes.GroupBy(x => x.ChapterID).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 purposeLabelsByScene = timeline.PurposeLabels.GroupBy(x => x.SceneID).ToDictionary(x => x.Key, x => x.OrderBy(p => p.SortOrder).ToList());
|
||||||
var orderedScenes = timeline.Scenes.ToList();
|
var orderedScenes = timeline.Scenes.ToList();
|
||||||
var warningCounts = (await TimeTimelineLoadAsync("dbo.ContinuityWarning_SceneCounts", () => warnings.GetSceneCountsAsync(projectId, bookId), projectId, bookId)).ToDictionary(x => x.SceneID, x => x.WarningCount);
|
var warningCounts = needsWarnings
|
||||||
|
? (await TimeTimelineLoadAsync("dbo.ContinuityWarning_SceneCounts", () => warnings.GetSceneCountsAsync(projectId, bookId), projectId, bookId)).ToDictionary(x => x.SceneID, x => x.WarningCount)
|
||||||
|
: new Dictionary<int, int>();
|
||||||
var dependencyCounts = (await TimeTimelineLoadAsync("dbo.SceneDependency_Counts", () => sceneDependencies.GetCountsAsync(projectId, bookId), projectId, bookId)).ToDictionary(x => x.SceneID, x => x.DependencyCount);
|
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)
|
foreach (var scene in orderedScenes)
|
||||||
@ -923,8 +947,12 @@ public sealed class TimelineService(
|
|||||||
scene.DependencyCount = dependencyCounts.GetValueOrDefault(scene.SceneID);
|
scene.DependencyCount = dependencyCounts.GetValueOrDefault(scene.SceneID);
|
||||||
}
|
}
|
||||||
|
|
||||||
var assetTimeline = await TimeTimelineLoadAsync("dbo.AssetTimeline_GetByProject", () => assets.GetTimelineAsync(projectId, bookId), projectId, bookId);
|
(IReadOnlyList<StoryAsset> Assets, IReadOnlyList<AssetEvent> Events) assetTimeline = needsAssetTimelineData
|
||||||
var characterTimeline = await TimeTimelineLoadAsync("dbo.CharacterTimeline_GetByProject", () => characters.GetTimelineAsync(projectId, bookId), projectId, bookId);
|
? await TimeTimelineLoadAsync("dbo.AssetTimeline_GetByProject", () => assets.GetTimelineAsync(projectId, bookId), projectId, bookId)
|
||||||
|
: ([], []);
|
||||||
|
(IReadOnlyList<Character> Characters, IReadOnlyList<SceneCharacter> Appearances) characterTimeline = needsCharacterTimelineData
|
||||||
|
? await TimeTimelineLoadAsync("dbo.CharacterTimeline_GetByProject", () => characters.GetTimelineAsync(projectId, bookId), projectId, bookId)
|
||||||
|
: ([], []);
|
||||||
var scenePovLabels = characterTimeline.Appearances
|
var scenePovLabels = characterTimeline.Appearances
|
||||||
.Where(x => x.RoleInSceneTypeName?.Contains("POV", StringComparison.OrdinalIgnoreCase) == true)
|
.Where(x => x.RoleInSceneTypeName?.Contains("POV", StringComparison.OrdinalIgnoreCase) == true)
|
||||||
.GroupBy(x => x.SceneID)
|
.GroupBy(x => x.SceneID)
|
||||||
@ -951,6 +979,7 @@ public sealed class TimelineService(
|
|||||||
return new TimelineViewModel
|
return new TimelineViewModel
|
||||||
{
|
{
|
||||||
Project = timeline.Project,
|
Project = timeline.Project,
|
||||||
|
Settings = settings,
|
||||||
SelectedBookID = bookId,
|
SelectedBookID = bookId,
|
||||||
SelectedSceneID = selectedScene?.SceneID,
|
SelectedSceneID = selectedScene?.SceneID,
|
||||||
SelectedScene = selectedScene,
|
SelectedScene = selectedScene,
|
||||||
@ -991,10 +1020,10 @@ public sealed class TimelineService(
|
|||||||
.ToList()
|
.ToList()
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
OrderedScenes = orderedScenes,
|
OrderedScenes = orderedScenes,
|
||||||
MetricGraphs = BuildMetricGraphs(timeline, orderedScenes),
|
MetricGraphs = settings.ShowMetricShape ? BuildMetricGraphs(timeline, orderedScenes) : [],
|
||||||
PlotLanes = BuildPlotLanes(timeline, orderedScenes),
|
PlotLanes = settings.ShowPlotLines ? BuildPlotLanes(timeline, orderedScenes) : [],
|
||||||
AssetLanes = BuildAssetLanes(assetTimeline.Assets, assetTimeline.Events, orderedScenes),
|
AssetLanes = settings.ShowStoryAssets ? BuildAssetLanes(assetTimeline.Assets, assetTimeline.Events, orderedScenes) : [],
|
||||||
CharacterLanes = BuildCharacterLanes(characterTimeline.Characters, characterTimeline.Appearances, orderedScenes),
|
CharacterLanes = settings.ShowCharacterAppearances ? BuildCharacterLanes(characterTimeline.Characters, characterTimeline.Appearances, orderedScenes) : [],
|
||||||
MatchingSceneIDs = matchingSceneIds,
|
MatchingSceneIDs = matchingSceneIds,
|
||||||
FocusSceneIDs = focusSceneIds,
|
FocusSceneIDs = focusSceneIds,
|
||||||
ScenePovLabels = scenePovLabels,
|
ScenePovLabels = scenePovLabels,
|
||||||
@ -1006,6 +1035,63 @@ public sealed class TimelineService(
|
|||||||
|
|
||||||
public Task ArchivePresetAsync(int timelineViewPresetId) => presets.ArchiveAsync(timelineViewPresetId);
|
public Task ArchivePresetAsync(int timelineViewPresetId) => presets.ArchiveAsync(timelineViewPresetId);
|
||||||
|
|
||||||
|
public async Task<TimelineSettingsViewModel?> GetSettingsAsync(int projectId)
|
||||||
|
{
|
||||||
|
var project = await projects.GetAsync(projectId);
|
||||||
|
if (project is null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var settings = await timelineSettings.GetAsync(projectId) ?? new ProjectTimelineSettings { ProjectID = projectId };
|
||||||
|
var metricTypes = await timelineSettings.ListMetricTypesAsync(projectId);
|
||||||
|
var selectedMetricIds = (await timelineSettings.ListMetricSettingsAsync(projectId)).Select(x => x.MetricTypeID).ToHashSet();
|
||||||
|
|
||||||
|
return new TimelineSettingsViewModel
|
||||||
|
{
|
||||||
|
ProjectID = project.ProjectID,
|
||||||
|
ProjectName = project.ProjectName,
|
||||||
|
ShowSceneCards = settings.ShowSceneCards,
|
||||||
|
ShowMetricShape = settings.ShowMetricShape,
|
||||||
|
ShowPlotLines = settings.ShowPlotLines,
|
||||||
|
ShowStoryAssets = settings.ShowStoryAssets,
|
||||||
|
ShowCharacterAppearances = settings.ShowCharacterAppearances,
|
||||||
|
ShowWarnings = settings.ShowWarnings,
|
||||||
|
SelectedMetricTypeIDs = selectedMetricIds.ToList(),
|
||||||
|
MetricOptions = metricTypes
|
||||||
|
.OrderBy(x => x.SortOrder)
|
||||||
|
.ThenBy(x => x.MetricName)
|
||||||
|
.Select(x => new TimelineMetricSettingOptionViewModel
|
||||||
|
{
|
||||||
|
MetricTypeID = x.MetricTypeID,
|
||||||
|
MetricName = x.MetricName,
|
||||||
|
Description = x.Description,
|
||||||
|
SortOrder = x.SortOrder,
|
||||||
|
IsSelected = selectedMetricIds.Contains(x.MetricTypeID)
|
||||||
|
})
|
||||||
|
.ToList()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveSettingsAsync(TimelineSettingsViewModel model)
|
||||||
|
{
|
||||||
|
if (model.ShowMetricShape && !model.SelectedMetricTypeIDs.Any())
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Select at least one metric or disable Metric Shape.");
|
||||||
|
}
|
||||||
|
|
||||||
|
await timelineSettings.SaveAsync(new ProjectTimelineSettings
|
||||||
|
{
|
||||||
|
ProjectID = model.ProjectID,
|
||||||
|
ShowSceneCards = model.ShowSceneCards,
|
||||||
|
ShowMetricShape = model.ShowMetricShape,
|
||||||
|
ShowPlotLines = model.ShowPlotLines,
|
||||||
|
ShowStoryAssets = model.ShowStoryAssets,
|
||||||
|
ShowCharacterAppearances = model.ShowCharacterAppearances,
|
||||||
|
ShowWarnings = model.ShowWarnings
|
||||||
|
}, model.SelectedMetricTypeIDs);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<T> TimeTimelineLoadAsync<T>(string operationName, Func<Task<T>> operation, int projectId, int? bookId)
|
private async Task<T> TimeTimelineLoadAsync<T>(string operationName, Func<Task<T>> operation, int projectId, int? bookId)
|
||||||
{
|
{
|
||||||
var stopwatch = Stopwatch.StartNew();
|
var stopwatch = Stopwatch.StartNew();
|
||||||
@ -1280,7 +1366,6 @@ public sealed class TimelineService(
|
|||||||
.ToDictionary(x => x.Key, x => x.ToDictionary(point => point.SceneID));
|
.ToDictionary(x => x.Key, x => x.ToDictionary(point => point.SceneID));
|
||||||
|
|
||||||
return timeline.MetricTypes
|
return timeline.MetricTypes
|
||||||
.Where(metric => DefaultGraphMetrics.Contains(metric.MetricName))
|
|
||||||
.OrderBy(metric => metric.SortOrder)
|
.OrderBy(metric => metric.SortOrder)
|
||||||
.Select(metric => new MetricGraphViewModel
|
.Select(metric => new MetricGraphViewModel
|
||||||
{
|
{
|
||||||
|
|||||||
271
PlotLine/Sql/026_TimelineConfigurationSettings.sql
Normal file
271
PlotLine/Sql/026_TimelineConfigurationSettings.sql
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
SET ANSI_NULLS ON;
|
||||||
|
GO
|
||||||
|
SET QUOTED_IDENTIFIER ON;
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF OBJECT_ID(N'dbo.ProjectTimelineSettings', N'U') IS NULL
|
||||||
|
BEGIN
|
||||||
|
CREATE TABLE dbo.ProjectTimelineSettings
|
||||||
|
(
|
||||||
|
ProjectTimelineSettingsID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_ProjectTimelineSettings PRIMARY KEY,
|
||||||
|
ProjectID int NOT NULL,
|
||||||
|
ShowSceneCards bit NOT NULL CONSTRAINT DF_ProjectTimelineSettings_ShowSceneCards DEFAULT 1,
|
||||||
|
ShowMetricShape bit NOT NULL CONSTRAINT DF_ProjectTimelineSettings_ShowMetricShape DEFAULT 1,
|
||||||
|
ShowPlotLines bit NOT NULL CONSTRAINT DF_ProjectTimelineSettings_ShowPlotLines DEFAULT 1,
|
||||||
|
ShowStoryAssets bit NOT NULL CONSTRAINT DF_ProjectTimelineSettings_ShowStoryAssets DEFAULT 1,
|
||||||
|
ShowCharacterAppearances bit NOT NULL CONSTRAINT DF_ProjectTimelineSettings_ShowCharacterAppearances DEFAULT 1,
|
||||||
|
ShowWarnings bit NOT NULL CONSTRAINT DF_ProjectTimelineSettings_ShowWarnings DEFAULT 1,
|
||||||
|
CreatedDate datetime2(0) NOT NULL CONSTRAINT DF_ProjectTimelineSettings_CreatedDate DEFAULT SYSUTCDATETIME(),
|
||||||
|
UpdatedDate datetime2(0) NOT NULL CONSTRAINT DF_ProjectTimelineSettings_UpdatedDate DEFAULT SYSUTCDATETIME(),
|
||||||
|
CONSTRAINT UQ_ProjectTimelineSettings_ProjectID UNIQUE(ProjectID),
|
||||||
|
CONSTRAINT FK_ProjectTimelineSettings_Projects FOREIGN KEY(ProjectID) REFERENCES dbo.Projects(ProjectID)
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF OBJECT_ID(N'dbo.ProjectTimelineMetricSettings', N'U') IS NULL
|
||||||
|
BEGIN
|
||||||
|
CREATE TABLE dbo.ProjectTimelineMetricSettings
|
||||||
|
(
|
||||||
|
ProjectID int NOT NULL,
|
||||||
|
MetricTypeID int NOT NULL,
|
||||||
|
SortOrder int NOT NULL,
|
||||||
|
CreatedDate datetime2(0) NOT NULL CONSTRAINT DF_ProjectTimelineMetricSettings_CreatedDate DEFAULT SYSUTCDATETIME(),
|
||||||
|
CONSTRAINT PK_ProjectTimelineMetricSettings PRIMARY KEY(ProjectID, MetricTypeID),
|
||||||
|
CONSTRAINT FK_ProjectTimelineMetricSettings_Projects FOREIGN KEY(ProjectID) REFERENCES dbo.Projects(ProjectID),
|
||||||
|
CONSTRAINT FK_ProjectTimelineMetricSettings_SceneMetricTypes FOREIGN KEY(MetricTypeID) REFERENCES dbo.SceneMetricTypes(MetricTypeID)
|
||||||
|
);
|
||||||
|
END;
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.ProjectTimelineSettings_EnsureDefaults
|
||||||
|
@ProjectID int
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM dbo.Projects WHERE ProjectID = @ProjectID AND IsArchived = 0)
|
||||||
|
RETURN;
|
||||||
|
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM dbo.ProjectTimelineSettings WHERE ProjectID = @ProjectID)
|
||||||
|
BEGIN
|
||||||
|
INSERT dbo.ProjectTimelineSettings
|
||||||
|
(ProjectID, ShowSceneCards, ShowMetricShape, ShowPlotLines, ShowStoryAssets, ShowCharacterAppearances, ShowWarnings)
|
||||||
|
VALUES
|
||||||
|
(@ProjectID, 1, 1, 1, 1, 1, 1);
|
||||||
|
END;
|
||||||
|
|
||||||
|
IF NOT EXISTS (SELECT 1 FROM dbo.ProjectTimelineMetricSettings WHERE ProjectID = @ProjectID)
|
||||||
|
BEGIN
|
||||||
|
INSERT dbo.ProjectTimelineMetricSettings (ProjectID, MetricTypeID, SortOrder)
|
||||||
|
SELECT @ProjectID, mt.MetricTypeID, mt.SortOrder
|
||||||
|
FROM dbo.SceneMetricTypes mt
|
||||||
|
WHERE mt.IsActive = 1
|
||||||
|
AND (mt.ProjectID IS NULL OR mt.ProjectID = @ProjectID)
|
||||||
|
AND mt.MetricName IN (N'Overall Intensity', N'Tension', N'Emotional Weight', N'Action');
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.ProjectTimelineSettings_Get
|
||||||
|
@ProjectID int
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
|
||||||
|
EXEC dbo.ProjectTimelineSettings_EnsureDefaults @ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
SELECT ProjectTimelineSettingsID, ProjectID, ShowSceneCards, ShowMetricShape, ShowPlotLines,
|
||||||
|
ShowStoryAssets, ShowCharacterAppearances, ShowWarnings, CreatedDate, UpdatedDate
|
||||||
|
FROM dbo.ProjectTimelineSettings
|
||||||
|
WHERE ProjectID = @ProjectID;
|
||||||
|
END;
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.ProjectTimelineSettings_MetricTypes
|
||||||
|
@ProjectID int
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
|
||||||
|
SELECT MetricTypeID, ProjectID, MetricName, Description, MinValue, MaxValue, DefaultValue, SortOrder, IsActive
|
||||||
|
FROM dbo.SceneMetricTypes
|
||||||
|
WHERE IsActive = 1 AND (ProjectID IS NULL OR ProjectID = @ProjectID)
|
||||||
|
ORDER BY SortOrder, MetricName;
|
||||||
|
END;
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.ProjectTimelineMetricSettings_List
|
||||||
|
@ProjectID int
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
|
||||||
|
EXEC dbo.ProjectTimelineSettings_EnsureDefaults @ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
SELECT ptms.ProjectID, ptms.MetricTypeID, mt.MetricName, mt.SortOrder
|
||||||
|
FROM dbo.ProjectTimelineMetricSettings ptms
|
||||||
|
INNER JOIN dbo.SceneMetricTypes mt ON mt.MetricTypeID = ptms.MetricTypeID
|
||||||
|
WHERE ptms.ProjectID = @ProjectID
|
||||||
|
AND mt.IsActive = 1
|
||||||
|
AND (mt.ProjectID IS NULL OR mt.ProjectID = @ProjectID)
|
||||||
|
ORDER BY ptms.SortOrder, mt.SortOrder, mt.MetricName;
|
||||||
|
END;
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.ProjectTimelineSettings_Save
|
||||||
|
@ProjectID int,
|
||||||
|
@ShowSceneCards bit,
|
||||||
|
@ShowMetricShape bit,
|
||||||
|
@ShowPlotLines bit,
|
||||||
|
@ShowStoryAssets bit,
|
||||||
|
@ShowCharacterAppearances bit,
|
||||||
|
@ShowWarnings bit,
|
||||||
|
@MetricTypeIDs nvarchar(max) = NULL
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
|
||||||
|
EXEC dbo.ProjectTimelineSettings_EnsureDefaults @ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
UPDATE dbo.ProjectTimelineSettings
|
||||||
|
SET ShowSceneCards = @ShowSceneCards,
|
||||||
|
ShowMetricShape = @ShowMetricShape,
|
||||||
|
ShowPlotLines = @ShowPlotLines,
|
||||||
|
ShowStoryAssets = @ShowStoryAssets,
|
||||||
|
ShowCharacterAppearances = @ShowCharacterAppearances,
|
||||||
|
ShowWarnings = @ShowWarnings,
|
||||||
|
UpdatedDate = SYSUTCDATETIME()
|
||||||
|
WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
DELETE FROM dbo.ProjectTimelineMetricSettings
|
||||||
|
WHERE ProjectID = @ProjectID;
|
||||||
|
|
||||||
|
IF @MetricTypeIDs IS NOT NULL AND LTRIM(RTRIM(@MetricTypeIDs)) <> N''
|
||||||
|
BEGIN
|
||||||
|
INSERT dbo.ProjectTimelineMetricSettings (ProjectID, MetricTypeID, SortOrder)
|
||||||
|
SELECT @ProjectID, mt.MetricTypeID, mt.SortOrder
|
||||||
|
FROM dbo.SceneMetricTypes mt
|
||||||
|
INNER JOIN
|
||||||
|
(
|
||||||
|
SELECT DISTINCT TRY_CONVERT(int, value) AS MetricTypeID
|
||||||
|
FROM string_split(@MetricTypeIDs, N',')
|
||||||
|
WHERE TRY_CONVERT(int, value) IS NOT NULL
|
||||||
|
) selected ON selected.MetricTypeID = mt.MetricTypeID
|
||||||
|
WHERE mt.IsActive = 1 AND (mt.ProjectID IS NULL OR mt.ProjectID = @ProjectID);
|
||||||
|
END;
|
||||||
|
END;
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.Timeline_GetByProject
|
||||||
|
@ProjectID int,
|
||||||
|
@BookID int = NULL,
|
||||||
|
@IncludeMetrics bit = 1,
|
||||||
|
@SelectedMetricTypeIDs nvarchar(max) = NULL,
|
||||||
|
@IncludePlotLines bit = 1
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
|
||||||
|
DECLARE @MetricSelection TABLE (MetricTypeID int NOT NULL PRIMARY KEY);
|
||||||
|
INSERT @MetricSelection (MetricTypeID)
|
||||||
|
SELECT DISTINCT TRY_CONVERT(int, value)
|
||||||
|
FROM string_split(COALESCE(@SelectedMetricTypeIDs, N''), N',')
|
||||||
|
WHERE TRY_CONVERT(int, value) IS NOT NULL;
|
||||||
|
|
||||||
|
SELECT ProjectID, ProjectName, Description, CreatedDate, UpdatedDate, IsArchived
|
||||||
|
FROM dbo.Projects
|
||||||
|
WHERE ProjectID = @ProjectID AND IsArchived = 0;
|
||||||
|
|
||||||
|
SELECT BookID, ProjectID, BookTitle, BookNumber, Description, SortOrder, CreatedDate, UpdatedDate, IsArchived
|
||||||
|
FROM dbo.Books
|
||||||
|
WHERE ProjectID = @ProjectID AND IsArchived = 0 AND (@BookID IS NULL OR BookID = @BookID)
|
||||||
|
ORDER BY SortOrder, BookNumber;
|
||||||
|
|
||||||
|
SELECT c.ChapterID, c.BookID, c.ChapterNumber, c.ChapterTitle, c.POVCharacterID, c.Summary, c.SortOrder,
|
||||||
|
c.RevisionStatusID, rs.StatusName AS RevisionStatusName, c.CreatedDate, c.UpdatedDate, c.IsArchived
|
||||||
|
FROM dbo.Chapters c
|
||||||
|
INNER JOIN dbo.Books b ON b.BookID = c.BookID
|
||||||
|
INNER JOIN dbo.RevisionStatuses rs ON rs.RevisionStatusID = c.RevisionStatusID
|
||||||
|
WHERE b.ProjectID = @ProjectID AND c.IsArchived = 0 AND b.IsArchived = 0 AND (@BookID IS NULL OR b.BookID = @BookID)
|
||||||
|
ORDER BY b.SortOrder, c.SortOrder;
|
||||||
|
|
||||||
|
SELECT s.SceneID, s.ChapterID, s.SceneNumber, s.SceneTitle, s.Summary, s.POVCharacterID, s.PrimaryLocationID,
|
||||||
|
location.LocationName AS PrimaryLocationName, location.LocationPath AS PrimaryLocationPath,
|
||||||
|
s.SortOrder, s.TimeModeID, tm.TimeModeName, s.StartDateTime, s.EndDateTime, s.DurationAmount, s.DurationUnitID,
|
||||||
|
du.DurationUnitName, s.RelativeTimeText, s.TimeConfidenceID, tc.TimeConfidenceName, s.ScenePurposeNotes,
|
||||||
|
s.SceneOutcomeNotes, s.RevisionStatusID, rs.StatusName AS RevisionStatusName, s.CreatedDate, s.UpdatedDate, s.IsArchived
|
||||||
|
FROM dbo.Scenes s
|
||||||
|
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
|
||||||
|
INNER JOIN dbo.Books b ON b.BookID = c.BookID
|
||||||
|
INNER JOIN dbo.TimeModes tm ON tm.TimeModeID = s.TimeModeID
|
||||||
|
INNER JOIN dbo.TimeConfidences tc ON tc.TimeConfidenceID = s.TimeConfidenceID
|
||||||
|
INNER JOIN dbo.RevisionStatuses rs ON rs.RevisionStatusID = s.RevisionStatusID
|
||||||
|
LEFT JOIN dbo.DurationUnits du ON du.DurationUnitID = s.DurationUnitID
|
||||||
|
LEFT JOIN dbo.LocationPaths location ON location.LocationID = s.PrimaryLocationID
|
||||||
|
WHERE b.ProjectID = @ProjectID AND s.IsArchived = 0 AND c.IsArchived = 0 AND b.IsArchived = 0 AND (@BookID IS NULL OR b.BookID = @BookID)
|
||||||
|
ORDER BY b.SortOrder, c.SortOrder, s.SortOrder;
|
||||||
|
|
||||||
|
SELECT sp.SceneID, spt.ScenePurposeTypeID, spt.PurposeName, spt.SortOrder
|
||||||
|
FROM dbo.ScenePurposes sp
|
||||||
|
INNER JOIN dbo.ScenePurposeTypes spt ON spt.ScenePurposeTypeID = sp.ScenePurposeTypeID
|
||||||
|
INNER JOIN dbo.Scenes s ON s.SceneID = sp.SceneID
|
||||||
|
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
|
||||||
|
INNER JOIN dbo.Books b ON b.BookID = c.BookID
|
||||||
|
WHERE b.ProjectID = @ProjectID AND (@BookID IS NULL OR b.BookID = @BookID)
|
||||||
|
ORDER BY spt.SortOrder;
|
||||||
|
|
||||||
|
SELECT MetricTypeID, ProjectID, MetricName, Description, MinValue, MaxValue, DefaultValue, SortOrder, IsActive
|
||||||
|
FROM dbo.SceneMetricTypes
|
||||||
|
WHERE @IncludeMetrics = 1
|
||||||
|
AND IsActive = 1
|
||||||
|
AND (ProjectID IS NULL OR ProjectID = @ProjectID)
|
||||||
|
AND (NOT EXISTS (SELECT 1 FROM @MetricSelection) OR MetricTypeID IN (SELECT MetricTypeID FROM @MetricSelection))
|
||||||
|
ORDER BY SortOrder;
|
||||||
|
|
||||||
|
SELECT s.SceneID, mt.MetricTypeID, mt.MetricName, COALESCE(smv.Value, mt.DefaultValue) AS Value, smv.Notes
|
||||||
|
FROM dbo.Scenes s
|
||||||
|
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
|
||||||
|
INNER JOIN dbo.Books b ON b.BookID = c.BookID
|
||||||
|
INNER JOIN dbo.SceneMetricTypes mt ON mt.IsActive = 1 AND (mt.ProjectID IS NULL OR mt.ProjectID = @ProjectID)
|
||||||
|
LEFT JOIN dbo.SceneMetricValues smv ON smv.SceneID = s.SceneID AND smv.MetricTypeID = mt.MetricTypeID
|
||||||
|
WHERE @IncludeMetrics = 1
|
||||||
|
AND b.ProjectID = @ProjectID
|
||||||
|
AND s.IsArchived = 0
|
||||||
|
AND c.IsArchived = 0
|
||||||
|
AND b.IsArchived = 0
|
||||||
|
AND (@BookID IS NULL OR b.BookID = @BookID)
|
||||||
|
AND (NOT EXISTS (SELECT 1 FROM @MetricSelection) OR mt.MetricTypeID IN (SELECT MetricTypeID FROM @MetricSelection))
|
||||||
|
ORDER BY b.SortOrder, c.SortOrder, s.SortOrder, mt.SortOrder;
|
||||||
|
|
||||||
|
SELECT pl.PlotLineID, pl.ProjectID, pl.BookID, b.BookTitle, pl.PlotLineName, pl.PlotLineTypeID, plt.TypeName AS PlotLineTypeName,
|
||||||
|
pl.Description, pl.ParentPlotLineID, parent.PlotLineName AS ParentPlotLineName, pl.SortOrder, pl.Colour, pl.IsMainPlot, pl.IsVisibleOnTimeline,
|
||||||
|
pl.CreatedDate, pl.UpdatedDate, pl.IsArchived
|
||||||
|
FROM dbo.PlotLines pl
|
||||||
|
INNER JOIN dbo.PlotLineTypes plt ON plt.PlotLineTypeID = pl.PlotLineTypeID
|
||||||
|
LEFT JOIN dbo.Books b ON b.BookID = pl.BookID
|
||||||
|
LEFT JOIN dbo.PlotLines parent ON parent.PlotLineID = pl.ParentPlotLineID
|
||||||
|
WHERE @IncludePlotLines = 1
|
||||||
|
AND pl.ProjectID = @ProjectID
|
||||||
|
AND pl.IsArchived = 0
|
||||||
|
AND pl.IsVisibleOnTimeline = 1
|
||||||
|
AND (@BookID IS NULL OR pl.BookID IS NULL OR pl.BookID = @BookID)
|
||||||
|
ORDER BY pl.SortOrder, pl.PlotLineName;
|
||||||
|
|
||||||
|
SELECT te.ThreadEventID, te.PlotThreadID, pt.ThreadTitle, pt.PlotLineID, pl.PlotLineName, pl.Colour, te.SceneID, te.EventTypeID,
|
||||||
|
tet.TypeName AS EventTypeName, tet.MarkerText, te.EventTitle, te.EventDescription, te.CreatedDate, te.UpdatedDate
|
||||||
|
FROM dbo.ThreadEvents te
|
||||||
|
INNER JOIN dbo.PlotThreads pt ON pt.PlotThreadID = te.PlotThreadID
|
||||||
|
INNER JOIN dbo.PlotLines pl ON pl.PlotLineID = pt.PlotLineID
|
||||||
|
INNER JOIN dbo.ThreadEventTypes tet ON tet.ThreadEventTypeID = te.EventTypeID
|
||||||
|
INNER JOIN dbo.Scenes s ON s.SceneID = te.SceneID
|
||||||
|
INNER JOIN dbo.Chapters c ON c.ChapterID = s.ChapterID
|
||||||
|
INNER JOIN dbo.Books b ON b.BookID = c.BookID
|
||||||
|
WHERE @IncludePlotLines = 1
|
||||||
|
AND b.ProjectID = @ProjectID
|
||||||
|
AND pl.IsArchived = 0
|
||||||
|
AND pt.IsArchived = 0
|
||||||
|
AND (@BookID IS NULL OR b.BookID = @BookID)
|
||||||
|
ORDER BY pl.SortOrder, pt.ThreadTitle, b.SortOrder, c.SortOrder, s.SortOrder;
|
||||||
|
END;
|
||||||
|
GO
|
||||||
@ -374,6 +374,7 @@ public sealed class Phase1AcceptanceViewModel
|
|||||||
public sealed class TimelineViewModel
|
public sealed class TimelineViewModel
|
||||||
{
|
{
|
||||||
public Project Project { get; set; } = new();
|
public Project Project { get; set; } = new();
|
||||||
|
public ProjectTimelineSettings Settings { get; set; } = new();
|
||||||
public int? SelectedBookID { get; set; }
|
public int? SelectedBookID { get; set; }
|
||||||
public int? SelectedSceneID { get; set; }
|
public int? SelectedSceneID { get; set; }
|
||||||
public SceneEditViewModel? SelectedScene { get; set; }
|
public SceneEditViewModel? SelectedScene { get; set; }
|
||||||
@ -415,6 +416,29 @@ public sealed class TimelineViewModel
|
|||||||
public ContinuityValidationSummary? LastValidationSummary { get; set; }
|
public ContinuityValidationSummary? LastValidationSummary { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class TimelineSettingsViewModel
|
||||||
|
{
|
||||||
|
public int ProjectID { get; set; }
|
||||||
|
public string ProjectName { get; set; } = string.Empty;
|
||||||
|
public bool ShowSceneCards { get; set; } = true;
|
||||||
|
public bool ShowMetricShape { get; set; } = true;
|
||||||
|
public bool ShowPlotLines { get; set; } = true;
|
||||||
|
public bool ShowStoryAssets { get; set; } = true;
|
||||||
|
public bool ShowCharacterAppearances { get; set; } = true;
|
||||||
|
public bool ShowWarnings { get; set; } = true;
|
||||||
|
public List<int> SelectedMetricTypeIDs { get; set; } = [];
|
||||||
|
public IReadOnlyList<TimelineMetricSettingOptionViewModel> MetricOptions { get; set; } = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class TimelineMetricSettingOptionViewModel
|
||||||
|
{
|
||||||
|
public int MetricTypeID { get; set; }
|
||||||
|
public string MetricName { get; set; } = string.Empty;
|
||||||
|
public string? Description { get; set; }
|
||||||
|
public int SortOrder { get; set; }
|
||||||
|
public bool IsSelected { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public sealed class StoryBibleViewModel
|
public sealed class StoryBibleViewModel
|
||||||
{
|
{
|
||||||
public Project Project { get; set; } = new();
|
public Project Project { get; set; } = new();
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<nav class="context-nav" aria-label="Project navigation">
|
<nav class="context-nav" aria-label="Project navigation">
|
||||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Timeline</a>
|
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Timeline</a>
|
||||||
|
<a asp-controller="Timeline" asp-action="Settings" asp-route-projectId="@Model.Project.ProjectID">Timeline Settings</a>
|
||||||
<a asp-controller="Scenarios" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Scenarios</a>
|
<a asp-controller="Scenarios" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Scenarios</a>
|
||||||
<a asp-controller="Writer" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Writer Workspace</a>
|
<a asp-controller="Writer" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Writer Workspace</a>
|
||||||
<a asp-controller="StoryBible" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Story Bible</a>
|
<a asp-controller="StoryBible" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Story Bible</a>
|
||||||
@ -42,6 +43,7 @@
|
|||||||
<div class="button-row">
|
<div class="button-row">
|
||||||
<a class="btn btn-outline-secondary" asp-action="Edit" asp-route-id="@Model.Project.ProjectID">Edit project</a>
|
<a class="btn btn-outline-secondary" asp-action="Edit" asp-route-id="@Model.Project.ProjectID">Edit project</a>
|
||||||
<a class="btn btn-outline-primary" asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Timeline</a>
|
<a class="btn btn-outline-primary" asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Timeline</a>
|
||||||
|
<a class="btn btn-outline-secondary" asp-controller="Timeline" asp-action="Settings" asp-route-projectId="@Model.Project.ProjectID">Timeline Settings</a>
|
||||||
<a class="btn btn-outline-primary" asp-controller="Scenarios" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Scenarios</a>
|
<a class="btn btn-outline-primary" asp-controller="Scenarios" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Scenarios</a>
|
||||||
<a class="btn btn-outline-primary" asp-controller="Writer" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Writer Workspace</a>
|
<a class="btn btn-outline-primary" asp-controller="Writer" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Writer Workspace</a>
|
||||||
<a class="btn btn-outline-primary" asp-controller="StoryBible" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Story Bible</a>
|
<a class="btn btn-outline-primary" asp-controller="StoryBible" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Story Bible</a>
|
||||||
|
|||||||
@ -116,6 +116,7 @@
|
|||||||
<nav class="context-nav" aria-label="Workspace navigation">
|
<nav class="context-nav" aria-label="Workspace navigation">
|
||||||
<a asp-controller="Projects" asp-action="Details" asp-route-id="@Model.Project.ProjectID">Project</a>
|
<a asp-controller="Projects" asp-action="Details" asp-route-id="@Model.Project.ProjectID">Project</a>
|
||||||
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Timeline</a>
|
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Timeline</a>
|
||||||
|
<a asp-controller="Timeline" asp-action="Settings" asp-route-projectId="@Model.Project.ProjectID">Timeline Settings</a>
|
||||||
<a asp-controller="Scenarios" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Scenarios</a>
|
<a asp-controller="Scenarios" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Scenarios</a>
|
||||||
<a asp-controller="Analytics" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Story health</a>
|
<a asp-controller="Analytics" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Story health</a>
|
||||||
<a asp-controller="Warnings" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Warnings</a>
|
<a asp-controller="Warnings" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Warnings</a>
|
||||||
@ -155,6 +156,7 @@
|
|||||||
}
|
}
|
||||||
<a class="btn btn-outline-secondary" asp-controller="Warnings" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Warnings</a>
|
<a class="btn btn-outline-secondary" asp-controller="Warnings" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Warnings</a>
|
||||||
<a class="btn btn-outline-secondary" asp-controller="Analytics" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Story health</a>
|
<a class="btn btn-outline-secondary" asp-controller="Analytics" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Story health</a>
|
||||||
|
<a class="btn btn-outline-secondary" asp-controller="Timeline" asp-action="Settings" asp-route-projectId="@Model.Project.ProjectID">Timeline Settings</a>
|
||||||
<a class="btn btn-outline-primary" asp-controller="Scenarios" asp-action="Create" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Create Scenario</a>
|
<a class="btn btn-outline-primary" asp-controller="Scenarios" asp-action="Create" asp-route-projectId="@Model.Project.ProjectID" asp-route-bookId="@Model.SelectedBookID">Create Scenario</a>
|
||||||
<a class="btn btn-outline-secondary" asp-controller="Archives" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Archived Items</a>
|
<a class="btn btn-outline-secondary" asp-controller="Archives" asp-action="Index" asp-route-projectId="@Model.Project.ProjectID">Archived Items</a>
|
||||||
</div>
|
</div>
|
||||||
@ -280,13 +282,12 @@
|
|||||||
<option value="scene-detail">Scene Detail</option>
|
<option value="scene-detail">Scene Detail</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label><input type="checkbox" data-timeline-toggle="scene-cards" checked /> Scene cards</label>
|
@if (Model.Settings.ShowSceneCards) { <label><input type="checkbox" data-timeline-toggle="scene-cards" checked /> Scene cards</label> }
|
||||||
<label><input type="checkbox" data-timeline-toggle="plot-lines" checked /> Plot lines</label>
|
@if (Model.Settings.ShowPlotLines) { <label><input type="checkbox" data-timeline-toggle="plot-lines" checked /> Plot lines</label> }
|
||||||
<label><input type="checkbox" data-timeline-toggle="assets" checked /> Story assets</label>
|
@if (Model.Settings.ShowStoryAssets) { <label><input type="checkbox" data-timeline-toggle="assets" checked /> Story assets</label> }
|
||||||
<label><input type="checkbox" data-timeline-toggle="characters" checked /> Characters</label>
|
@if (Model.Settings.ShowCharacterAppearances) { <label><input type="checkbox" data-timeline-toggle="characters" checked /> Characters</label> }
|
||||||
<label><input type="checkbox" data-timeline-toggle="locations" checked /> Locations</label>
|
@if (Model.Settings.ShowWarnings) { <label><input type="checkbox" data-timeline-toggle="warnings" checked /> Warnings</label> }
|
||||||
<label><input type="checkbox" data-timeline-toggle="warnings" checked /> Warnings</label>
|
@if (Model.Settings.ShowMetricShape) { <label><input type="checkbox" data-timeline-toggle="metrics" checked /> Metrics</label> }
|
||||||
<label><input type="checkbox" data-timeline-toggle="metrics" checked /> Metrics</label>
|
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
@ -575,6 +576,8 @@ else
|
|||||||
<div class="workspace-layout timeline-filtered-root @(hasSelectedScene ? "inspector-drawer-open" : "inspector-drawer-closed")" data-timeline-root>
|
<div class="workspace-layout timeline-filtered-root @(hasSelectedScene ? "inspector-drawer-open" : "inspector-drawer-closed")" data-timeline-root>
|
||||||
<main class="timeline-workspace">
|
<main class="timeline-workspace">
|
||||||
<section class="timeline-shell workspace-timeline" data-timeline-section="scene-cards" style="--scene-count:@timelineColumns.Count">
|
<section class="timeline-shell workspace-timeline" data-timeline-section="scene-cards" style="--scene-count:@timelineColumns.Count">
|
||||||
|
@if (Model.Settings.ShowSceneCards)
|
||||||
|
{
|
||||||
<div class="timeline-section-header" data-collapse-target="scene-cards">
|
<div class="timeline-section-header" data-collapse-target="scene-cards">
|
||||||
<button type="button" data-collapse-toggle="scene-cards">Scene Cards</button>
|
<button type="button" data-collapse-toggle="scene-cards">Scene Cards</button>
|
||||||
<span>@Model.OrderedScenes.Count scene@(Model.OrderedScenes.Count == 1 ? "" : "s")</span>
|
<span>@Model.OrderedScenes.Count scene@(Model.OrderedScenes.Count == 1 ? "" : "s")</span>
|
||||||
@ -659,13 +662,16 @@ else
|
|||||||
<span class="scene-pov-label">@povLabel</span>
|
<span class="scene-pov-label">@povLabel</span>
|
||||||
<div class="scene-badge-row">
|
<div class="scene-badge-row">
|
||||||
<span class="status-pill">@scene.RevisionStatusName</span>
|
<span class="status-pill">@scene.RevisionStatusName</span>
|
||||||
@if (scene.WarningCount > 0)
|
@if (Model.Settings.ShowWarnings)
|
||||||
{
|
{
|
||||||
<span class="warning-placeholder active" data-warning-marker>@scene.WarningCount warning@(scene.WarningCount == 1 ? "" : "s")</span>
|
if (scene.WarningCount > 0)
|
||||||
}
|
{
|
||||||
else
|
<span class="warning-placeholder active" data-warning-marker>@scene.WarningCount warning@(scene.WarningCount == 1 ? "" : "s")</span>
|
||||||
{
|
}
|
||||||
<span class="warning-placeholder">Warnings 0</span>
|
else
|
||||||
|
{
|
||||||
|
<span class="warning-placeholder">Warnings 0</span>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@if (scene.DependencyCount > 0)
|
@if (scene.DependencyCount > 0)
|
||||||
{
|
{
|
||||||
@ -704,6 +710,9 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
@if (Model.Settings.ShowMetricShape)
|
||||||
|
{
|
||||||
<div class="metric-timeline-board" data-timeline-section="metrics" style="--scene-count:@timelineColumns.Count">
|
<div class="metric-timeline-board" data-timeline-section="metrics" style="--scene-count:@timelineColumns.Count">
|
||||||
<div class="lane-board-heading metric-lane-board-heading">
|
<div class="lane-board-heading metric-lane-board-heading">
|
||||||
<button type="button" data-collapse-toggle="metrics">Metric Shape</button>
|
<button type="button" data-collapse-toggle="metrics">Metric Shape</button>
|
||||||
@ -777,9 +786,12 @@ else
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@if (Model.PlotLanes.Any() && Model.OrderedScenes.Any())
|
}
|
||||||
|
@if (Model.Settings.ShowPlotLines)
|
||||||
{
|
{
|
||||||
<div class="plot-lane-board" data-timeline-section="plot-lines" style="--scene-count:@timelineColumns.Count">
|
if (Model.PlotLanes.Any() && Model.OrderedScenes.Any())
|
||||||
|
{
|
||||||
|
<div class="plot-lane-board" data-timeline-section="plot-lines" style="--scene-count:@timelineColumns.Count">
|
||||||
<div class="lane-board-heading plot-lane-board-heading">
|
<div class="lane-board-heading plot-lane-board-heading">
|
||||||
<button type="button" data-collapse-toggle="plot-lines">Plot line lanes</button>
|
<button type="button" data-collapse-toggle="plot-lines">Plot line lanes</button>
|
||||||
<small>Thread event markers by scene</small>
|
<small>Thread event markers by scene</small>
|
||||||
@ -838,17 +850,20 @@ else
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="future-lane-placeholder">
|
||||||
|
Add visible plot lines and thread events to see narrative lanes here.
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
@if (Model.Settings.ShowStoryAssets)
|
||||||
{
|
{
|
||||||
<div class="future-lane-placeholder">
|
if (Model.AssetLanes.Any() && Model.OrderedScenes.Any())
|
||||||
Add visible plot lines and thread events to see narrative lanes here.
|
{
|
||||||
</div>
|
<div class="asset-lane-board" data-timeline-section="assets" style="--scene-count:@timelineColumns.Count">
|
||||||
}
|
|
||||||
@if (Model.AssetLanes.Any() && Model.OrderedScenes.Any())
|
|
||||||
{
|
|
||||||
<div class="asset-lane-board" data-timeline-section="assets" style="--scene-count:@timelineColumns.Count">
|
|
||||||
<div class="lane-board-heading asset-lane-board-heading">
|
<div class="lane-board-heading asset-lane-board-heading">
|
||||||
<button type="button" data-collapse-toggle="assets">Story asset lanes</button>
|
<button type="button" data-collapse-toggle="assets">Story asset lanes</button>
|
||||||
<small>Asset event markers by scene</small>
|
<small>Asset event markers by scene</small>
|
||||||
@ -902,17 +917,20 @@ else
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="future-lane-placeholder">
|
||||||
|
Add story assets and asset events to see asset lanes here.
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
@if (Model.Settings.ShowCharacterAppearances)
|
||||||
{
|
{
|
||||||
<div class="future-lane-placeholder">
|
if (Model.CharacterLanes.Any() && Model.OrderedScenes.Any())
|
||||||
Add story assets and asset events to see asset lanes here.
|
{
|
||||||
</div>
|
<div class="character-lane-board" data-timeline-section="characters" style="--scene-count:@timelineColumns.Count">
|
||||||
}
|
|
||||||
@if (Model.CharacterLanes.Any() && Model.OrderedScenes.Any())
|
|
||||||
{
|
|
||||||
<div class="character-lane-board" data-timeline-section="characters" style="--scene-count:@timelineColumns.Count">
|
|
||||||
<div class="lane-board-heading character-lane-board-heading">
|
<div class="lane-board-heading character-lane-board-heading">
|
||||||
<button type="button" data-collapse-toggle="characters">Character appearances</button>
|
<button type="button" data-collapse-toggle="characters">Character appearances</button>
|
||||||
<small>All project characters, grouped by role and activity</small>
|
<small>All project characters, grouped by role and activity</small>
|
||||||
@ -971,13 +989,14 @@ else
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="future-lane-placeholder">
|
<div class="future-lane-placeholder">
|
||||||
Add characters to scenes to see character appearance lanes here.
|
Add characters to scenes to see character appearance lanes here.
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
130
PlotLine/Views/Timeline/Settings.cshtml
Normal file
130
PlotLine/Views/Timeline/Settings.cshtml
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
@model TimelineSettingsViewModel
|
||||||
|
@{
|
||||||
|
ViewData["Title"] = "Timeline Settings";
|
||||||
|
}
|
||||||
|
|
||||||
|
<nav class="breadcrumb-trail" aria-label="Breadcrumb">
|
||||||
|
<a asp-controller="Projects" asp-action="Index">Projects</a>
|
||||||
|
<a asp-controller="Projects" asp-action="Details" asp-route-id="@Model.ProjectID">@Model.ProjectName</a>
|
||||||
|
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.ProjectID">Timeline</a>
|
||||||
|
<span>Timeline Settings</span>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<section class="context-header">
|
||||||
|
<div class="context-title">
|
||||||
|
<span class="eyebrow">Display configuration</span>
|
||||||
|
<strong>@Model.ProjectName</strong>
|
||||||
|
</div>
|
||||||
|
<nav class="context-nav" aria-label="Timeline settings navigation">
|
||||||
|
<a asp-controller="Timeline" asp-action="Index" asp-route-projectId="@Model.ProjectID">Open timeline</a>
|
||||||
|
<a asp-controller="Projects" asp-action="Details" asp-route-id="@Model.ProjectID">Project</a>
|
||||||
|
</nav>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="page-heading compact">
|
||||||
|
<div>
|
||||||
|
<p class="eyebrow">Timeline Settings</p>
|
||||||
|
<h1>Configure timeline display</h1>
|
||||||
|
<p class="lead-text">Choose which workspace sections PlotLine loads and renders for this project. Filters and saved views still work separately.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (TempData["TimelineSettingsMessage"] is string message)
|
||||||
|
{
|
||||||
|
<div class="alert alert-info">@message</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<form asp-action="Settings" method="post" class="timeline-settings-form">
|
||||||
|
<input type="hidden" asp-for="ProjectID" />
|
||||||
|
<input type="hidden" asp-for="ProjectName" />
|
||||||
|
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||||
|
|
||||||
|
<section class="story-bible-section timeline-settings-section">
|
||||||
|
<div class="story-bible-section-heading">
|
||||||
|
<div>
|
||||||
|
<p class="eyebrow">Sections</p>
|
||||||
|
<h2>Workspace sections</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-settings-grid">
|
||||||
|
<label class="timeline-setting-card">
|
||||||
|
<input asp-for="ShowSceneCards" />
|
||||||
|
<span>
|
||||||
|
<strong>Scene Cards</strong>
|
||||||
|
<small>Shows books, chapters and scene cards in narrative order.</small>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label class="timeline-setting-card">
|
||||||
|
<input asp-for="ShowMetricShape" />
|
||||||
|
<span>
|
||||||
|
<strong>Metric Shape</strong>
|
||||||
|
<small>Shows emotional and pacing metrics beneath the scene timeline.</small>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label class="timeline-setting-card">
|
||||||
|
<input asp-for="ShowPlotLines" />
|
||||||
|
<span>
|
||||||
|
<strong>Plot Lines</strong>
|
||||||
|
<small>Shows plot thread activity across the scene timeline.</small>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label class="timeline-setting-card">
|
||||||
|
<input asp-for="ShowStoryAssets" />
|
||||||
|
<span>
|
||||||
|
<strong>Story Assets</strong>
|
||||||
|
<small>Shows clues, objects, evidence and state changes by scene.</small>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label class="timeline-setting-card">
|
||||||
|
<input asp-for="ShowCharacterAppearances" />
|
||||||
|
<span>
|
||||||
|
<strong>Character Appearances</strong>
|
||||||
|
<small>Shows which characters appear in each scene.</small>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<label class="timeline-setting-card">
|
||||||
|
<input asp-for="ShowWarnings" />
|
||||||
|
<span>
|
||||||
|
<strong>Warning Indicators</strong>
|
||||||
|
<small>Shows continuity warning counts and warning-focused timeline cues.</small>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="story-bible-section timeline-settings-section">
|
||||||
|
<div class="story-bible-section-heading">
|
||||||
|
<div>
|
||||||
|
<p class="eyebrow">Metric Shape</p>
|
||||||
|
<h2>Timeline metrics</h2>
|
||||||
|
</div>
|
||||||
|
<span class="soft-count">@Model.MetricOptions.Count metrics</span>
|
||||||
|
</div>
|
||||||
|
<p class="muted">These metrics appear on the timeline graph only. Story Health can continue using the full metric set.</p>
|
||||||
|
<span asp-validation-for="SelectedMetricTypeIDs" class="text-danger"></span>
|
||||||
|
<div class="timeline-settings-grid timeline-metric-settings-grid">
|
||||||
|
@foreach (var metric in Model.MetricOptions)
|
||||||
|
{
|
||||||
|
<label class="timeline-setting-card metric-setting-card">
|
||||||
|
<input type="checkbox" name="SelectedMetricTypeIDs" value="@metric.MetricTypeID" checked="@metric.IsSelected" />
|
||||||
|
<span>
|
||||||
|
<strong>@metric.MetricName</strong>
|
||||||
|
@if (!string.IsNullOrWhiteSpace(metric.Description))
|
||||||
|
{
|
||||||
|
<small>@metric.Description</small>
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="button-row">
|
||||||
|
<button class="btn btn-primary" type="submit">Save settings</button>
|
||||||
|
<a class="btn btn-outline-secondary" asp-action="Index" asp-route-projectId="@Model.ProjectID">Back to timeline</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
@section Scripts {
|
||||||
|
<partial name="_ValidationScriptsPartial" />
|
||||||
|
}
|
||||||
@ -870,6 +870,62 @@ a:focus-visible {
|
|||||||
background: rgba(122, 77, 44, 0.1);
|
background: rgba(122, 77, 44, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-settings-form {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
max-width: 1180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-settings-section {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-settings-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-setting-card {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto minmax(0, 1fr);
|
||||||
|
gap: 0.72rem;
|
||||||
|
align-items: start;
|
||||||
|
min-height: 92px;
|
||||||
|
border: 1px solid rgba(84, 68, 48, 0.13);
|
||||||
|
border-radius: var(--plotline-radius-sm);
|
||||||
|
padding: 0.85rem;
|
||||||
|
background: rgba(255, 253, 248, 0.82);
|
||||||
|
box-shadow: var(--plotline-shadow-subtle);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-setting-card input {
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
accent-color: var(--plotline-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-setting-card strong,
|
||||||
|
.timeline-setting-card small {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-setting-card strong {
|
||||||
|
color: #211915;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-setting-card small {
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
color: var(--plotline-text-muted);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-setting-card:has(input:checked) {
|
||||||
|
border-color: rgba(49, 95, 103, 0.25);
|
||||||
|
background: linear-gradient(135deg, rgba(223, 236, 239, 0.52), rgba(255, 253, 248, 0.92));
|
||||||
|
}
|
||||||
|
|
||||||
.plotline-confirm-modal .modal-title {
|
.plotline-confirm-modal .modal-title {
|
||||||
font-family: Georgia, "Times New Roman", serif;
|
font-family: Georgia, "Times New Roman", serif;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user