diff --git a/Telegram/Resources/iv_html/page.css b/Telegram/Resources/iv_html/page.css
index b5feac073..6f27a6e1c 100644
--- a/Telegram/Resources/iv_html/page.css
+++ b/Telegram/Resources/iv_html/page.css
@@ -1,871 +1,884 @@
body {
- font-family: 'Helvetica Neue';
- font-size: 17px;
- line-height: 25px;
- padding: 0;
- margin: 0;
+ font-family: 'Helvetica Neue';
+ font-size: 17px;
+ line-height: 25px;
+ padding: 0;
+ margin: 0;
+ background-color: var(--td-window-bg);
+ color: var(--td-window-fg);
}
+
+html.custom_scroll ::-webkit-scrollbar {
+ border-radius: 5px !important;
+ border: 3px solid transparent !important;
+ background-color: var(--td-scroll-bg) !important;
+ background-clip: content-box !important;
+ width: 10px !important;
+}
+html.custom_scroll ::-webkit-scrollbar:hover {
+ background-color: var(--td-scroll-bg-over) !important;
+}
+html.custom_scroll ::-webkit-scrollbar-thumb {
+ border-radius: 5px !important;
+ border: 3px solid transparent !important;
+ background-color: var(--td-scroll-bar-bg) !important;
+ background-clip: content-box !important;
+}
+html.custom_scroll ::-webkit-scrollbar-thumb:hover {
+ background-color: var(--td-scroll-bar-bg-over) !important;
+}
+
article {
- padding-bottom: 12px;
- overflow: hidden;
- white-space: pre-wrap;
- max-width: 732px;
- margin: 0 auto;
+ padding-bottom: 12px;
+ overflow: hidden;
+ white-space: pre-wrap;
+ max-width: 732px;
+ margin: 0 auto;
}
article h1,
article h2 {
- font-family: 'Georgia';
- font-size: 28px;
- line-height: 31px;
- margin: 21px 18px 12px;
- font-weight: normal;
- min-height: 31px;
+ font-family: 'Georgia';
+ font-size: 28px;
+ line-height: 31px;
+ margin: 21px 18px 12px;
+ font-weight: normal;
+ min-height: 31px;
}
article h2 {
- font-size: 24px;
- line-height: 30px;
- margin: -6px 18px 12px;
- color: #777;
-}
-article h6.kicker {
- font-family: 'Helvetica Neue';
- font-size: 14px;
- line-height: 17px;
- margin: 21px 18px 12px;
- font-weight: 500;
- color: #79828B;
-}
-article h6.kicker + h1 {
- margin-top: 12px;
+ font-size: 24px;
+ line-height: 30px;
+ margin: -6px 18px 12px;
+ color: var(--td-window-sub-text-fg);
}
article address {
- font-size: 15px;
- color: #79828B;
- margin: 12px 18px 21px;
- font-style: normal;
+ font-size: 15px;
+ color: var(--td-window-sub-text-fg);
+ margin: 12px 18px 21px;
+ font-style: normal;
}
article.rtl address {
- direction: ltr;
- text-align: right;
+ direction: ltr;
+ text-align: right;
}
article address figure {
- width: 25px;
- height: 25px;
- float: right;
- margin: 0 0 0 12px;
- background: no-repeat center;
- background-size: cover;
- border-radius: 50%;
+ width: 25px;
+ height: 25px;
+ float: right;
+ margin: 0 0 0 12px;
+ background: no-repeat center;
+ background-size: cover;
+ border-radius: 50%;
}
article address a,
article address a[href] {
- color: #79828B;
+ color: var(--td-window-sub-text-fg);
}
article address a[href] {
- text-decoration: underline;
+ text-decoration: underline;
}
article a[href] {
- color: #007EE5;
- text-decoration: none;
+ color: var(--td-window-active-text-fg);
+ text-decoration: none;
}
article span.reference {
- border: dotted #ddd;
- border-width: 1px 1px 1px 2px;
- background: rgba(255, 255, 255, 0.7);
- margin: 0 1px;
- padding: 2px;
- position: relative;
+ border: dotted var(--td-window-sub-text-fg);
+ border-width: 1px 1px 1px 2px;
+ background: rgba(255, 255, 255, 0.7);
+ margin: 0 1px;
+ padding: 2px;
+ position: relative;
}
article.rtl span.reference {
- border-width: 1px 0 1px 1px;
+ border-width: 1px 0 1px 1px;
}
article code {
- font-size: 0.94em;
- background: #eee;
- border-radius: 2px;
- padding: 0 3px 1px;
+ font-size: 0.94em;
+ background: var(--td-box-divider-bg);
+ border-radius: 2px;
+ padding: 0 3px 1px;
}
article mark {
- background: #fcf8e3;
- border-radius: 2px;
- padding: 0 3px 1px;
+ background: var(--td-window-bg-over);
+ color: var(--td-window-fg);
+ border-radius: 2px;
+ padding: 0 3px 1px;
}
article sup,
article sub {
- font-size: 0.75em;
- line-height: 1;
+ font-size: 0.75em;
+ line-height: 1;
}
article p {
- margin: 0 18px 12px;
- word-wrap: break-word;
+ margin: 0 18px 12px;
+ word-wrap: break-word;
}
article ul p,
article ol p {
- margin: 0 0 6px;
+ margin: 0 0 6px;
}
article pre,
article pre.hljs {
- font-family: Menlo;
- margin: 14px 0;
- padding: 7px 18px;
- background: #F5F8FC;
- font-size: 16px;
- white-space: pre-wrap;
- word-wrap: break-word;
- overflow-x: visible;
- position: relative;
+ font-family: Menlo;
+ margin: 14px 0;
+ padding: 7px 18px;
+ background: #F5F8FC;
+ font-size: 16px;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+ overflow-x: visible;
+ position: relative;
}
article ul pre,
article ol pre,
article ul pre.hljs,
article ol pre.hljs {
- margin: 6px 0 6px -18px;
+ margin: 6px 0 6px -18px;
}
article.rtl ul pre,
article.rtl ol pre,
article.rtl ul pre.hljs,
article.rtl ol pre.hljs {
- margin-right: -18px;
- margin-left: 0;
+ margin-right: -18px;
+ margin-left: 0;
}
article pre + pre {
- margin-top: -14px;
+ margin-top: -14px;
}
article h3,
article h4 {
- font-family: 'Georgia';
- font-size: 24px;
- line-height: 30px;
- margin: 18px 18px 9px;
- font-weight: normal;
+ font-family: 'Georgia';
+ font-size: 24px;
+ line-height: 30px;
+ margin: 18px 18px 9px;
+ font-weight: normal;
}
article h4 {
- font-size: 19px;
- margin: 18px 18px 7px;
+ font-size: 19px;
+ margin: 18px 18px 7px;
}
article ul h3,
article ol h3 {
- margin: 12px 0 7px;
+ margin: 12px 0 7px;
}
article ul h4,
article ol h4 {
- margin: 10px 0 5px;
+ margin: 10px 0 5px;
}
article blockquote {
- font-family: 'Georgia';
- margin: 18px 18px 16px;
- padding-left: 22px;
- position: relative;
- font-style: italic;
- word-wrap: break-word;
+ font-family: 'Georgia';
+ margin: 18px 18px 16px;
+ padding-left: 22px;
+ position: relative;
+ font-style: italic;
+ word-wrap: break-word;
}
article blockquote:before {
- content: '';
- position: absolute;
- left: 1px;
- top: 3px;
- bottom: 3px;
- width: 3px;
- background-color: #000;
- border-radius: 3px;
+ content: '';
+ position: absolute;
+ left: 1px;
+ top: 3px;
+ bottom: 3px;
+ width: 3px;
+ background-color: var(--td-window-bg-active);
+ border-radius: 3px;
}
article.rtl blockquote {
- padding-right: 22px;
- padding-left: 0;
+ padding-right: 22px;
+ padding-left: 0;
}
article.rtl blockquote:before {
- right: 1px;
- left: auto;
+ right: 1px;
+ left: auto;
}
article aside {
- font-family: 'Georgia';
- margin: 18px 18px 16px;
- padding: 0 18px;
- text-align: center;
- font-style: italic;
+ font-family: 'Georgia';
+ margin: 18px 18px 16px;
+ padding: 0 18px;
+ text-align: center;
+ font-style: italic;
}
article ul blockquote,
article ol blockquote,
article ul aside,
article ol aside {
- margin: 12px 0 10px;
+ margin: 12px 0 10px;
}
article blockquote cite,
article aside cite,
article footer cite,
article .iv-pullquote cite {
- font-family: 'Helvetica Neue';
- font-size: 15px;
- display: block;
- color: #79828B;
- line-height: 19px;
- padding: 5px 0 2px;
- font-style: normal;
+ font-family: 'Helvetica Neue';
+ font-size: 15px;
+ display: block;
+ color: var(--td-window-sub-text-fg);
+ line-height: 19px;
+ padding: 5px 0 2px;
+ font-style: normal;
}
article hr {
- width: 50%;
- margin: 36px auto 26px;
- padding: 2px 0 10px;
- border: none;
+ width: 50%;
+ margin: 36px auto 26px;
+ padding: 2px 0 10px;
+ border: none;
}
article ul hr,
article ol hr {
- margin: 18px auto;
+ margin: 18px auto;
}
article hr:before {
- content: '';
- display: block;
- border-top: 1px solid #c9cdd1;
- padding: 0 0 2px;
+ content: '';
+ display: block;
+ border-top: 1px solid var(--td-window-sub-text-fg);
+ padding: 0 0 2px;
}
article footer hr {
- margin: 18px auto 6px;
+ margin: 18px auto 6px;
}
article ul,
article ol {
- margin: 0 18px 12px;
- padding-left: 18px;
+ margin: 0 18px 12px;
+ padding-left: 18px;
}
article.rtl ul,
article.rtl ol {
- padding-right: 18px;
- padding-left: 0;
+ padding-right: 18px;
+ padding-left: 0;
}
/*article ul {
- list-style: none;
+ list-style: none;
}*/
article ul > li,
article ol > li {
- padding-left: 4px;
+ padding-left: 4px;
}
article.rtl ul > li,
article.rtl ol > li {
- padding-right: 4px;
- padding-left: 0;
+ padding-right: 4px;
+ padding-left: 0;
}
/*article ul > li {
- position: relative;
+ position: relative;
}
article ul > li:before {
- content: '\2022';
- position: absolute;
- display: block;
- font-size: 163%;
- left: -19px;
- top: 1px;
+ content: '\2022';
+ position: absolute;
+ display: block;
+ font-size: 163%;
+ left: -19px;
+ top: 1px;
}
article.rtl ul > li:before {
- left: auto;
- right: -19px;
+ left: auto;
+ right: -19px;
}*/
article ul ul,
article ul ol,
article ol ul,
article ol ol {
- margin: 0 0 12px;
+ margin: 0 0 12px;
}
article table {
- width: 100%;
- border-collapse: collapse;
+ width: 100%;
+ border-collapse: collapse;
}
article table.bordered,
article table.bordered td,
article table.bordered th {
- border: 1px solid #ddd;
+ border: 1px solid var(--td-box-divider-fg);
}
article table.striped tr:nth-child(odd) td {
- background-color: #f7f7f7;
+ background-color: var(--td-box-divider-bg);
}
article table caption {
- font-size: 15px;
- line-height: 18px;
- margin: 4px 0 7px;
- text-align: left;
- color: #79828B;
+ font-size: 15px;
+ line-height: 18px;
+ margin: 4px 0 7px;
+ text-align: left;
+ color: var(--td-window-sub-text-fg);
}
article.rtl table caption {
- text-align: right;
+ text-align: right;
}
article td,
article th {
- font-size: 15px;
- line-height: 21px;
- padding: 6px 5px 5px;
- background-color: #fff;
- vertical-align: middle;
- font-weight: normal;
- text-align: left;
+ font-size: 15px;
+ line-height: 21px;
+ padding: 6px 5px 5px;
+ background-color: var(--td-window-bg);
+ vertical-align: middle;
+ font-weight: normal;
+ text-align: left;
}
article th {
- background-color: #efefef;
+ background-color: var(--td-box-divider-bg);
}
article.rtl table td,
article.rtl table th {
- text-align: right;
+ text-align: right;
}
article details {
- position: relative;
- margin: 0 0 12px;
- padding: 0 0 1px;
+ position: relative;
+ margin: 0 0 12px;
+ padding: 0 0 1px;
}
article details:before {
- content: '';
- display: block;
- border-bottom: 1px solid #c8c7cb;
- position: absolute;
- left: 18px;
- right: 0;
- bottom: 0;
+ content: '';
+ display: block;
+ border-bottom: 1px solid var(--td-box-divider-fg);
+ position: absolute;
+ left: 18px;
+ right: 0;
+ bottom: 0;
}
article.rtl details:before {
- right: 18px;
- left: 0;
+ right: 18px;
+ left: 0;
}
article details + details {
- margin-top: -12px;
+ margin-top: -12px;
}
article details > details:last-child {
- margin-bottom: -1px;
+ margin-bottom: -1px;
}
article summary {
- padding: 10px 18px 10px 42px;
- line-height: 25px;
- min-height: 25px;
+ padding: 10px 18px 10px 42px;
+ line-height: 25px;
+ min-height: 25px;
}
article.rtl summary {
- padding-left: 18px;
- padding-right: 42px;
+ padding-left: 18px;
+ padding-right: 42px;
}
article summary:hover {
- cursor: pointer;
+ cursor: pointer;
}
article summary:focus {
- outline: none;
+ outline: none;
}
article summary::-webkit-details-marker {
- display: none;
+ display: none;
}
article summary::marker {
- content: '';
+ content: '';
}
article summary:before {
- content: '';
- background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAICAYAAADN5B7xAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAH1JREFUeNqEjUEKgCAQRSfrNi1bdZFadJjsMC46SSAIHqjB5mcFqdFfhD3eUyKZtb6ln92O2janmXdvrRu+ZTfAgasu1jAHU4qiHAwc/Ff4oCQKsxxZ0NT33XrxUTjkWvgiXFf3TWkU6Vt+XihH515yFiQRpfLnEMUw3yHAABZNTT9emBrvAAAAAElFTkSuQmCC');
- transition: all .2s ease;
- display: inline-block;
- position: absolute;
- width: 12px;
- height: 8px;
- left: 18px;
- top: 18px;
+ content: '';
+ background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAICAYAAADN5B7xAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAH1JREFUeNqEjUEKgCAQRSfrNi1bdZFadJjsMC46SSAIHqjB5mcFqdFfhD3eUyKZtb6ln92O2janmXdvrRu+ZTfAgasu1jAHU4qiHAwc/Ff4oCQKsxxZ0NT33XrxUTjkWvgiXFf3TWkU6Vt+XihH515yFiQRpfLnEMUw3yHAABZNTT9emBrvAAAAAElFTkSuQmCC');
+ transition: all .2s ease;
+ display: inline-block;
+ position: absolute;
+ width: 12px;
+ height: 8px;
+ left: 18px;
+ top: 18px;
}
article.rtl summary:before {
- right: 18px;
- left: auto;
+ right: 18px;
+ left: auto;
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
- article summary:before {
- background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAQCAYAAAAMJL+VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPxJREFUeNq8lEESgiAUhgFbZ0epSW28gB2pZbrrSukBHDWto1TrwHih45AiaDOxesLP9w1PBlzXNfrLSNPqkGWV8ysHGMBqv4mAlyFC7MRPk+T51Z0Lh73AAJZgIoRFUR/bEMb4TggJPG9TTIUzxmIuWHWzOCLfQQgwRiedRMBpIsObFvn+NgSTLEE2bCiKm6eDQ0bAkS2v4AjYuPvJcqtEu9DDshaB665zFZzSV6yCfyr5JplLTOA9wZiEg/a+72Qic9nxubMOPijQSZraCK4UjEiezSVYmsBHBSrJAEIJ1wr0knG4kUAt0cONBX2JGXzGi1uG7SNmOt4CDADc4r+K4txg+wAAAABJRU5ErkJggg==');
- background-size: 12px 8px;
- }
+ article summary:before {
+ background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAQCAYAAAAMJL+VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPxJREFUeNq8lEESgiAUhgFbZ0epSW28gB2pZbrrSukBHDWto1TrwHih45AiaDOxesLP9w1PBlzXNfrLSNPqkGWV8ysHGMBqv4mAlyFC7MRPk+T51Z0Lh73AAJZgIoRFUR/bEMb4TggJPG9TTIUzxmIuWHWzOCLfQQgwRiedRMBpIsObFvn+NgSTLEE2bCiKm6eDQ0bAkS2v4AjYuPvJcqtEu9DDshaB665zFZzSV6yCfyr5JplLTOA9wZiEg/a+72Qic9nxubMOPijQSZraCK4UjEiezSVYmsBHBSrJAEIJ1wr0knG4kUAt0cONBX2JGXzGi1uG7SNmOt4CDADc4r+K4txg+wAAAABJRU5ErkJggg==');
+ background-size: 12px 8px;
+ }
}
article details[open] > summary:before {
- /*transform: rotateZ(-180deg);*/
- transform: scaleY(-1);
+ /*transform: rotateZ(-180deg);*/
+ transform: scaleY(-1);
}
article li summary {
- padding-left: 24px;
+ padding-left: 24px;
}
article li details:before,
article li summary:before {
- left: 0;
+ left: 0;
}
img,
video,
iframe {
- max-width: 100%;
- max-height: 400px;
- vertical-align: top;
+ max-width: 100%;
+ max-height: 400px;
+ vertical-align: top;
}
video {
- width: 100%;
+ width: 100%;
}
audio {
- width: 100%;
- width: calc(100% - 36px);
- margin: 0 18px;
- vertical-align: top;
+ width: 100%;
+ width: calc(100% - 36px);
+ margin: 0 18px;
+ vertical-align: top;
}
img {
- font-size: 12px;
- line-height: 14px;
- color: #999;
+ font-size: 12px;
+ line-height: 14px;
+ color: var(--td-window-sub-text-fg);
}
img.pic {
- max-height: none;
- font-size: inherit;
- vertical-align: middle;
- position: relative;
- top: -0.1em;
+ max-height: none;
+ font-size: inherit;
+ vertical-align: middle;
+ position: relative;
+ top: -0.1em;
}
img.pic.optional {
- opacity: 0.4;
+ opacity: 0.4;
}
body:hover img.pic.optional {
- opacity: 1;
+ opacity: 1;
}
iframe.autosize {
- max-height: none;
+ max-height: none;
}
.iframe-wrap {
- max-width: 100%;
- vertical-align: top;
- display: inline-block;
- position: relative;
+ max-width: 100%;
+ vertical-align: top;
+ display: inline-block;
+ position: relative;
}
.iframe-wrap iframe {
- position: absolute;
- width: 100%;
- height: 100%;
- top: 0;
- left: 0;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
}
figure {
- margin: 0 0 16px;
- padding: 0;
- text-align: center;
- position: relative;
+ margin: 0 0 16px;
+ padding: 0;
+ text-align: center;
+ position: relative;
}
figure.nowide {
- margin-left: 18px;
- margin-right: 18px;
+ margin-left: 18px;
+ margin-right: 18px;
}
figure.nowide figcaption {
- padding-left: 0;
- padding-right: 0;
+ padding-left: 0;
+ padding-right: 0;
}
ul figure.nowide,
ol figure.nowide {
- margin: 0 0 12px;
+ margin: 0 0 12px;
}
figure > figure {
- margin: 0;
+ margin: 0;
}
figcaption {
- font-size: 15px;
- color: #79828B;
- padding: 6px 18px 0;
- line-height: 19px;
- text-align: left;
+ font-size: 15px;
+ color: var(--td-window-sub-text-fg);
+ padding: 6px 18px 0;
+ line-height: 19px;
+ text-align: left;
}
article.rtl figcaption {
- text-align: right;
+ text-align: right;
}
ul figcaption,
ol figcaption {
- padding-left: 0;
- padding-right: 0;
+ padding-left: 0;
+ padding-right: 0;
}
figcaption > cite {
- font-family: 'Helvetica Neue';
- font-size: 12px;
- display: block;
- line-height: 15px;
- padding: 2px 0 0;
- font-style: normal;
+ font-family: 'Helvetica Neue';
+ font-size: 12px;
+ display: block;
+ line-height: 15px;
+ padding: 2px 0 0;
+ font-style: normal;
}
footer {
- margin: 12px 18px;
- color: #79828B;
+ margin: 12px 18px;
+ color: var(--td-window-sub-text-fg);
}
figure.slideshow-wrap {
- position: relative;
+ position: relative;
}
figure.slideshow {
- position: relative;
- white-space: nowrap;
- width: 100%;
- background: #000;
- overflow: hidden;
+ position: relative;
+ white-space: nowrap;
+ width: 100%;
+ background: #000;
+ overflow: hidden;
}
figure.slideshow > figure {
- position: static !important;
- display: inline-block;
- width: 100%;
- vertical-align: middle;
- transition: margin .3s;
+ position: static !important;
+ display: inline-block;
+ width: 100%;
+ vertical-align: middle;
+ transition: margin .3s;
}
figure.slideshow > figure figcaption {
- box-sizing: border-box;
- position: absolute;
- bottom: 0;
- width: 100%;
- padding-bottom: 36px;
+ box-sizing: border-box;
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ padding-bottom: 36px;
}
figure.slideshow > figure figcaption:after {
- content: '';
- display: block;
- position: absolute;
- left: 0;
- right: 0;
- bottom: 0;
- top: -75px;
- background: -moz-linear-gradient(top,rgba(64,64,64,0),rgba(64,64,64,.55));
- background: -webkit-gradient(linear,0 0,0 100%,from(rgba(64,64,64,0)),to(rgba(64,64,64,.55)));
- background: -o-linear-gradient(rgba(64,64,64,0),rgba(64,64,64,.55));
- pointer-events: none;
+ content: '';
+ display: block;
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ top: -75px;
+ background: -moz-linear-gradient(top,rgba(64,64,64,0),rgba(64,64,64,.55));
+ background: -webkit-gradient(linear,0 0,0 100%,from(rgba(64,64,64,0)),to(rgba(64,64,64,.55)));
+ background: -o-linear-gradient(rgba(64,64,64,0),rgba(64,64,64,.55));
+ pointer-events: none;
}
figure.slideshow > figure figcaption > span,
figure.slideshow > figure figcaption > cite {
- position: relative;
- color: #fff;
- text-shadow: 0 1px rgba(0, 0, 0, .4);
- z-index: 1;
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
+ position: relative;
+ color: #fff;
+ text-shadow: 0 1px rgba(0, 0, 0, .4);
+ z-index: 1;
+ display: block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
figure.slideshow > figure figcaption > span {
- display: -webkit-box;
- max-height: 3.8em;
- -webkit-line-clamp: 3;
- -webkit-box-orient: vertical;
- white-space: pre-wrap;
+ display: -webkit-box;
+ max-height: 3.8em;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+ white-space: pre-wrap;
}
figure.slideshow > figure figcaption code {
- text-shadow: none;
- background: rgba(204, 204, 204, .7);
- color: #fff;
+ text-shadow: none;
+ background: rgba(204, 204, 204, .7);
+ color: #fff;
}
figure.slideshow > figure figcaption mark {
- text-shadow: none;
- background: rgba(33, 123, 134, .7);
- color: #fff;
+ text-shadow: none;
+ background: rgba(33, 123, 134, .7);
+ color: #fff;
}
figure.slideshow > figure figcaption a,
figure.slideshow > figure figcaption a:hover {
- color: #66baff;
+ color: #66baff;
}
.slideshow-buttons {
- position: absolute;
- width: 100%;
- bottom: 10px;
- white-space: nowrap;
- overflow: hidden;
- z-index: 3;
+ position: absolute;
+ width: 100%;
+ bottom: 10px;
+ white-space: nowrap;
+ overflow: hidden;
+ z-index: 3;
}
.slideshow-buttons > fieldset {
- padding: 0 10px 20px;
- margin: 0 0 -20px;
- border: none;
- line-height: 0;
- overflow: hidden;
- overflow-x: auto;
- min-width: auto;
+ padding: 0 10px 20px;
+ margin: 0 0 -20px;
+ border: none;
+ line-height: 0;
+ overflow: hidden;
+ overflow-x: auto;
+ min-width: auto;
}
.slideshow-buttons label {
- display: inline-block;
- padding: 7px;
- cursor: pointer;
+ display: inline-block;
+ padding: 7px;
+ cursor: pointer;
}
.slideshow-buttons input {
- position: absolute;
- left: -10000px;
+ position: absolute;
+ left: -10000px;
}
.slideshow-buttons label i {
- display: inline-block;
- background: #fff;
- box-shadow: 0 0 3px rgba(0, 0, 0, .4);
- border-radius: 3.5px;
- width: 7px;
- height: 7px;
- opacity: .6;
- transition: opacity .3s;
+ display: inline-block;
+ background: #fff;
+ box-shadow: 0 0 3px rgba(0, 0, 0, .4);
+ border-radius: 3.5px;
+ width: 7px;
+ height: 7px;
+ opacity: .6;
+ transition: opacity .3s;
}
.slideshow-buttons input:checked ~ i {
- opacity: 1;
+ opacity: 1;
}
figure.collage {
- margin: -2px 16px;
- text-align: left;
+ margin: -2px 16px;
+ text-align: left;
}
figure.collage > figure {
- display: inline-block;
- vertical-align: top;
- width: calc(25% - 4px);
- margin: 2px;
- box-sizing: border-box;
+ display: inline-block;
+ vertical-align: top;
+ width: calc(25% - 4px);
+ margin: 2px;
+ box-sizing: border-box;
}
figure.collage > figure > i {
- background: no-repeat center;
- background-size: cover;
- display: inline-block;
- vertical-align: top;
- width: 100%;
- padding-top: 100%;
+ background: no-repeat center;
+ background-size: cover;
+ display: inline-block;
+ vertical-align: top;
+ width: 100%;
+ padding-top: 100%;
}
figure.table-wrap {
- overflow: auto;
- -webkit-overflow-scrolling: touch;
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
}
figure.table {
- display: table-cell;
- padding: 0 18px;
+ display: table-cell;
+ padding: 0 18px;
}
article ol figure.table-wrap,
article ul figure.table-wrap {
- margin-top: 7px;
+ margin-top: 7px;
}
article ol figure.table,
article ul figure.table {
- padding: 0;
+ padding: 0;
}
figure blockquote.embed-post {
- text-align: left;
- margin-bottom: 0;
+ text-align: left;
+ margin-bottom: 0;
}
article.rtl figure blockquote.embed-post {
- text-align: right;
+ text-align: right;
}
blockquote.embed-post address {
- margin: 0;
- padding: 5px 0 9px;
- overflow: hidden;
+ margin: 0;
+ padding: 5px 0 9px;
+ overflow: hidden;
}
blockquote.embed-post address figure {
- width: 50px;
- height: 50px;
- float: left;
- margin: 0 12px 0 0;
- background: no-repeat center;
- background-size: cover;
- border-radius: 50%;
+ width: 50px;
+ height: 50px;
+ float: left;
+ margin: 0 12px 0 0;
+ background: no-repeat center;
+ background-size: cover;
+ border-radius: 50%;
}
article.rtl blockquote.embed-post address figure {
- float: right;
- margin-left: 12px;
- margin-right: 0;
+ float: right;
+ margin-left: 12px;
+ margin-right: 0;
}
blockquote.embed-post address a {
- display: inline-block;
- padding-top: 2px;
- font-size: 17px;
- font-weight: 600;
- color: #000;
+ display: inline-block;
+ padding-top: 2px;
+ font-size: 17px;
+ font-weight: 600;
+ color: var(--td-window-fg);
}
blockquote.embed-post address time {
- display: block;
- line-height: 19px;
+ display: block;
+ line-height: 19px;
}
blockquote.embed-post p,
blockquote.embed-post blockquote {
- margin: 0 0 7px;
- clear: left;
+ margin: 0 0 7px;
+ clear: left;
}
blockquote.embed-post figcaption {
- padding-left: 0;
- padding-right: 0;
+ padding-left: 0;
+ padding-right: 0;
}
blockquote.embed-post figure.collage {
- margin-left: -2px;
- margin-right: -2px;
+ margin-left: -2px;
+ margin-right: -2px;
}
blockquote.embed-post footer {
- margin: 12px 0 0;
- font-style: normal;
+ margin: 12px 0 0;
+ font-style: normal;
}
blockquote.embed-post footer hr {
- display: none;
+ display: none;
}
section.embed-post {
- display: block;
- width: auto;
- height: auto;
- background: #f7f7f7;
- margin: 0 18px 12px;
- padding: 24px 18px;
- text-align: center;
+ display: block;
+ width: auto;
+ height: auto;
+ background: var(--td-box-divider-bg);
+ margin: 0 18px 12px;
+ padding: 24px 18px;
+ text-align: center;
}
section.embed-post strong {
- font-size: 21px;
- font-weight: normal;
- display: block;
- color: #777;
+ font-size: 21px;
+ font-weight: normal;
+ display: block;
+ color: var(--td-window-sub-text-fg);
}
section.embed-post small {
- display: block;
- color: #777;
+ display: block;
+ color: var(--td-window-sub-text-fg);
}
section.related {
- margin: 7px 0 12px;
+ margin: 7px 0 12px;
}
section.related h4 {
- font-family: 'Helvetica Neue';
- font-size: 17px;
- line-height: 26px;
- font-weight: 500;
- display: block;
- padding: 7px 18px;
- background: #f7f7f7;
- margin: 0;
- color: #000;
+ font-family: 'Helvetica Neue';
+ font-size: 17px;
+ line-height: 26px;
+ font-weight: 500;
+ display: block;
+ padding: 7px 18px;
+ background: var(--td-box-divider-bg);
+ margin: 0;
+ color: var(--td-window-fg);
}
section.related a.related-link {
- display: block;
- padding: 15px 18px 16px;
- background: #fff;
- position: relative;
- overflow: hidden;
+ display: block;
+ padding: 15px 18px 16px;
+ background: var(--td-window-bg);
+ position: relative;
+ overflow: hidden;
}
section.related a.related-link:after {
- content: '';
- display: block;
- border-bottom: 1px solid #c8c7cb;
- position: absolute;
- left: 18px;
- right: 0;
- bottom: 0;
+ content: '';
+ display: block;
+ border-bottom: 1px solid var(--td-box-divider-fg);
+ position: absolute;
+ left: 18px;
+ right: 0;
+ bottom: 0;
}
section.related .related-link-url {
- display: block;
- font-size: 15px;
- line-height: 18px;
- padding: 7px 0;
- color: #999;
- word-break: break-word;
+ display: block;
+ font-size: 15px;
+ line-height: 18px;
+ padding: 7px 0;
+ color: var(--td-window-sub-text-fg);
+ word-break: break-word;
}
section.related .related-link-thumb {
- display: inline-block;
- float: right;
- width: 87px;
- height: 87px;
- border-radius: 4px;
- background: no-repeat center;
- background-size: cover;
- margin-left: 15px;
+ display: inline-block;
+ float: right;
+ width: 87px;
+ height: 87px;
+ border-radius: 4px;
+ background: no-repeat center;
+ background-size: cover;
+ margin-left: 15px;
}
section.related .related-link-content {
- display: block;
- margin: -3px 0;
+ display: block;
+ margin: -3px 0;
}
section.related .related-link-title {
- font-size: 15px;
- font-weight: 500;
- line-height: 18px;
- display: block;
- display: -webkit-box;
- margin-bottom: 4px;
- max-height: 36px;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: pre-wrap;
- color: #000;
+ font-size: 15px;
+ font-weight: 500;
+ line-height: 18px;
+ display: block;
+ display: -webkit-box;
+ margin-bottom: 4px;
+ max-height: 36px;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: pre-wrap;
+ color: var(--td-window-fg);
}
section.related .related-link-desc {
- font-size: 14px;
- line-height: 17px;
- display: block;
- display: -webkit-box;
- max-height: 51px;
- -webkit-line-clamp: 3;
- -webkit-box-orient: vertical;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: pre-wrap;
- color: #000;
+ font-size: 14px;
+ line-height: 17px;
+ display: block;
+ display: -webkit-box;
+ max-height: 51px;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: pre-wrap;
+ color: var(--td-window-fg);
}
section.related .related-link-source {
- font-size: 13px;
- line-height: 17px;
- display: block;
- overflow: hidden;
- margin-top: 4px;
- text-overflow: ellipsis;
- white-space: nowrap;
- color: #818181;
+ font-size: 13px;
+ line-height: 17px;
+ display: block;
+ overflow: hidden;
+ margin-top: 4px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ color: var(--td-window-sub-text-fg);
}
section.message {
- position: absolute;
- display: table;
- width: 100%;
- height: 100%;
+ position: absolute;
+ display: table;
+ width: 100%;
+ height: 100%;
}
section.message.static {
- position: static;
- min-height: 200px;
- height: 100vh;
+ position: static;
+ min-height: 200px;
+ height: 100vh;
}
section.message > aside {
- display: table-cell;
- vertical-align: middle;
- text-align: center;
- color: #999;
- font-size: 24px;
- pointer-events: none;
+ display: table-cell;
+ vertical-align: middle;
+ text-align: center;
+ color: var(--td-window-sub-text-fg);
+ font-size: 24px;
+ pointer-events: none;
}
section.message > aside > cite {
- display: block;
- font-size: 14px;
- padding: 10px 0 0;
- font-style: normal;
- color: #ccc;
+ display: block;
+ font-size: 14px;
+ padding: 10px 0 0;
+ font-style: normal;
+ color: var(--td-window-sub-text-fg);
}
section.channel {
- margin-top: -16px;
- margin-bottom: -9px;
+ margin-top: -16px;
+ margin-bottom: -9px;
}
section.channel:first-child {
- margin-top: 0;
+ margin-top: 0;
}
section.channel > a {
- display: block;
- padding: 7px 18px;
- background: #f7f7f7;
+ display: block;
+ padding: 7px 18px;
+ background: var(--td-box-divider-bg);
}
section.channel > a:before {
- content: 'Join';
- color: #3196e8;
- font-weight: 500;
- margin-left: 7px;
- float: right;
+ content: var(--td-lng-group-call-join);
+ color: var(--td-window-active-text-fg);
+ font-weight: 500;
+ margin-left: 7px;
+ float: right;
}
section.channel > a > h4 {
- font-family: 'Helvetica Neue';
- font-size: 17px;
- line-height: 26px;
- font-weight: 500;
- margin: 0;
- color: #000;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
+ font-family: 'Helvetica Neue';
+ font-size: 17px;
+ line-height: 26px;
+ font-weight: 500;
+ margin: 0;
+ color: var(--td-window-fg);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
.iv-pullquote {
- text-align: center;
- max-width: 420px;
- font-size: 19px;
- display: block;
- margin: 0 auto;
+ text-align: center;
+ max-width: 420px;
+ font-size: 19px;
+ display: block;
+ margin: 0 auto;
}
.iv-photo-wrap {
- width: 100%;
- background-size: 100%;
- margin: 0 auto;
+ width: 100%;
+ background-size: 100%;
+ margin: 0 auto;
}
.iv-photo {
- background-size: 100%;
+ background-size: 100%;
}
diff --git a/Telegram/Resources/iv_html/page.js b/Telegram/Resources/iv_html/page.js
index 8486e2cc7..b81a556b1 100644
--- a/Telegram/Resources/iv_html/page.js
+++ b/Telegram/Resources/iv_html/page.js
@@ -49,15 +49,13 @@ var IV = {
});
}
},
- postMessageHandler: function(event) {
- if (event.source !== window.parent ||
- event.origin != window.parentOrigin) {
- return;
- }
- try {
- var data = JSON.parse(event.data);
- } catch(e) {
- var data = {};
+ updateStyles: function (styles) {
+ if (IV.styles !== styles) {
+ console.log('Setting', styles);
+ IV.styles = styles;
+ document.getElementsByTagName('html')[0].style = styles;
+ } else {
+ console.log('Skipping', styles);
}
},
slideshowSlide: function(el, next) {
diff --git a/Telegram/SourceFiles/iv/iv_controller.cpp b/Telegram/SourceFiles/iv/iv_controller.cpp
index 709461eaa..b2e6e0582 100644
--- a/Telegram/SourceFiles/iv/iv_controller.cpp
+++ b/Telegram/SourceFiles/iv/iv_controller.cpp
@@ -8,13 +8,18 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "iv/iv_controller.h"
#include "base/platform/base_platform_info.h"
+#include "base/invoke_queued.h"
#include "iv/iv_data.h"
+#include "lang/lang_keys.h"
#include "ui/widgets/rp_window.h"
#include "webview/webview_data_stream_memory.h"
#include "webview/webview_embed.h"
#include "webview/webview_interface.h"
#include "styles/palette.h"
+#include "base/call_delayed.h"
+#include "ui/effects/animations.h"
+
#include
#include
#include
@@ -23,8 +28,99 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include
namespace Iv {
+namespace {
-Controller::Controller() = default;
+[[nodiscard]] QByteArray ComputeStyles() {
+ static const auto map = base::flat_map{
+ { "scroll-bg", &st::scrollBg },
+ { "scroll-bg-over", &st::scrollBgOver },
+ { "scroll-bar-bg", &st::scrollBarBg },
+ { "scroll-bar-bg-over", &st::scrollBarBgOver },
+ { "window-bg", &st::windowBg },
+ { "window-bg-over", &st::windowBgOver },
+ { "window-bg-ripple", &st::windowBgRipple },
+ { "window-fg", &st::windowFg },
+ { "window-sub-text-fg", &st::windowSubTextFg },
+ { "window-active-text-fg", &st::windowActiveTextFg },
+ { "window-bg-active", &st::windowBgActive },
+ { "box-divider-bg", &st::boxDividerBg },
+ { "box-divider-fg", &st::boxDividerFg },
+ };
+ static const auto phrases = base::flat_map>{
+ { "group-call-join", tr::lng_group_call_join },
+ };
+ static const auto serialize = [](const style::color *color) {
+ const auto qt = (*color)->c;
+ if (qt.alpha() == 255) {
+ return '#'
+ + QByteArray::number(qt.red(), 16).right(2)
+ + QByteArray::number(qt.green(), 16).right(2)
+ + QByteArray::number(qt.blue(), 16).right(2);
+ }
+ return "rgba("
+ + QByteArray::number(qt.red()) + ","
+ + QByteArray::number(qt.green()) + ","
+ + QByteArray::number(qt.blue()) + ","
+ + QByteArray::number(qt.alpha() / 255.) + ")";
+ };
+ static const auto escape = [](tr::phrase<> phrase) {
+ const auto text = phrase(tr::now);
+
+ auto result = QByteArray();
+ for (auto i = 0; i != text.size(); ++i) {
+ uint ucs4 = text[i].unicode();
+ if (QChar::isHighSurrogate(ucs4) && i + 1 != text.size()) {
+ ushort low = text[i + 1].unicode();
+ if (QChar::isLowSurrogate(low)) {
+ ucs4 = QChar::surrogateToUcs4(ucs4, low);
+ ++i;
+ }
+ }
+ if (ucs4 == '\'' || ucs4 == '\"' || ucs4 == '\\') {
+ result.append('\\').append(char(ucs4));
+ } else if (ucs4 < 32 || ucs4 > 127) {
+ result.append('\\' + QByteArray::number(ucs4, 16) + ' ');
+ } else {
+ result.append(char(ucs4));
+ }
+ }
+ return result;
+ };
+ auto result = QByteArray();
+ for (const auto &[name, phrase] : phrases) {
+ result += "--td-lng-" + name + ":'" + escape(phrase) + "'; ";
+ }
+ for (const auto &[name, color] : map) {
+ result += "--td-" + name + ':' + serialize(color) + ';';
+ }
+ return result;
+}
+
+[[nodiscard]] QByteArray EscapeForAttribute(QByteArray value) {
+ return value
+ .replace('&', "&")
+ .replace('"', """)
+ .replace('\'', "'")
+ .replace('<', "<")
+ .replace('>', ">");
+}
+
+[[nodiscard]] QByteArray EscapeForScriptString(QByteArray value) {
+ return value
+ .replace('\\', "\\\\")
+ .replace('"', "\\\"")
+ .replace('\'', "\\\'");
+}
+
+} // namespace
+Controller::Controller()
+: _updateStyles([=] {
+ const auto str = EscapeForScriptString(ComputeStyles());
+ if (_webview) {
+ _webview->eval("IV.updateStyles(\"" + str + "\");");
+ }
+}) {
+}
Controller::~Controller() {
_webview = nullptr;
@@ -32,21 +128,66 @@ Controller::~Controller() {
}
void Controller::show(const QString &dataPath, Prepared page) {
+ createWindow();
+ InvokeQueued(_container, [=, page = std::move(page)]() mutable {
+ showInWindow(dataPath, std::move(page));
+ });
+}
+
+void Controller::createWindow() {
_window = std::make_unique();
const auto window = _window.get();
window->setGeometry({ 200, 200, 600, 800 });
- const auto container = Ui::CreateChild(
- window->body().get());
- window->sizeValue() | rpl::start_with_next([=](QSize size) {
- container->setGeometry(QRect(QPoint(), size));
- }, container->lifetime());
- container->show();
+ const auto skip = window->lifetime().make_state>(0);
+ _container = Ui::CreateChild(window->body().get());
+ rpl::combine(
+ window->body()->sizeValue(),
+ skip->value()
+ ) | rpl::start_with_next([=](QSize size, int skip) {
+ _container->setGeometry(QRect(QPoint(), size).marginsRemoved({ 0, skip, 0, 0 }));
+ }, _container->lifetime());
+
+ base::call_delayed(5000, window, [=] {
+ const auto animation = window->lifetime().make_state();
+ animation->start([=] {
+ *skip = animation->value(64);
+ if (!animation->animating()) {
+ base::call_delayed(4000, window, [=] {
+ animation->start([=] {
+ *skip = animation->value(0);
+ }, 64, 0, 200, anim::easeOutCirc);
+ });
+ }
+ }, 0, 64, 200, anim::easeOutCirc);
+ });
+
+ window->body()->paintRequest() | rpl::start_with_next([=](QRect clip) {
+ auto p = QPainter(window->body());
+ p.fillRect(clip, st::windowBg);
+ p.fillRect(clip, QColor(0, 128, 0, 128));
+ }, window->body()->lifetime());
+
+ _container->paintRequest() | rpl::start_with_next([=](QRect clip) {
+ QPainter(_container).fillRect(clip, st::windowBg);
+ }, _container->lifetime());
+
+ _container->show();
+ window->show();
+}
+
+void Controller::showInWindow(const QString &dataPath, Prepared page) {
+ Expects(_container != nullptr);
+
+ const auto window = _window.get();
_webview = std::make_unique(
- container,
- Webview::WindowConfig{ .userDataPath = dataPath });
+ _container,
+ Webview::WindowConfig{
+ .opaqueBg = st::windowBg->c,
+ .userDataPath = dataPath,
+ });
const auto raw = _webview.get();
window->lifetime().add([=] {
@@ -69,14 +210,10 @@ void Controller::show(const QString &dataPath, Prepared page) {
}, window->lifetime());
raw->widget()->show();
- container->geometryValue(
- ) | rpl::start_with_next([=](QRect geometry) {
- raw->widget()->setGeometry(geometry);
- }, container->lifetime());
-
- container->paintRequest() | rpl::start_with_next([=](QRect clip) {
- QPainter(container).fillRect(clip, st::windowBg);
- }, container->lifetime());
+ _container->sizeValue(
+ ) | rpl::start_with_next([=](QSize size) {
+ raw->widget()->setGeometry(QRect(QPoint(), size));
+ }, _container->lifetime());
raw->setNavigationStartHandler([=](const QString &uri, bool newWindow) {
return true;
@@ -113,12 +250,27 @@ void Controller::show(const QString &dataPath, Prepared page) {
.stream = std::make_unique(
std::move(data),
std::move(mime)),
- });
+ });
return Webview::DataResult::Done;
};
const auto id = std::string_view(request.id).substr(3);
if (id == "page.html") {
- return finishWith(page.html, "text/html");
+ const auto i = page.html.indexOf("= 0);
+ const auto colored = page.html.mid(0, i + 5)
+ + " style=\"" + EscapeForAttribute(ComputeStyles()) + "\""
+ + page.html.mid(i + 5);
+ if (!_subscribedToColors) {
+ _subscribedToColors = true;
+
+ rpl::merge(
+ Lang::Updated(),
+ style::PaletteChanged()
+ ) | rpl::start_with_next([=] {
+ _updateStyles.call();
+ }, _webview->lifetime());
+ }
+ return finishWith(colored, "text/html");
}
const auto css = id.ends_with(".css");
const auto js = !css && id.ends_with(".js");
@@ -140,8 +292,6 @@ void Controller::show(const QString &dataPath, Prepared page) {
raw->init(R"(
)");
raw->navigateToData("iv/page.html");
-
- window->show();
}
bool Controller::active() const {
diff --git a/Telegram/SourceFiles/iv/iv_controller.h b/Telegram/SourceFiles/iv/iv_controller.h
index 7e623f7ce..5a081ca32 100644
--- a/Telegram/SourceFiles/iv/iv_controller.h
+++ b/Telegram/SourceFiles/iv/iv_controller.h
@@ -7,12 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
+#include "base/invoke_queued.h"
+
namespace Webview {
struct DataRequest;
class Window;
} // namespace Webview
namespace Ui {
+class RpWidget;
class RpWindow;
} // namespace Ui
@@ -45,14 +48,21 @@ public:
[[nodiscard]] rpl::lifetime &lifetime();
private:
+ void createWindow();
+ void showInWindow(const QString &dataPath, Prepared page);
+
void escape();
void close();
void quit();
std::unique_ptr _window;
+ Ui::RpWidget *_container = nullptr;
std::unique_ptr _webview;
rpl::event_stream _dataRequests;
rpl::event_stream _events;
+ SingleQueuedInvokation _updateStyles;
+ bool _subscribedToColors = false;
+
rpl::lifetime _lifetime;
};
diff --git a/Telegram/SourceFiles/iv/iv_prepare.cpp b/Telegram/SourceFiles/iv/iv_prepare.cpp
index 69a86689c..dc93510c7 100644
--- a/Telegram/SourceFiles/iv/iv_prepare.cpp
+++ b/Telegram/SourceFiles/iv/iv_prepare.cpp
@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "iv/iv_data.h"
#include "lang/lang_keys.h"
#include "ui/image/image_prepare.h"
+#include "styles/palette.h"
#include
@@ -1009,8 +1010,14 @@ QByteArray Parser::prepare(QByteArray body) {
}
QByteArray Parser::html(const QByteArray &head, const QByteArray &body) {
+#ifdef Q_OS_MAC
+ const auto classAttribute = ""_q;
+#else // Q_OS_MAC
+ const auto classAttribute = " class=\"custom_scroll\""_q;
+#endif // Q_OS_MAC
+
return R"(
-
+