@ -1 +1,5 @@ | |||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#C5C5C5"/><rect height="3" width="11" y="7" x="3" fill="#C5C5C5"/></svg> | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<rect fill="#C5C5C5" x="6.5" y="5.5" width="3" height="11"/> | |||
<rect fill="#C5C5C5" x="2.5" y="9.5" width="11" height="3"/> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#C5C5C5" d="m13,8c0,-1.11 -0.89,-2 -2,-2c-1.11,0 -2,0.89 -2,2c0,0.73 0.41,1.38 1,1.72l0,0.3c-0.02,0.52 -0.23,0.98 -0.63,1.38c-0.4,0.4 -0.86,0.61 -1.38,0.63c-0.83,0.02 -1.48,0.16 -2,0.45l0,-4.76c0.59,-0.34 1,-0.98 1,-1.72c0,-1.11 -0.89,-2 -2,-2c-1.11,0 -1.99,0.89 -1.99,2c0,0.73 0.41,1.38 1,1.72l0,6.56c-0.59,0.35 -1,0.99 -1,1.72c0,1.11 0.89,2 2,2c1.11,0 2,-0.89 2,-2c0,-0.53 -0.2,-1 -0.53,-1.36c0.09,-0.06 0.48,-0.41 0.59,-0.47c0.25,-0.11 0.56,-0.17 0.94,-0.17c1.05,-0.05 1.95,-0.45 2.75,-1.25c0.8,-0.8 1.2,-1.98 1.25,-3.02l-0.02,0c0.61,-0.36 1.02,-1 1.02,-1.73l0,0zm-8,-3.2c0.66,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2c-0.65,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2l0,0zm0,12.41c-0.66,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2c0.65,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2l0,0zm6,-8c-0.66,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2c0.65,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2l0,0z" /> | |||
</svg> |
@ -1,4 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256" height="256" viewBox="0 0 14 16" xml:space="preserve"> | |||
<path fill="#C5C5C5" d="M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z"></path> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#C5C5C5" d="m11.86,10c-0.45,-1.72 -2,-3 -3.86,-3c-1.86,0 -3.41,1.28 -3.86,3l-3.14,0l0,2l3.14,0c0.45,1.72 2,3 3.86,3c1.86,0 3.41,-1.28 3.86,-3l3.14,0l0,-2l-3.14,0zm-3.86,3.2c-1.22,0 -2.2,-0.98 -2.2,-2.2c0,-1.22 0.98,-2.2 2.2,-2.2c1.22,0 2.2,0.98 2.2,2.2c0,1.22 -0.98,2.2 -2.2,2.2z"></path> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#C5C5C5" d="m9,15l2,0l-3,3l-3,-3l2,0l0,-5l2,0l0,5l0,0zm3,-8c0,-0.44 -0.91,-3 -4.5,-3c-2.42,0 -4.5,1.92 -4.5,4c-1.98,0 -3,1.52 -3,3c0,1.53 1,3 3,3l3,0l0,-1.3l-3,0c-1.62,0 -1.7,-1.42 -1.7,-1.7c0,-0.17 0.05,-1.7 1.7,-1.7l1.3,0l0,-1.3c0,-1.39 1.56,-2.7 3.2,-2.7c2.55,0 3.13,1.55 3.2,1.8l0,1.2l1.3,0c0.81,0 2.7,0.22 2.7,2.2c0,2.09 -2.25,2.2 -2.7,2.2l-2,0l0,1.3l2,0c2.08,0 4,-1.16 4,-3.5c0,-2.44 -1.92,-3.5 -4,-3.5l0,0z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#C5C5C5" d="m9,16l-2,0l0,-7l5,0l0,2l-3,0l0,5l0,0zm-1,-12c-2.19,0 -4.13,1.02 -5.41,2.59l-1.59,-1.59l0,4l4,0l-1.5,-1.5c1.05,-1.33 2.67,-2.2 4.5,-2.2c3.14,0 5.7,2.56 5.7,5.7c0,3.14 -2.56,5.7 -5.7,5.7c-3.14,0 -5.7,-2.56 -5.7,-5.7c0,-0.34 0.03,-0.67 0.09,-1l-1.31,0c-0.05,0.33 -0.08,0.66 -0.08,1c0,3.86 3.14,7 7,7c3.86,0 7,-3.14 7,-7c0,-3.86 -3.14,-7 -7,-7l0,0z" /> | |||
</svg> |
@ -1,5 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"> | |||
<path d="M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3a2.98 2.98 0 0 1-2.107-.868 2.98 2.98 0 0 1-.873-2.111 3.004 3.004 0 0 1 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012L13.115 4.1 8.196 0H7.059v2.404A6.759 6.759 0 0 0 .938 9.125c0 1.809.707 3.508 1.986 4.782a6.707 6.707 0 0 0 4.784 1.988 6.758 6.758 0 0 0 6.75-6.75 6.741 6.741 0 0 0-1.007-3.536z" fill="#2D2D30"/> | |||
<path d="M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4a3.986 3.986 0 0 1-2.817-1.164 3.987 3.987 0 0 1-1.163-2.815c0-2.206 1.794-4 4-4l.351.025v1.85S9.685 5.679 9.69 5.682l1.869-1.577-3.5-2.917v2.218l-.371-.03a5.75 5.75 0 0 0-4.055 9.826 5.75 5.75 0 0 0 9.826-4.056 5.725 5.725 0 0 0-.859-3.012z" fill="#C5C5C5"/> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#C5C5C5" d="m12.901149,9.091851l-0.094,0.071c-0.269,0.333 -0.746,1.096 -0.91,2.375c0.057,0.277 0.092,0.495 0.092,0.545c0,2.206 -1.794,4 -4,4a3.986,3.986 0 0 1 -2.817,-1.164a3.987,3.987 0 0 1 -1.163,-2.815c0,-2.206 1.794,-4 4,-4l0.351,0.025l0,1.85s1.626,-1.342 1.631,-1.339l1.869,-1.577l-3.5,-2.917l0,2.218l-0.371,-0.03a5.75,5.75 0 0 0 -4.055,9.826a5.75,5.75 0 0 0 9.826,-4.056a5.725,5.725 0 0 0 -0.859,-3.012z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#C5C5C5" d="m12.519592,15.157073l-9.039184,0c-1.367793,0 -2.480539,-1.112828 -2.480539,-2.480622s1.112746,-2.480539 2.480539,-2.480539l0.281314,0c0.349178,-0.47173 0.888523,-0.771191 1.476341,-0.815025c0.321917,-1.471535 1.619609,-2.537962 3.165139,-2.537962c1.221543,0 2.341663,0.699516 2.889377,1.772488c0.083027,-0.008618 0.166386,-0.012926 0.250076,-0.012926c1.190221,0 2.194667,0.874105 2.378785,2.027867c0.670514,0.460047 1.07869,1.225023 1.07869,2.046096c0,1.367793 -1.112828,2.480622 -2.480539,2.480622z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#C5C5C5" d="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#C5C5C5" d="m14.414133,16.199437l-3.415492,-3.433421c0.627518,-0.878526 0.995065,-1.945307 0.995065,-3.110698c0,-2.967265 -2.411463,-5.378728 -5.378728,-5.378728c-2.967265,0 -5.378728,2.411463 -5.378728,5.378728c0,2.967265 2.411463,5.378728 5.378728,5.378728c1.165391,0 2.223207,-0.367546 3.110698,-0.995065l3.433421,3.415492c0.170326,0.179291 0.403405,0.268936 0.627518,0.268936c0.224114,0 0.466156,-0.080681 0.627518,-0.268936c0.349617,-0.349617 0.349617,-0.914384 0,-1.264001l0,0.008965zm-7.799155,-2.330782c-2.321817,0 -4.213337,-1.891519 -4.213337,-4.213337c0,-2.321817 1.891519,-4.213337 4.213337,-4.213337c2.321817,0 4.213337,1.891519 4.213337,4.213337c0,2.321817 -1.891519,4.213337 -4.213337,4.213337l0,0z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="22px"> | |||
<path fill="#C5C5C5" d="m14.687501,11.955358l-1.079554,-6.821251c-0.076429,-0.458572 -0.477679,-0.821607 -0.955357,-0.821607l-9.30518,0c-0.477679,0 -0.878929,0.363036 -0.955357,0.821607l-1.079554,6.821251l0,4.776787c0,0.525447 0.429911,0.955357 0.955357,0.955357l11.464288,0c0.525447,0 0.955357,-0.429911 0.955357,-0.955357l0,-4.776787l0,0zm-3.133572,0.525447l-0.420357,0.850268c-0.162411,0.324821 -0.496786,0.535 -0.869375,0.535l-4.547501,0c-0.363036,0 -0.687857,-0.210179 -0.850268,-0.525447l-0.420357,-0.869375c-0.162411,-0.315268 -0.496786,-0.525447 -0.850268,-0.525447l-1.327947,0l0.955357,-6.687501l9.553573,0l0.955357,6.687501l-1.318393,0c-0.372589,0 -0.697411,0.210179 -0.869375,0.525447l0.009554,0.009554z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#C5C5C5" d="m7,12l-2,0l3,-3l3,3l-2,0l0,5l-2,0l0,-5l0,0zm5,-4c0,-0.44 -0.91,-3 -4.5,-3c-2.42,0 -4.5,1.92 -4.5,4c-1.98,0 -3,1.52 -3,3c0,1.53 1,3 3,3l3,0l0,-1.3l-3,0c-1.62,0 -1.7,-1.42 -1.7,-1.7c0,-0.17 0.05,-1.7 1.7,-1.7l1.3,0l0,-1.3c0,-1.39 1.56,-2.7 3.2,-2.7c2.55,0 3.13,1.55 3.2,1.8l0,1.2l1.3,0c0.81,0 2.7,0.22 2.7,2.2c0,2.09 -2.25,2.2 -2.7,2.2l-2,0l0,1.3l2,0c2.08,0 4,-1.16 4,-3.5c0,-2.44 -1.92,-3.5 -4,-3.5l0,0z" /> | |||
</svg> |
@ -1 +1,5 @@ | |||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#424242"/><rect height="3" width="11" y="7" x="3" fill="#424242"/></svg> | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<rect fill="#424242" x="6.5" y="5.5" width="3" height="11"/> | |||
<rect fill="#424242" x="2.5" y="9.5" width="11" height="3"/> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#424242" d="m13,8c0,-1.11 -0.89,-2 -2,-2c-1.11,0 -2,0.89 -2,2c0,0.73 0.41,1.38 1,1.72l0,0.3c-0.02,0.52 -0.23,0.98 -0.63,1.38c-0.4,0.4 -0.86,0.61 -1.38,0.63c-0.83,0.02 -1.48,0.16 -2,0.45l0,-4.76c0.59,-0.34 1,-0.98 1,-1.72c0,-1.11 -0.89,-2 -2,-2c-1.11,0 -1.99,0.89 -1.99,2c0,0.73 0.41,1.38 1,1.72l0,6.56c-0.59,0.35 -1,0.99 -1,1.72c0,1.11 0.89,2 2,2c1.11,0 2,-0.89 2,-2c0,-0.53 -0.2,-1 -0.53,-1.36c0.09,-0.06 0.48,-0.41 0.59,-0.47c0.25,-0.11 0.56,-0.17 0.94,-0.17c1.05,-0.05 1.95,-0.45 2.75,-1.25c0.8,-0.8 1.2,-1.98 1.25,-3.02l-0.02,0c0.61,-0.36 1.02,-1 1.02,-1.73l0,0zm-8,-3.2c0.66,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2c-0.65,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2l0,0zm0,12.41c-0.66,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2c0.65,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2l0,0zm6,-8c-0.66,0 -1.2,-0.55 -1.2,-1.2c0,-0.65 0.55,-1.2 1.2,-1.2c0.65,0 1.2,0.55 1.2,1.2c0,0.65 -0.55,1.2 -1.2,1.2l0,0z" /> | |||
</svg> |
@ -1,4 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256" height="256" viewBox="0 0 14 16" xml:space="preserve"> | |||
<path fill="#6c6c6c" d="M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z"></path> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#424242" d="m11.86,10c-0.45,-1.72 -2,-3 -3.86,-3c-1.86,0 -3.41,1.28 -3.86,3l-3.14,0l0,2l3.14,0c0.45,1.72 2,3 3.86,3c1.86,0 3.41,-1.28 3.86,-3l3.14,0l0,-2l-3.14,0zm-3.86,3.2c-1.22,0 -2.2,-0.98 -2.2,-2.2c0,-1.22 0.98,-2.2 2.2,-2.2c1.22,0 2.2,0.98 2.2,2.2c0,1.22 -0.98,2.2 -2.2,2.2z"></path> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#424242" d="m9,15l2,0l-3,3l-3,-3l2,0l0,-5l2,0l0,5l0,0zm3,-8c0,-0.44 -0.91,-3 -4.5,-3c-2.42,0 -4.5,1.92 -4.5,4c-1.98,0 -3,1.52 -3,3c0,1.53 1,3 3,3l3,0l0,-1.3l-3,0c-1.62,0 -1.7,-1.42 -1.7,-1.7c0,-0.17 0.05,-1.7 1.7,-1.7l1.3,0l0,-1.3c0,-1.39 1.56,-2.7 3.2,-2.7c2.55,0 3.13,1.55 3.2,1.8l0,1.2l1.3,0c0.81,0 2.7,0.22 2.7,2.2c0,2.09 -2.25,2.2 -2.7,2.2l-2,0l0,1.3l2,0c2.08,0 4,-1.16 4,-3.5c0,-2.44 -1.92,-3.5 -4,-3.5l0,0z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#424242" d="m9,16l-2,0l0,-7l5,0l0,2l-3,0l0,5l0,0zm-1,-12c-2.19,0 -4.13,1.02 -5.41,2.59l-1.59,-1.59l0,4l4,0l-1.5,-1.5c1.05,-1.33 2.67,-2.2 4.5,-2.2c3.14,0 5.7,2.56 5.7,5.7c0,3.14 -2.56,5.7 -5.7,5.7c-3.14,0 -5.7,-2.56 -5.7,-5.7c0,-0.34 0.03,-0.67 0.09,-1l-1.31,0c-0.05,0.33 -0.08,0.66 -0.08,1c0,3.86 3.14,7 7,7c3.86,0 7,-3.14 7,-7c0,-3.86 -3.14,-7 -7,-7l0,0z" /> | |||
</svg> |
@ -1,5 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"> | |||
<path d='M13.451 5.609l-.579-.939-1.068.812-.076.094c-.335.415-.927 1.341-1.124 2.876l-.021.165.033.163.071.345c0 1.654-1.346 3-3 3a2.98 2.98 0 0 1-2.107-.868 2.98 2.98 0 0 1-.873-2.111 3.004 3.004 0 0 1 2.351-2.929v2.926s2.528-2.087 2.984-2.461h.012L13.115 4.1 8.196 0H7.059v2.404A6.759 6.759 0 0 0 .938 9.125c0 1.809.707 3.508 1.986 4.782a6.707 6.707 0 0 0 4.784 1.988 6.758 6.758 0 0 0 6.75-6.75 6.741 6.741 0 0 0-1.007-3.536z' fill='#F6F6F6'/> | |||
<path d='M12.6 6.134l-.094.071c-.269.333-.746 1.096-.91 2.375.057.277.092.495.092.545 0 2.206-1.794 4-4 4a3.986 3.986 0 0 1-2.817-1.164 3.987 3.987 0 0 1-1.163-2.815c0-2.206 1.794-4 4-4l.351.025v1.85S9.685 5.679 9.69 5.682l1.869-1.577-3.5-2.917v2.218l-.371-.03a5.75 5.75 0 0 0-4.055 9.826 5.75 5.75 0 0 0 9.826-4.056 5.725 5.725 0 0 0-.859-3.012z' fill='#424242'/> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#424242" d="m12.901149,9.091851l-0.094,0.071c-0.269,0.333 -0.746,1.096 -0.91,2.375c0.057,0.277 0.092,0.495 0.092,0.545c0,2.206 -1.794,4 -4,4a3.986,3.986 0 0 1 -2.817,-1.164a3.987,3.987 0 0 1 -1.163,-2.815c0,-2.206 1.794,-4 4,-4l0.351,0.025l0,1.85s1.626,-1.342 1.631,-1.339l1.869,-1.577l-3.5,-2.917l0,2.218l-0.371,-0.03a5.75,5.75 0 0 0 -4.055,9.826a5.75,5.75 0 0 0 9.826,-4.056a5.725,5.725 0 0 0 -0.859,-3.012z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#424242" d="m12.519592,15.157073l-9.039184,0c-1.367793,0 -2.480539,-1.112828 -2.480539,-2.480622s1.112746,-2.480539 2.480539,-2.480539l0.281314,0c0.349178,-0.47173 0.888523,-0.771191 1.476341,-0.815025c0.321917,-1.471535 1.619609,-2.537962 3.165139,-2.537962c1.221543,0 2.341663,0.699516 2.889377,1.772488c0.083027,-0.008618 0.166386,-0.012926 0.250076,-0.012926c1.190221,0 2.194667,0.874105 2.378785,2.027867c0.670514,0.460047 1.07869,1.225023 1.07869,2.046096c0,1.367793 -1.112828,2.480622 -2.480539,2.480622z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#424242" d="m6,12l-1,0l0,-1l1,0l0,1l0,0zm0,-3l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm0,-2l-1,0l0,1l1,0l0,-1l0,0zm8,-1l0,12c0,0.55 -0.45,1 -1,1l-5,0l0,2l-1.5,-1.5l-1.5,1.5l0,-2l-2,0c-0.55,0 -1,-0.45 -1,-1l0,-12c0,-0.55 0.45,-1 1,-1l10,0c0.55,0 1,0.45 1,1l0,0zm-1,10l-10,0l0,2l2,0l0,-1l3,0l0,1l5,0l0,-2l0,0zm0,-10l-9,0l0,9l9,0l0,-9l0,0z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#424242" d="m14.414133,16.199437l-3.415492,-3.433421c0.627518,-0.878526 0.995065,-1.945307 0.995065,-3.110698c0,-2.967265 -2.411463,-5.378728 -5.378728,-5.378728c-2.967265,0 -5.378728,2.411463 -5.378728,5.378728c0,2.967265 2.411463,5.378728 5.378728,5.378728c1.165391,0 2.223207,-0.367546 3.110698,-0.995065l3.433421,3.415492c0.170326,0.179291 0.403405,0.268936 0.627518,0.268936c0.224114,0 0.466156,-0.080681 0.627518,-0.268936c0.349617,-0.349617 0.349617,-0.914384 0,-1.264001l0,0.008965zm-7.799155,-2.330782c-2.321817,0 -4.213337,-1.891519 -4.213337,-4.213337c0,-2.321817 1.891519,-4.213337 4.213337,-4.213337c2.321817,0 4.213337,1.891519 4.213337,4.213337c0,2.321817 -1.891519,4.213337 -4.213337,4.213337l0,0z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="22px"> | |||
<path fill="#424242" d="m14.687501,11.955358l-1.079554,-6.821251c-0.076429,-0.458572 -0.477679,-0.821607 -0.955357,-0.821607l-9.30518,0c-0.477679,0 -0.878929,0.363036 -0.955357,0.821607l-1.079554,6.821251l0,4.776787c0,0.525447 0.429911,0.955357 0.955357,0.955357l11.464288,0c0.525447,0 0.955357,-0.429911 0.955357,-0.955357l0,-4.776787l0,0zm-3.133572,0.525447l-0.420357,0.850268c-0.162411,0.324821 -0.496786,0.535 -0.869375,0.535l-4.547501,0c-0.363036,0 -0.687857,-0.210179 -0.850268,-0.525447l-0.420357,-0.869375c-0.162411,-0.315268 -0.496786,-0.525447 -0.850268,-0.525447l-1.327947,0l0.955357,-6.687501l9.553573,0l0.955357,6.687501l-1.318393,0c-0.372589,0 -0.697411,0.210179 -0.869375,0.525447l0.009554,0.009554z" /> | |||
</svg> |
@ -0,0 +1,4 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<svg width="16" height="22" version="1.1" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#424242" d="m7,12l-2,0l3,-3l3,3l-2,0l0,5l-2,0l0,-5l0,0zm5,-4c0,-0.44 -0.91,-3 -4.5,-3c-2.42,0 -4.5,1.92 -4.5,4c-1.98,0 -3,1.52 -3,3c0,1.53 1,3 3,3l3,0l0,-1.3l-3,0c-1.62,0 -1.7,-1.42 -1.7,-1.7c0,-0.17 0.05,-1.7 1.7,-1.7l1.3,0l0,-1.3c0,-1.39 1.56,-2.7 3.2,-2.7c2.55,0 3.13,1.55 3.2,1.8l0,1.2l1.3,0c0.81,0 2.7,0.22 2.7,2.2c0,2.09 -2.25,2.2 -2.7,2.2l-2,0l0,1.3l2,0c2.08,0 4,-1.16 4,-3.5c0,-2.44 -1.92,-3.5 -4,-3.5l0,0z" /> | |||
</svg> |
@ -1,89 +0,0 @@ | |||
'use strict'; | |||
// import { Arrays } from '../system'; | |||
import { commands, Event, EventEmitter, ExtensionContext, TextEditor, TreeDataProvider, TreeItem, Uri, window } from 'vscode'; | |||
import { Commands, DiffWithPreviousCommandArgs, openEditor, OpenFileInRemoteCommandArgs } from '../commands'; | |||
import { UriComparer } from '../comparers'; | |||
import { CommitNode, ExplorerNode, FileHistoryNode, TextExplorerNode } from './explorerNodes'; | |||
import { GitService, GitUri } from '../gitService'; | |||
export * from './explorerNodes'; | |||
export class FileHistoryExplorer implements TreeDataProvider<ExplorerNode> { | |||
private _node?: ExplorerNode; | |||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>(); | |||
public get onDidChangeTreeData(): Event<ExplorerNode> { | |||
return this._onDidChangeTreeData.event; | |||
} | |||
constructor(private context: ExtensionContext, private git: GitService) { | |||
commands.registerCommand('gitlens.fileHistoryExplorer.refresh', this.refresh, this); | |||
commands.registerCommand('gitlens.fileHistoryExplorer.openChanges', this.openChanges, this); | |||
commands.registerCommand('gitlens.fileHistoryExplorer.openFile', this.openFile, this); | |||
commands.registerCommand('gitlens.fileHistoryExplorer.openFileRevision', this.openFileRevision, this); | |||
commands.registerCommand('gitlens.fileHistoryExplorer.openFileInRemote', this.openFileInRemote, this); | |||
commands.registerCommand('gitlens.fileHistoryExplorer.openFileRevisionInRemote', this.openFileRevisionInRemote, this); | |||
context.subscriptions.push(window.onDidChangeActiveTextEditor(this.onActiveEditorChanged, this)); | |||
this._node = this.getRootNode(window.activeTextEditor); | |||
} | |||
async getTreeItem(node: ExplorerNode): Promise<TreeItem> { | |||
return node.getTreeItem(); | |||
} | |||
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> { | |||
if (this._node === undefined) return [new TextExplorerNode('No active file')]; | |||
if (node === undefined) return this._node.getChildren(); | |||
return node.getChildren(); | |||
} | |||
private getRootNode(editor: TextEditor | undefined): ExplorerNode | undefined { | |||
if (window.visibleTextEditors.length === 0) return undefined; | |||
if (editor === undefined) return this._node; | |||
const uri = this.git.getGitUriForFile(editor.document.uri) || new GitUri(editor.document.uri, { repoPath: this.git.repoPath, fileName: editor.document.uri.fsPath }); | |||
if (UriComparer.equals(uri, this._node && this._node.uri)) return this._node; | |||
return new FileHistoryNode(uri, this.context, this.git); | |||
} | |||
private onActiveEditorChanged(editor: TextEditor | undefined) { | |||
const node = this.getRootNode(editor); | |||
if (node === this._node) return; | |||
this.refresh(); | |||
} | |||
refresh(node?: ExplorerNode) { | |||
this._node = node || this.getRootNode(window.activeTextEditor); | |||
this._onDidChangeTreeData.fire(); | |||
} | |||
private openChanges(node: CommitNode) { | |||
const command = node.getCommand(); | |||
if (command === undefined || command.arguments === undefined) return; | |||
const [uri, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs]; | |||
args.showOptions!.preview = false; | |||
return commands.executeCommand(command.command, uri, args); | |||
} | |||
private openFile(node: CommitNode) { | |||
return openEditor(node.uri, { preserveFocus: true, preview: false }); | |||
} | |||
private openFileRevision(node: CommitNode) { | |||
return openEditor(GitService.toGitContentUri(node.uri), { preserveFocus: true, preview: false }); | |||
} | |||
private async openFileInRemote(node: CommitNode) { | |||
return commands.executeCommand(Commands.OpenFileInRemote, node.commit.uri, { range: false } as OpenFileInRemoteCommandArgs); | |||
} | |||
private async openFileRevisionInRemote(node: CommitNode) { | |||
return commands.executeCommand(Commands.OpenFileInRemote, new GitUri(node.commit.uri, node.commit), { range: false } as OpenFileInRemoteCommandArgs); | |||
} | |||
} |
@ -1,73 +1,162 @@ | |||
'use strict'; | |||
// import { Functions } from '../system'; | |||
import { commands, Event, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, Uri } from 'vscode'; | |||
import { Functions } from '../system'; | |||
import { commands, Event, EventEmitter, ExtensionContext, TextDocumentShowOptions, TextEditor, TreeDataProvider, TreeItem, Uri, window } from 'vscode'; | |||
import { Commands, DiffWithPreviousCommandArgs, DiffWithWorkingCommandArgs, openEditor, OpenFileInRemoteCommandArgs } from '../commands'; | |||
import { UriComparer } from '../comparers'; | |||
import { ExplorerNode, FileHistoryNode, RepositoryNode, ResourceType, StashNode } from './explorerNodes'; | |||
import { CommandContext, setCommandContext } from '../constants'; | |||
import { CommitFileNode, CommitNode, ExplorerNode, HistoryNode, MessageNode, RepositoryNode, StashNode } from './explorerNodes'; | |||
import { GitService, GitUri } from '../gitService'; | |||
export * from './explorerNodes'; | |||
export type GitExplorerView = | |||
'history' | | |||
'repository'; | |||
export const GitExplorerView = { | |||
History: 'history' as GitExplorerView, | |||
Repository: 'repository' as GitExplorerView | |||
}; | |||
export interface OpenFileRevisionCommandArgs { | |||
uri?: Uri; | |||
showOptions?: TextDocumentShowOptions; | |||
} | |||
export class GitExplorer implements TreeDataProvider<ExplorerNode> { | |||
// private _refreshDebounced: () => void; | |||
private _root?: ExplorerNode; | |||
private _view: GitExplorerView = GitExplorerView.Repository; | |||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>(); | |||
public get onDidChangeTreeData(): Event<ExplorerNode> { | |||
return this._onDidChangeTreeData.event; | |||
} | |||
private _roots: ExplorerNode[] = []; | |||
constructor(private readonly context: ExtensionContext, private readonly git: GitService) { | |||
commands.registerCommand('gitlens.gitExplorer.switchToHistoryView', () => this.switchTo(GitExplorerView.History), this); | |||
commands.registerCommand('gitlens.gitExplorer.switchToRepositoryView', () => this.switchTo(GitExplorerView.Repository), this); | |||
commands.registerCommand('gitlens.gitExplorer.refresh', this.refresh, this); | |||
commands.registerCommand('gitlens.gitExplorer.openChanges', this.openChanges, this); | |||
commands.registerCommand('gitlens.gitExplorer.openChangesWithWorking', this.openChangesWithWorking, this); | |||
commands.registerCommand('gitlens.gitExplorer.openFile', this.openFile, this); | |||
commands.registerCommand('gitlens.gitExplorer.openFileRevision', this.openFileRevision, this); | |||
commands.registerCommand('gitlens.gitExplorer.openFileRevisionInRemote', this.openFileRevisionInRemote, this); | |||
commands.registerCommand('gitlens.gitExplorer.openChangedFiles', this.openChangedFiles, this); | |||
commands.registerCommand('gitlens.gitExplorer.openChangedFileRevisions', this.openChangedFileRevisions, this); | |||
const fn = Functions.debounce(this.onActiveEditorChanged, 500); | |||
context.subscriptions.push(window.onDidChangeActiveTextEditor(fn, this)); | |||
this._view = this.git.config.gitExplorer.view; | |||
setCommandContext(CommandContext.GitExplorerView, this._view); | |||
this._root = this.getRootNode(); | |||
} | |||
constructor(private context: ExtensionContext, private git: GitService) { | |||
commands.registerCommand('gitlens.gitExplorer.refresh', () => this.refresh()); | |||
async getTreeItem(node: ExplorerNode): Promise<TreeItem> { | |||
return node.getTreeItem(); | |||
} | |||
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> { | |||
if (this._root === undefined) { | |||
if (this._view === GitExplorerView.History) return [new MessageNode('No active file; no history to show')]; | |||
return []; | |||
} | |||
// this._refreshDebounced = Functions.debounce(this.refresh.bind(this), 250); | |||
if (node === undefined) return this._root.getChildren(); | |||
return node.getChildren(); | |||
} | |||
// const editor = window.activeTextEditor; | |||
private getRootNode(editor?: TextEditor): ExplorerNode | undefined { | |||
const uri = new GitUri(Uri.file(this.git.repoPath), { repoPath: this.git.repoPath, fileName: this.git.repoPath }); | |||
// const uri = (editor !== undefined && editor.document !== undefined) | |||
// ? new GitUri(editor.document.uri, { repoPath: git.repoPath, fileName: editor.document.uri.fsPath }) | |||
// : new GitUri(Uri.file(git.repoPath), { repoPath: git.repoPath, fileName: git.repoPath }); | |||
switch (this._view) { | |||
case GitExplorerView.History: return this.getHistoryNode(editor || window.activeTextEditor); | |||
case GitExplorerView.Repository: return new RepositoryNode(uri, this.context, this.git); | |||
} | |||
const uri = new GitUri(Uri.file(git.repoPath), { repoPath: git.repoPath, fileName: git.repoPath }); | |||
this._roots.push(new RepositoryNode(uri, context, git)); | |||
return undefined; | |||
} | |||
async getTreeItem(node: ExplorerNode): Promise<TreeItem> { | |||
// if (node.onDidChangeTreeData !== undefined) { | |||
// node.onDidChangeTreeData(() => setTimeout(this._refreshDebounced, 1)); | |||
// } | |||
return node.getTreeItem(); | |||
private getHistoryNode(editor: TextEditor | undefined): ExplorerNode | undefined { | |||
if (window.visibleTextEditors.length === 0) return undefined; | |||
if (editor === undefined) return this._root; | |||
const uri = this.git.getGitUriForFile(editor.document.uri) || new GitUri(editor.document.uri, { repoPath: this.git.repoPath, fileName: editor.document.uri.fsPath }); | |||
if (UriComparer.equals(uri, this._root && this._root.uri)) return this._root; | |||
return new HistoryNode(uri, this.context, this.git); | |||
} | |||
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> { | |||
if (this._roots.length === 0) return []; | |||
if (node === undefined) return this._roots; | |||
private onActiveEditorChanged(editor: TextEditor | undefined) { | |||
if (this._view !== GitExplorerView.History) return; | |||
const root = this.getRootNode(editor); | |||
if (root === this._root) return; | |||
return node.getChildren(); | |||
this.refresh(root); | |||
} | |||
addHistory(uri: GitUri) { | |||
this._add(uri, FileHistoryNode); | |||
refresh(root?: ExplorerNode) { | |||
this._root = root || this.getRootNode(); | |||
this._onDidChangeTreeData.fire(); | |||
} | |||
switchTo(view: GitExplorerView) { | |||
if (this._view === view) return; | |||
this._view = view; | |||
setCommandContext(CommandContext.GitExplorerView, this._view); | |||
this._root = undefined; | |||
this.refresh(); | |||
} | |||
private openChanges(node: CommitNode | StashNode) { | |||
const command = node.getCommand(); | |||
if (command === undefined || command.arguments === undefined) return; | |||
const [uri, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs]; | |||
args.showOptions!.preview = false; | |||
return commands.executeCommand(command.command, uri, args); | |||
} | |||
addStash(uri: GitUri) { | |||
this._add(uri, StashNode); | |||
private openChangesWithWorking(node: CommitNode | StashNode) { | |||
const args: DiffWithWorkingCommandArgs = { | |||
commit: node.commit, | |||
showOptions: { | |||
preserveFocus: true, | |||
preview: false | |||
} | |||
}; | |||
return commands.executeCommand(Commands.DiffWithWorking, new GitUri(node.commit.uri, node.commit), args); | |||
} | |||
private openFile(node: CommitNode | StashNode) { | |||
return openEditor(node.uri, { preserveFocus: true, preview: false }); | |||
} | |||
private openFileRevision(node: CommitNode | StashNode | CommitFileNode, options: OpenFileRevisionCommandArgs = { showOptions: { preserveFocus: true, preview: false } }) { | |||
return openEditor(options.uri || GitService.toGitContentUri(node.uri), options.showOptions || { preserveFocus: true, preview: false }); | |||
} | |||
private _add<T extends ExplorerNode>(uri: GitUri, type: { new (uri: GitUri, context: ExtensionContext, git: GitService): T, rootType: ResourceType }) { | |||
if (!this._roots.some(_ => _.resourceType === type.rootType && UriComparer.equals(uri, _.uri))) { | |||
this._roots.push(new type(uri, this.context, this.git)); | |||
private async openChangedFiles(node: CommitNode | StashNode, options: TextDocumentShowOptions = { preserveFocus: false, preview: false }) { | |||
const repoPath = node.commit.repoPath; | |||
const uris = node.commit.fileStatuses.filter(s => s.status !== 'D').map(s => GitUri.fromFileStatus(s, repoPath)); | |||
for (const uri of uris) { | |||
await openEditor(uri, options); | |||
} | |||
this.refresh(); | |||
} | |||
clear() { | |||
this._roots = []; | |||
this.refresh(); | |||
private async openChangedFileRevisions(node: CommitNode | StashNode, options: TextDocumentShowOptions = { preserveFocus: false, preview: false }) { | |||
const uris = node.commit.fileStatuses | |||
.filter(s => s.status !== 'D') | |||
.map(s => GitService.toGitContentUri(node.commit.sha, node.commit.shortSha, s.fileName, node.commit.repoPath, s.originalFileName)); | |||
for (const uri of uris) { | |||
await openEditor(uri, options); | |||
} | |||
} | |||
refresh() { | |||
this._onDidChangeTreeData.fire(); | |||
private async openFileRevisionInRemote(node: CommitNode | StashNode) { | |||
return commands.executeCommand(Commands.OpenFileInRemote, new GitUri(node.commit.uri, node.commit), { range: false } as OpenFileInRemoteCommandArgs); | |||
} | |||
} |
@ -0,0 +1,30 @@ | |||
'use strict'; | |||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode'; | |||
import { ExplorerNode, ResourceType } from './explorerNode'; | |||
import { FileHistoryNode } from './fileHistoryNode'; | |||
import { GitService, GitUri } from '../gitService'; | |||
export class HistoryNode extends ExplorerNode { | |||
readonly resourceType: ResourceType = 'gitlens:history'; | |||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) { | |||
super(uri); | |||
} | |||
async getChildren(): Promise<ExplorerNode[]> { | |||
return [new FileHistoryNode(this.uri, this.context, this.git)]; | |||
} | |||
getTreeItem(): TreeItem { | |||
const item = new TreeItem(`${this.uri.getFormattedPath()}`, TreeItemCollapsibleState.Expanded); | |||
item.contextValue = this.resourceType; | |||
item.iconPath = { | |||
dark: this.context.asAbsolutePath('images/dark/icon-history.svg'), | |||
light: this.context.asAbsolutePath('images/light/icon-history.svg') | |||
}; | |||
return item; | |||
} | |||
} |
@ -0,0 +1,35 @@ | |||
'use strict'; | |||
import { Iterables } from '../system'; | |||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode'; | |||
import { BranchHistoryNode } from './branchHistoryNode'; | |||
import { ExplorerNode, ResourceType } from './explorerNode'; | |||
import { GitRemote, GitService, GitUri } from '../gitService'; | |||
export class RemoteNode extends ExplorerNode { | |||
readonly resourceType: ResourceType = 'gitlens:remote'; | |||
constructor(public readonly remote: GitRemote, uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) { | |||
super(uri); | |||
} | |||
async getChildren(): Promise<ExplorerNode[]> { | |||
const branches = await this.git.getBranches(this.uri.repoPath!); | |||
if (branches === undefined) return []; | |||
branches.sort((a, b) => a.name.localeCompare(b.name)); | |||
return [...Iterables.filterMap(branches, b => !b.remote || !b.name.startsWith(this.remote.name) ? undefined : new BranchHistoryNode(b, this.remote, this.uri, this.git.config.gitExplorer.commitFormat, this.context, this.git))]; | |||
} | |||
getTreeItem(): TreeItem { | |||
const item = new TreeItem(this.remote.name, TreeItemCollapsibleState.Collapsed); | |||
item.contextValue = this.resourceType; | |||
// item.iconPath = { | |||
// dark: this.context.asAbsolutePath('images/dark/icon-remote.svg'), | |||
// light: this.context.asAbsolutePath('images/light/icon-remote.svg') | |||
// }; | |||
return item; | |||
} | |||
} |
@ -0,0 +1,35 @@ | |||
'use strict'; | |||
import { Arrays, Iterables } from '../system'; | |||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode'; | |||
import { ExplorerNode, ResourceType } from './explorerNode'; | |||
import { GitService, GitUri } from '../gitService'; | |||
import { RemoteNode } from './remoteNode'; | |||
export class RemotesNode extends ExplorerNode { | |||
readonly resourceType: ResourceType = 'gitlens:remotes'; | |||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) { | |||
super(uri); | |||
} | |||
async getChildren(): Promise<ExplorerNode[]> { | |||
const remotes = Arrays.uniqueBy(await this.git.getRemotes(this.uri.repoPath!), r => r.url, r => !!r.provider); | |||
if (remotes === undefined) return []; | |||
remotes.sort((a, b) => a.name.localeCompare(b.name)); | |||
return [...Iterables.map(remotes, r => new RemoteNode(r, this.uri, this.context, this.git))]; | |||
} | |||
getTreeItem(): TreeItem { | |||
const item = new TreeItem(`Remotes`, TreeItemCollapsibleState.Collapsed); | |||
item.contextValue = this.resourceType; | |||
item.iconPath = { | |||
dark: this.context.asAbsolutePath('images/dark/icon-remote.svg'), | |||
light: this.context.asAbsolutePath('images/light/icon-remote.svg') | |||
}; | |||
return item; | |||
} | |||
} |
@ -1,46 +0,0 @@ | |||
'use strict'; | |||
import { Event, EventEmitter, ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode'; | |||
import { CommitFileNode } from './commitFileNode'; | |||
import { ExplorerNode, ResourceType } from './explorerNode'; | |||
import { CommitFormatter, GitService, GitStashCommit, GitUri } from '../gitService'; | |||
export class StashCommitNode extends ExplorerNode { | |||
readonly resourceType: ResourceType = 'stash-commit'; | |||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>(); | |||
public get onDidChangeTreeData(): Event<ExplorerNode> { | |||
return this._onDidChangeTreeData.event; | |||
} | |||
constructor(public readonly commit: GitStashCommit, protected readonly context: ExtensionContext, protected readonly git: GitService) { | |||
super(new GitUri(commit.uri, commit)); | |||
} | |||
async getChildren(): Promise<CommitFileNode[]> { | |||
return Promise.resolve((this.commit as GitStashCommit).fileStatuses.map(_ => new CommitFileNode(_, this.commit, this.git.config.stashExplorer.stashFileFormat, this.context, this.git))); | |||
} | |||
getTreeItem(): TreeItem { | |||
const label = CommitFormatter.fromTemplate(this.git.config.stashExplorer.stashFormat, this.commit, this.git.config.defaultDateFormat); | |||
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed); | |||
item.contextValue = this.resourceType; | |||
// item.command = { | |||
// title: 'Show Stash Details', | |||
// command: Commands.ShowQuickCommitDetails, | |||
// arguments: [ | |||
// new GitUri(commit.uri, commit), | |||
// { | |||
// commit: this.commit, | |||
// sha: this.commit.sha | |||
// } as ShowQuickCommitDetailsCommandArgs | |||
// ] | |||
// }; | |||
return item; | |||
} | |||
refresh() { | |||
this._onDidChangeTreeData.fire(); | |||
} | |||
} |
@ -1,75 +0,0 @@ | |||
'use strict'; | |||
// import { Functions } from '../system'; | |||
import { commands, Event, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, Uri } from 'vscode'; | |||
import { Commands, DiffWithPreviousCommandArgs, openEditor, OpenFileInRemoteCommandArgs } from '../commands'; | |||
import { ExplorerNode, StashCommitNode, StashNode } from './explorerNodes'; | |||
import { GitService, GitUri } from '../gitService'; | |||
export * from './explorerNodes'; | |||
export class StashExplorer implements TreeDataProvider<ExplorerNode> { | |||
private _node: ExplorerNode; | |||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>(); | |||
public get onDidChangeTreeData(): Event<ExplorerNode> { | |||
return this._onDidChangeTreeData.event; | |||
} | |||
constructor(private context: ExtensionContext, private git: GitService) { | |||
commands.registerCommand('gitlens.stashExplorer.refresh', this.refresh, this); | |||
commands.registerCommand('gitlens.stashExplorer.openChanges', this.openChanges, this); | |||
commands.registerCommand('gitlens.stashExplorer.openFile', this.openFile, this); | |||
commands.registerCommand('gitlens.stashExplorer.openStashedFile', this.openStashedFile, this); | |||
commands.registerCommand('gitlens.stashExplorer.openFileInRemote', this.openFileInRemote, this); | |||
context.subscriptions.push(this.git.onDidChangeRepo(this.onRepoChanged, this)); | |||
this._node = this.getRootNode(); | |||
} | |||
async getTreeItem(node: ExplorerNode): Promise<TreeItem> { | |||
return node.getTreeItem(); | |||
} | |||
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> { | |||
if (node === undefined) return this._node.getChildren(); | |||
return node.getChildren(); | |||
} | |||
private getRootNode(): ExplorerNode { | |||
const uri = new GitUri(Uri.file(this.git.repoPath), { repoPath: this.git.repoPath, fileName: this.git.repoPath }); | |||
return new StashNode(uri, this.context, this.git); | |||
} | |||
private onRepoChanged(reasons: ('stash' | 'unknown')[]) { | |||
if (!reasons.includes('stash')) return; | |||
this.refresh(); | |||
} | |||
refresh() { | |||
this._onDidChangeTreeData.fire(); | |||
} | |||
private openChanges(node: StashCommitNode) { | |||
const command = node.getCommand(); | |||
if (command === undefined || command.arguments === undefined) return; | |||
const [uri, args] = command.arguments as [Uri, DiffWithPreviousCommandArgs]; | |||
args.showOptions!.preview = false; | |||
return commands.executeCommand(command.command, uri, args); | |||
} | |||
private openFile(node: StashCommitNode) { | |||
return openEditor(node.uri, { preserveFocus: true, preview: false }); | |||
} | |||
private openStashedFile(node: StashCommitNode) { | |||
return openEditor(GitService.toGitContentUri(node.uri), { preserveFocus: true, preview: false }); | |||
} | |||
private openFileInRemote(node: StashCommitNode) { | |||
return commands.executeCommand(Commands.OpenFileInRemote, node.commit.uri, { range: false } as OpenFileInRemoteCommandArgs); | |||
} | |||
} |
@ -0,0 +1,14 @@ | |||
'use strict'; | |||
import { ExtensionContext } from 'vscode'; | |||
import { ResourceType } from './explorerNode'; | |||
import { GitService, GitStashCommit, IGitStatusFile } from '../gitService'; | |||
import { CommitFileNode } from './commitFileNode'; | |||
export class StashFileNode extends CommitFileNode { | |||
readonly resourceType: ResourceType = 'gitlens:stash-file'; | |||
constructor(readonly status: IGitStatusFile, readonly commit: GitStashCommit, readonly context: ExtensionContext, readonly git: GitService) { | |||
super(status, commit, context, git); | |||
} | |||
} |
@ -1,29 +1,35 @@ | |||
'use strict'; | |||
import { Iterables } from '../system'; | |||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode'; | |||
import { ExplorerNode, ResourceType, TextExplorerNode } from './explorerNode'; | |||
import { GitService, GitUri } from '../gitService'; | |||
import { StashCommitNode } from './stashCommitNode'; | |||
import { Event, EventEmitter, ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode'; | |||
import { ExplorerNode, ResourceType } from './explorerNode'; | |||
import { CommitFormatter, GitService, GitStashCommit, GitUri } from '../gitService'; | |||
import { StashFileNode } from './stashFileNode'; | |||
export class StashNode extends ExplorerNode { | |||
static readonly rootType: ResourceType = 'stash-history'; | |||
readonly resourceType: ResourceType = 'stash-history'; | |||
readonly resourceType: ResourceType = 'gitlens:stash'; | |||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) { | |||
super(uri); | |||
} | |||
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>(); | |||
public get onDidChangeTreeData(): Event<ExplorerNode> { | |||
return this._onDidChangeTreeData.event; | |||
} | |||
async getChildren(): Promise<ExplorerNode[]> { | |||
const stash = await this.git.getStashList(this.uri.repoPath!); | |||
if (stash === undefined) return [new TextExplorerNode('No stashed changes')]; | |||
constructor(public readonly commit: GitStashCommit, protected readonly context: ExtensionContext, protected readonly git: GitService) { | |||
super(new GitUri(commit.uri, commit)); | |||
} | |||
return [...Iterables.map(stash.commits.values(), c => new StashCommitNode(c, this.context, this.git))]; | |||
async getChildren(): Promise<ExplorerNode[]> { | |||
return Promise.resolve((this.commit as GitStashCommit).fileStatuses.map(s => new StashFileNode(s, this.commit, this.context, this.git))); | |||
} | |||
getTreeItem(): TreeItem { | |||
const item = new TreeItem(`Stashed Changes`, TreeItemCollapsibleState.Collapsed); | |||
const label = CommitFormatter.fromTemplate(this.git.config.gitExplorer.stashFormat, this.commit, this.git.config.defaultDateFormat); | |||
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed); | |||
item.contextValue = this.resourceType; | |||
return item; | |||
} | |||
refresh() { | |||
this._onDidChangeTreeData.fire(); | |||
} | |||
} |
@ -0,0 +1,34 @@ | |||
'use strict'; | |||
import { Iterables } from '../system'; | |||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode'; | |||
import { ExplorerNode, MessageNode, ResourceType } from './explorerNode'; | |||
import { GitService, GitUri } from '../gitService'; | |||
import { StashNode } from './stashNode'; | |||
export class StashesNode extends ExplorerNode { | |||
readonly resourceType: ResourceType = 'gitlens:stashes'; | |||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) { | |||
super(uri); | |||
} | |||
async getChildren(): Promise<ExplorerNode[]> { | |||
const stash = await this.git.getStashList(this.uri.repoPath!); | |||
if (stash === undefined) return [new MessageNode('No stashed changes')]; | |||
return [...Iterables.map(stash.commits.values(), c => new StashNode(c, this.context, this.git))]; | |||
} | |||
getTreeItem(): TreeItem { | |||
const item = new TreeItem(`Stashes`, TreeItemCollapsibleState.Collapsed); | |||
item.contextValue = this.resourceType; | |||
item.iconPath = { | |||
dark: this.context.asAbsolutePath('images/dark/icon-stash.svg'), | |||
light: this.context.asAbsolutePath('images/light/icon-stash.svg') | |||
}; | |||
return item; | |||
} | |||
} |
@ -1,34 +1,60 @@ | |||
import { Strings } from '../system'; | |||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode'; | |||
import { GlyphChars } from '../constants'; | |||
import { ExplorerNode, ResourceType } from './explorerNode'; | |||
import { GitService, GitUri } from '../gitService'; | |||
import { StatusUpstreamNode } from './statusUpstreamNode'; | |||
export class StatusNode extends ExplorerNode { | |||
readonly resourceType: ResourceType = 'status'; | |||
readonly resourceType: ResourceType = 'gitlens:status'; | |||
constructor(uri: GitUri, protected readonly context: ExtensionContext, protected readonly git: GitService) { | |||
super(uri); | |||
} | |||
async getChildren(): Promise<ExplorerNode[]> { | |||
return []; | |||
// const status = await this.git.getStatusForRepo(this.uri.repoPath!); | |||
// if (status === undefined) return []; | |||
const status = await this.git.getStatusForRepo(this.uri.repoPath!); | |||
if (status === undefined) return []; | |||
const children = []; | |||
if (status.state.behind) { | |||
children.push(new StatusUpstreamNode(status, 'behind', this.git.config.gitExplorer.commitFormat, this.context, this.git)); | |||
} | |||
if (status.state.ahead) { | |||
children.push(new StatusUpstreamNode(status, 'ahead', this.git.config.gitExplorer.commitFormat, this.context, this.git)); | |||
} | |||
// return [...Iterables.map(status.files, b => new CommitFile(b, this.uri, this.context, this.git))]; | |||
return children; | |||
} | |||
async getTreeItem(): Promise<TreeItem> { | |||
const status = await this.git.getStatusForRepo(this.uri.repoPath!); | |||
let suffix = ''; | |||
if (status !== undefined) { | |||
suffix = ` ${GlyphChars.Dash} ${GlyphChars.ArrowUp} ${status.state.ahead} ${GlyphChars.ArrowDown} ${status.state.behind} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${status.branch} ${GlyphChars.ArrowLeftRight} ${status.upstream}`; | |||
if (status === undefined) return new TreeItem('No repo status'); | |||
let hasChildren = false; | |||
let label = ''; | |||
if (status.upstream) { | |||
if (!status.state.ahead && !status.state.behind) { | |||
label = `${status.branch} is up-to-date with ${status.upstream}`; | |||
} | |||
else { | |||
label = `${status.branch} is not up-to-date with ${status.upstream}`; | |||
hasChildren = true; | |||
} | |||
} | |||
else { | |||
label = `${status.branch} is up-to-date`; | |||
} | |||
const item = new TreeItem(`Status${suffix}`, TreeItemCollapsibleState.Collapsed); | |||
const item = new TreeItem(label, hasChildren ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None); | |||
item.contextValue = this.resourceType; | |||
item.iconPath = { | |||
dark: this.context.asAbsolutePath('images/dark/icon-repo.svg'), | |||
light: this.context.asAbsolutePath('images/light/icon-repo.svg') | |||
}; | |||
return item; | |||
} | |||
} |
@ -0,0 +1,53 @@ | |||
'use strict'; | |||
import { Iterables } from '../system'; | |||
import { ExtensionContext, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode'; | |||
import { ExplorerNode, ResourceType } from './explorerNode'; | |||
import { GitService, GitStatus, GitUri } from '../gitService'; | |||
import { CommitNode } from './commitNode'; | |||
export class StatusUpstreamNode extends ExplorerNode { | |||
readonly resourceType: ResourceType = 'gitlens:status-upstream'; | |||
constructor(public readonly status: GitStatus, public readonly direction: 'ahead' | 'behind', private readonly template: string, protected readonly context: ExtensionContext, protected readonly git: GitService) { | |||
super(new GitUri(Uri.file(status.repoPath), { repoPath: status.repoPath, fileName: status.repoPath })); | |||
} | |||
async getChildren(): Promise<ExplorerNode[]> { | |||
const range = this.direction === 'ahead' | |||
? `${this.status.upstream}..${this.status.branch}` | |||
: `${this.status.branch}..${this.status.upstream}`; | |||
let log = await this.git.getLogForRepo(this.uri.repoPath!, range); | |||
if (log === undefined) return []; | |||
if (this.direction !== 'ahead') return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.template, this.context, this.git))]; | |||
// Since the last commit when we are looking 'ahead' can have no previous (because of the range given) -- look it up | |||
const commits = Array.from(log.commits.values()); | |||
const commit = commits[commits.length - 1]; | |||
if (commit.previousSha === undefined) { | |||
log = await this.git.getLogForRepo(this.uri.repoPath!, commit.sha, 2); | |||
if (log !== undefined) { | |||
commits[commits.length - 1] = Iterables.first(log.commits.values()); | |||
} | |||
} | |||
return [...Iterables.map(commits, c => new CommitNode(c, this.template, this.context, this.git))]; | |||
} | |||
async getTreeItem(): Promise<TreeItem> { | |||
const label = this.direction === 'ahead' | |||
? `${this.status.state.ahead} commit${this.status.state.ahead > 1 ? 's' : ''} ahead` // of ${this.status.upstream}` | |||
: `${this.status.state.behind} commit${this.status.state.behind > 1 ? 's' : ''} behind`; // ${this.status.upstream}`; | |||
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed); | |||
item.contextValue = this.resourceType; | |||
item.iconPath = { | |||
dark: this.context.asAbsolutePath(`images/dark/icon-${this.direction === 'ahead' ? 'upload' : 'download'}.svg`), | |||
light: this.context.asAbsolutePath(`images/light/icon-${this.direction === 'ahead' ? 'upload' : 'download'}.svg`) | |||
}; | |||
return item; | |||
} | |||
} |