hexo-theme-solitude 1.8.9 → 1.8.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/_config.yml +2 -25
  2. package/languages/default.yml +7 -0
  3. package/languages/en.yml +7 -0
  4. package/languages/zh-CN.yml +7 -0
  5. package/languages/zh-TW.yml +7 -0
  6. package/layout/includes/footer.pug +1 -1
  7. package/layout/includes/head/page_config.pug +1 -1
  8. package/layout/includes/inject/body.pug +5 -5
  9. package/layout/includes/inject/head.pug +3 -3
  10. package/layout/includes/page/links.pug +0 -2
  11. package/layout/includes/page/music.pug +6 -1
  12. package/layout/includes/widgets/aside/asideInfoCard.pug +54 -20
  13. package/layout/includes/widgets/aside/asideWebInfo.pug +12 -4
  14. package/layout/includes/widgets/home/carousel.pug +27 -21
  15. package/layout/includes/widgets/post/post-ai.pug +2 -2
  16. package/layout/includes/widgets/post/postMeta.pug +6 -2
  17. package/layout/includes/widgets/third-party/comments/artalk.pug +3 -3
  18. package/layout/includes/widgets/third-party/comments/twikoo.pug +4 -2
  19. package/layout/includes/widgets/third-party/comments/valine.pug +5 -3
  20. package/layout/includes/widgets/third-party/comments/waline.pug +4 -2
  21. package/layout/page.pug +4 -6
  22. package/package.json +1 -1
  23. package/plugins.yml +5 -1
  24. package/scripts/event/merge_config.js +1 -13
  25. package/source/css/_layout/aside.styl +363 -225
  26. package/source/css/_layout/header.styl +7 -6
  27. package/source/css/_layout/sidebar.styl +2 -2
  28. package/source/css/_page/_home/carousel.styl +73 -89
  29. package/source/css/_page/index.styl +0 -3
  30. package/source/css/_page/links.styl +1 -1
  31. package/source/js/barrage_comment.js +63 -70
  32. package/source/js/covercolor/api.js +35 -52
  33. package/source/js/covercolor/local.js +22 -27
  34. package/source/js/main.js +472 -567
  35. package/source/js/music.js +15 -5
  36. package/source/js/right_menu.js +38 -47
  37. package/source/js/search/local.js +16 -11
  38. package/source/js/utils.js +109 -136
  39. package/.github/workflows/github-publish.yml +0 -20
  40. package/layout/includes/page/moment.pug +0 -28
  41. package/layout/includes/widgets/page/moments/angle.pug +0 -19
  42. package/source/css/_page/moment.styl +0 -180
@@ -4,47 +4,10 @@ div#swiper_container
4
4
  position relative
5
5
  transition all .3s
6
6
  overflow hidden
7
-
8
- #swiperBox.recent-post-item
9
- width 100%
10
- cursor default
11
- margin-top 0
12
-
13
- #swiperBox
14
-
15
- .swiperBox-top-text
16
- position absolute
17
- z-index 2
18
- color var(--efu-white)
19
- background var(--efu-red)
20
- letter-spacing 3px
21
- top 0
22
- left 15px
23
- font-size 15px
24
- width 35px
25
- display flex
26
- justify-content center
27
- border-radius 0 0 12px 12px
28
-
29
- .swiper-button-next::after, .swiper-button-prev::after
30
- font-size 1rem !important
31
-
32
- .swiper-button-prev, .swiper-button-next
33
- transition all .3s
34
- border-radius 5px
35
- color var(--efu-main) !important
36
- background var(--efu-maskbg)
37
- opacity .5
38
-
39
- &:hover
40
- opacity 1
41
- transition all .3s
42
- color var(--efu-white) !important
43
- background var(--efu-main)
44
-
45
- .swiper-button-next::after, .swiper-button-prev::after
46
- font-size 1.5rem
47
- color var(--efu-bg)
7
+ display flex
8
+ flex-direction row
9
+ justify-content center
10
+ align-items center
48
11
 
49
12
  .blog-slider__pagination .swiper-pagination-bullet
50
13
  margin 0 8px
@@ -52,71 +15,92 @@ div#swiper_container
52
15
  height 11px
53
16
  display inline-block
54
17
  border-radius 99px
55
- background var(--efu-white)
56
- opacity .8
18
+ background var(--efu-gray)
19
+ opacity .2
57
20
  transition all .3s
58
21
 
59
22
  .blog-slider__pagination .swiper-pagination-bullet-active
60
23
  opacity 1
61
24
  background var(--efu-main)
62
- width 30px
25
+ height 30px
63
26
 
64
27
  .blog-slider__pagination
65
28
  position absolute
66
29
  z-index 21
67
30
  text-align center
31
+ display flex
32
+ justify-content space-between
33
+ flex-direction column
34
+ height 60%
68
35
 
69
- #recent-posts > #swiperBox.recent-post-item
70
- cursor default
71
-
72
- .blog-slider__item
73
- background-size cover
74
- background-position center
75
- overflow hidden
76
-
77
- &::after
78
- content ''
79
- position absolute
80
- width 100%
81
- height 100%
82
- background-color rgba(0, 0, 0, .5)
83
- z-index -1
84
- left 0
85
- top 0
86
-
87
- .blog-slider__content > *
88
- text-align center
89
- line-height 1.5
90
- margin 2px 0
91
- color var(--efu-white)
36
+ #swiperBox.recent-post-item
37
+ width 100%
38
+ margin-top 0
39
+ +maxWidth798()
40
+ display none
92
41
 
93
- a.blog-slider__title
94
- font-size 2rem
42
+ #swiperBox
43
+ .blog-slider__item.swiper-slide
44
+ padding 1rem
45
+ display flex
46
+ justify-content space-between
47
+ flex-direction row
48
+ height 100%
95
49
 
96
- +maxWidth768()
97
- font-size 1.3rem
50
+ &:hover
51
+ .blog-slider__img
52
+ img
53
+ transform scale(1.1)
54
+ transition all .3s
98
55
 
99
- .blog-slider__code
100
- display block
101
- font-weight 500
56
+ .blog-slider__title
57
+ color var(--efu-main)
58
+ transition all .3s
102
59
 
103
- .blog-slider__text
104
- font-size 18px
105
- -webkit-line-clamp 2
60
+ .blog-slider__img
61
+ border-radius 12px
106
62
  overflow hidden
107
- display -webkit-box
108
- -webkit-box-orient vertical
109
- +minWidth1300()
110
- padding 0 5rem
111
- +maxWidth900()
112
- padding 0 3rem
113
- +maxWidth768()
114
- display none
63
+ width 35%
64
+ height 100%
65
+ transition all .3s
66
+ cursor pointer
67
+
68
+ img
69
+ width 100%
70
+ height 100%
71
+ object-fit cover
115
72
 
116
73
  .blog-slider__content
117
- padding 0 50px 20px
74
+ margin 0 2rem 0 1rem
75
+ position relative
76
+ width 65%
118
77
  display flex
119
- justify-content center
120
- align-items center
78
+ align-items left
121
79
  flex-direction column
122
- height 100%
80
+ height 100%
81
+
82
+ .article-meta-wrap
83
+ padding 0
84
+ bottom 0
85
+
86
+ .tags-punctuation
87
+ &:hover
88
+ color var(--efu-main)
89
+ transition all .3s
90
+
91
+ .blog-slider__title
92
+ font-size 1.5rem
93
+ font-weight 600
94
+ color var(--efu-fontcolor)
95
+ margin 0
96
+ transition all .3s
97
+ cursor pointer
98
+
99
+ .blog-slider__desc
100
+ -webkit-line-clamp: 4;
101
+ display: -webkit-box;
102
+ overflow: hidden;
103
+ -webkit-box-orient: vertical;
104
+ opacity: 0.8;
105
+ font-size: 14px;
106
+ line-height: 1.8;
@@ -6,9 +6,6 @@
6
6
 
7
7
  @import "error.styl"
8
8
 
9
- if hexo-config('moments.enable')
10
- @import "moment.styl"
11
-
12
9
  if hexo-config('says.enable')
13
10
  @import "says.styl"
14
11
 
@@ -17,7 +17,7 @@
17
17
  box-shadow var(--efu-shadow-blue)
18
18
  color var(--efu-white)
19
19
  z-index 1
20
- border-radius 12px 0 12px 0
20
+ border-radius 0 0 12px 0
21
21
  transition .3s
22
22
  font-size .6rem
23
23
  overflow hidden
@@ -1,84 +1,77 @@
1
- function initializeCommentBarrage(array) {
2
- if (array === []) return;
3
- let existingBarrage = window.currentBarrage;
4
-
5
- if (existingBarrage) {
6
- existingBarrage.destroy();
1
+ class Barrage {
2
+ constructor(comments) {
3
+ this.comments = comments;
4
+ this.dom = document.querySelector(".comment-barrage");
5
+ this.barrageList = [];
6
+ this.barrageIndex = 0;
7
+ this.barrageTimer = [];
8
+ this.hoverOnCommentBarrage = false;
9
+ this.init();
7
10
  }
8
11
 
9
- let barrage = class {
10
- constructor() {
11
- this.config = {
12
- barrageTimer: [],
13
- barrageList: [],
14
- barrageIndex: 0,
15
- dom: document.querySelector(".comment-barrage"),
16
- maxBarrage: 1,
17
- barrageTime: 5000
18
- };
19
- this.hoverOnCommentBarrage = false;
20
- this.init();
21
- }
22
-
23
- filterAndFlatten(comments) {
24
- return comments.flatMap(comment => comment.replies ? [comment, ...this.filterAndFlatten(comment.replies)] : [comment]);
25
- }
12
+ filterAndFlatten = (comments) => {
13
+ return (comments.flatMap(comment => comment.replies ? [comment, ...this.filterAndFlatten(comment.replies)] : [comment]))
14
+ }
26
15
 
27
- sanitizeContent(content) {
28
- return content.replace(/(<([^>]+)>)/ig, '').trim();
29
- }
16
+ sanitizeContent(content) {
17
+ return content.replace(/(<([^>]+)>)/ig, '').trim();
18
+ }
30
19
 
31
- createBarrageItem(comment) {
32
- const content = this.sanitizeContent(comment.content);
33
- if (!content) return false;
34
- const element = document.createElement("div");
35
- element.className = "comment-barrage-item";
36
- element.innerHTML = `<div class="barrageHead"><a class="barrageTitle" href="javascript:sco.scrollTo('post-comment')">${GLOBAL_CONFIG.lang.barrage.title}</a><div class="barrageNick">${comment.nick}</div><img class="barrageAvatar" src="${GLOBAL_CONFIG.comment.avatar}/avatar/${comment.mailMd5}"/><a class="comment-barrage-close" href="javascript:sco.switchCommentBarrage();"><i class="solitude st-close-fill"></i></a></div><a class="barrageContent" href="${comment.id ? `javascript:sco.scrollTo(\'${comment.id}\')` : 'javascript:sco.scrollTo(\'post-comment\')'}">${content}</a>`;
37
- this.config.dom.appendChild(element);
38
- this.config.barrageTimer.push(element);
39
- return true;
40
- }
20
+ createBarrageItem(comment) {
21
+ const content = this.sanitizeContent(comment.content);
22
+ if (!content) return false;
23
+ const element = document.createElement("div");
24
+ element.className = "comment-barrage-item";
25
+ element.innerHTML = `<div class="barrageHead"><a class="barrageTitle" href="javascript:sco.scrollTo('post-comment')">${GLOBAL_CONFIG.lang.barrage.title}</a><div class="barrageNick">${comment.nick}</div><img class="barrageAvatar" src="${GLOBAL_CONFIG.comment.avatar}/avatar/${comment.mailMd5}"/><a class="comment-barrage-close" href="javascript:sco.switchCommentBarrage();"><i class="solitude st-close-fill"></i></a></div><a class="barrageContent" href="${comment.id ? `javascript:sco.scrollTo(\'${comment.id}\')` : 'javascript:sco.scrollTo(\'post-comment\')'}">${content}</a>`;
26
+ this.dom.appendChild(element);
27
+ this.barrageTimer.push(element);
28
+ return true;
29
+ }
41
30
 
42
- removeBarrageItem(element) {
43
- element.classList.add("out");
44
- setTimeout(() => this.config.dom.removeChild(element), 1000);
45
- }
31
+ removeBarrageItem(element) {
32
+ element.classList.add("out");
33
+ setTimeout(() => this.dom.removeChild(element), 1000);
34
+ }
46
35
 
47
- manageBarrage() {
48
- if (this.config.barrageList.length && !this.hoverOnCommentBarrage) {
49
- if (!this.createBarrageItem(this.config.barrageList[this.config.barrageIndex])) {
50
- this.config.barrageIndex = (this.config.barrageIndex + 1) % this.config.barrageList.length;
51
- return this.manageBarrage();
52
- }
53
- this.config.barrageIndex = (this.config.barrageIndex + 1) % this.config.barrageList.length;
54
- }
55
- if (this.config.barrageTimer.length > Math.min(this.config.maxBarrage, this.config.barrageList.length) && !this.hoverOnCommentBarrage) {
56
- this.removeBarrageItem(this.config.barrageTimer.shift());
36
+ manageBarrage() {
37
+ if (this.barrageList.length && !this.hoverOnCommentBarrage) {
38
+ if (!this.createBarrageItem(this.barrageList[this.barrageIndex])) {
39
+ this.barrageIndex = (this.barrageIndex + 1) % this.barrageList.length;
40
+ return this.manageBarrage();
57
41
  }
42
+ this.barrageIndex = (this.barrageIndex + 1) % this.barrageList.length;
58
43
  }
59
-
60
- async initBarrage() {
61
- const storageSwitch = utils.saveToLocal.get("commentBarrageSwitch");
62
- this.config.dom.style.display = storageSwitch ? "flex" : "none";
63
- this.config.barrageList = this.filterAndFlatten(array);
64
- this.config.dom.innerHTML = "";
65
- clearInterval(this.commentInterval);
66
- this.commentInterval = setInterval(() => this.manageBarrage(), this.config.barrageTime);
44
+ if (this.barrageTimer.length > Math.min(1, this.barrageList.length) && !this.hoverOnCommentBarrage) {
45
+ this.removeBarrageItem(this.barrageTimer.shift());
67
46
  }
47
+ }
68
48
 
69
- async init() {
70
- await this.initBarrage();
71
- this.config.dom.addEventListener('mouseover', () => this.hoverOnCommentBarrage = true);
72
- this.config.dom.addEventListener('mouseout', () => this.hoverOnCommentBarrage = false);
73
- }
49
+ initBarrage() {
50
+ const storageSwitch = utils.saveToLocal.get("commentBarrageSwitch");
51
+ this.dom.style.display = storageSwitch ? "flex" : "none";
52
+ this.barrageList = this.filterAndFlatten(this.comments);
53
+ this.dom.innerHTML = "";
54
+ clearInterval(this.commentInterval);
55
+ this.commentInterval = setInterval(() => this.manageBarrage(), 5000);
56
+ }
74
57
 
75
- destroy() {
76
- clearInterval(this.commentInterval);
77
- this.config.dom.removeEventListener('mouseover', () => this.hoverOnCommentBarrage = true)
78
- this.config.dom.removeEventListener('mouseout', () => this.hoverOnCommentBarrage = false)
79
- this.config.dom.innerHTML = ""
80
- }
58
+ init() {
59
+ this.initBarrage();
60
+ this.dom.addEventListener('mouseover', () => this.hoverOnCommentBarrage = true);
61
+ this.dom.addEventListener('mouseout', () => this.hoverOnCommentBarrage = false);
62
+ }
63
+
64
+ destroy() {
65
+ clearInterval(this.commentInterval);
66
+ this.dom.removeEventListener('mouseover', () => this.hoverOnCommentBarrage = true)
67
+ this.dom.removeEventListener('mouseout', () => this.hoverOnCommentBarrage = false)
68
+ this.dom.innerHTML = ""
81
69
  }
70
+ }
82
71
 
83
- window.currentBarrage = new barrage();
72
+ function initializeCommentBarrage(array) {
73
+ if (array.length === 0) return;
74
+ let existingBarrage = window.currentBarrage;
75
+ if (existingBarrage) existingBarrage.destroy();
76
+ window.currentBarrage = new Barrage(array);
84
77
  }
@@ -1,76 +1,59 @@
1
1
  const coverColor = () => {
2
2
  const path = document.getElementById("post-cover")?.src;
3
- if (path) {
4
- handleApiColor(path);
5
- } else {
6
- document.documentElement.style.setProperty('--efu-main', 'var(--efu-theme)');
7
- document.documentElement.style.setProperty('--efu-main-op', 'var(--efu-theme-op)');
8
- document.documentElement.style.setProperty('--efu-main-op-deep', 'var(--efu-theme-op-deep)');
9
- document.documentElement.style.setProperty('--efu-main-none', 'var(--efu-theme-none)');
10
- initThemeColor()
11
- }
3
+ path ? handleApiColor(path) : setDefaultThemeColors();
12
4
  }
13
5
 
14
6
  function handleApiColor(path) {
15
7
  const cacheGroup = JSON.parse(localStorage.getItem('Solitude')) || {};
16
- if (cacheGroup.postcolor && cacheGroup.postcolor[path]) {
17
- const color = cacheGroup.postcolor[path].value;
18
- const [r, g, b] = color.match(/\w\w/g).map(x => parseInt(x, 16));
19
- setThemeColors(color, r, g, b);
20
- } else {
21
- img2color(path);
22
- }
8
+ cacheGroup.postcolor && cacheGroup.postcolor[path] ? setThemeColors(cacheGroup.postcolor[path].value) : img2color(path);
23
9
  }
24
10
 
25
11
  function img2color(src) {
26
- const apiUrl = coverColorConfig.api + encodeURIComponent(src);
27
- fetch(apiUrl)
12
+ fetch(coverColorConfig.api + encodeURIComponent(src))
28
13
  .then(response => response.json())
29
14
  .then(data => {
30
- const color = data.RGB;
31
- const [r, g, b] = color.match(/\w\w/g).map(x => parseInt(x, 16));
32
- setThemeColors(color, r, g, b);
33
- const expirationTime = Date.now() + coverColorConfig.time;
34
- const cacheGroup = JSON.parse(localStorage.getItem('Solitude')) || {};
35
- cacheGroup.postcolor = cacheGroup.postcolor || {};
36
- cacheGroup.postcolor[src] = {value: color, expiration: expirationTime};
37
- localStorage.setItem('Solitude', JSON.stringify(cacheGroup));
15
+ setThemeColors(data.RGB);
16
+ cacheColor(src, data.RGB);
38
17
  })
39
- .catch(error => {
40
- console.error('请检查API是否正常!\n' + error);
41
- });
18
+ .catch(console.error);
42
19
  }
43
20
 
44
- function setThemeColors(value, r = null, g = null, b = null) {
21
+ function setThemeColors(value) {
45
22
  if (value) {
23
+ const [r, g, b] = value.match(/\w\w/g).map(x => parseInt(x, 16));
46
24
  document.documentElement.style.setProperty('--efu-main', value);
47
25
  document.documentElement.style.setProperty('--efu-main-op', value + '23');
48
26
  document.documentElement.style.setProperty('--efu-main-op-deep', value + 'dd');
49
27
  document.documentElement.style.setProperty('--efu-main-none', value + '00');
50
-
51
- if (r && g && b) {
52
- let brightness = Math.round(((parseInt(r) * 299) + (parseInt(g) * 587) + (parseInt(b) * 114)) / 1000);
53
- if (brightness < 125) {
54
- let cardContents = document.getElementsByClassName('card-content');
55
- for (let i = 0; i < cardContents.length; i++) {
56
- cardContents[i].style.setProperty('--efu-card-bg', 'var(--efu-white)');
57
- }
58
-
59
- let authorInfo = document.getElementsByClassName('author-info__sayhi');
60
- for (let i = 0; i < authorInfo.length; i++) {
61
- authorInfo[i].style.setProperty('background', 'var(--efu-white-op)');
62
- authorInfo[i].style.setProperty('color', 'var(--efu-white)');
63
- }
64
- }
65
- }
66
-
28
+ adjustBrightness(r, g, b);
67
29
  document.getElementById("coverdiv").classList.add("loaded");
68
30
  initThemeColor();
69
31
  } else {
70
- document.documentElement.style.setProperty('--efu-main', 'var(--efu-theme)');
71
- document.documentElement.style.setProperty('--efu-main-op', 'var(--efu-theme-op)');
72
- document.documentElement.style.setProperty('--efu-main-op-deep', 'var(--efu-theme-op-deep)');
73
- document.documentElement.style.setProperty('--efu-main-none', 'var(--efu-theme-none)');
74
- initThemeColor();
32
+ setDefaultThemeColors();
33
+ }
34
+ }
35
+
36
+ function setDefaultThemeColors() {
37
+ document.documentElement.style.setProperty('--efu-main', 'var(--efu-theme)');
38
+ document.documentElement.style.setProperty('--efu-main-op', 'var(--efu-theme-op)');
39
+ document.documentElement.style.setProperty('--efu-main-op-deep', 'var(--efu-theme-op-deep)');
40
+ document.documentElement.style.setProperty('--efu-main-none', 'var(--efu-theme-none)');
41
+ initThemeColor();
42
+ }
43
+
44
+ function cacheColor(src, color) {
45
+ const cacheGroup = JSON.parse(localStorage.getItem('Solitude')) || {};
46
+ cacheGroup.postcolor = cacheGroup.postcolor || {};
47
+ cacheGroup.postcolor[src] = {value: color, expiration: Date.now() + coverColorConfig.time};
48
+ localStorage.setItem('Solitude', JSON.stringify(cacheGroup));
49
+ }
50
+
51
+ function adjustBrightness(r, g, b) {
52
+ if (Math.round(((r * 299) + (g * 587) + (b * 114)) / 1000) < 125) {
53
+ [...document.getElementsByClassName('card-content')].forEach(item => item.style.setProperty('--efu-card-bg', 'var(--efu-white)'));
54
+ [...document.getElementsByClassName('author-info__sayhi')].forEach(item => {
55
+ item.style.setProperty('background', 'var(--efu-white-op)');
56
+ item.style.setProperty('color', 'var(--efu-white)');
57
+ });
75
58
  }
76
59
  }
@@ -1,39 +1,34 @@
1
1
  const coverColor = () => {
2
2
  const path = document.getElementById("post-cover")?.src;
3
- if (path) {
4
- localColor(path);
5
- } else {
6
- document.documentElement.style.setProperty('--efu-main', 'var(--efu-theme)');
7
- document.documentElement.style.setProperty('--efu-main-op', 'var(--efu-theme-op)');
8
- document.documentElement.style.setProperty('--efu-main-op-deep', 'var(--efu-theme-op-deep)');
9
- document.documentElement.style.setProperty('--efu-main-none', 'var(--efu-theme-none)');
10
- initThemeColor()
11
- }
3
+ path ? localColor(path) : setDefaultThemeColors();
12
4
  }
13
5
 
14
- const localColor = (path) => {
6
+ function setDefaultThemeColors() {
7
+ document.documentElement.style.setProperty('--efu-main', 'var(--efu-theme)');
8
+ document.documentElement.style.setProperty('--efu-main-op', 'var(--efu-theme-op)');
9
+ document.documentElement.style.setProperty('--efu-main-op-deep', 'var(--efu-theme-op-deep)');
10
+ document.documentElement.style.setProperty('--efu-main-none', 'var(--efu-theme-none)');
11
+ initThemeColor();
12
+ }
13
+
14
+ const localColor = path => {
15
15
  const img = new Image();
16
16
  img.crossOrigin = "Anonymous";
17
- img.onload = function () {
18
- const canvas = document.createElement("canvas");
19
- canvas.width = img.width;
20
- canvas.height = img.height;
21
- const ctx = canvas.getContext("2d");
22
- ctx.drawImage(img, 0, 0);
23
- const data = ctx.getImageData(0, 0, img.width, img.height).data;
24
- const {r, g, b} = calculateRGB(data);
25
- let value = rgbToHex(r, g, b);
26
- if (getContrastYIQ(value) === "light") {
27
- value = LightenDarkenColor(value, -50);
28
- }
29
- setThemeColors(value, r, g, b);
30
- };
31
- img.onerror = function () {
32
- console.error('图片加载失败');
33
- };
17
+ img.onload = () => setThemeColors(calculateColor(img));
18
+ img.onerror = () => console.error('Image Error');
34
19
  img.src = path;
35
20
  }
36
21
 
22
+ const calculateColor = img => {
23
+ const canvas = document.createElement("canvas");
24
+ const ctx = canvas.getContext("2d");
25
+ ctx.drawImage(img, 0, 0);
26
+ const data = ctx.getImageData(0, 0, img.width, img.height).data;
27
+ const {r, g, b} = calculateRGB(data);
28
+ let value = rgbToHex(r, g, b);
29
+ return getContrastYIQ(value) === "light" ? LightenDarkenColor(value, -50) : value;
30
+ }
31
+
37
32
  function calculateRGB(data) {
38
33
  let r = 0, g = 0, b = 0;
39
34
  const step = 5;