diff --git a/app/about.html b/app/about.html index b792f66f..5e95fb75 100644 --- a/app/about.html +++ b/app/about.html @@ -105,7 +105,7 @@
Copyright © TheDesk 2018
- Main developer(author): Cutls P
+ Main developer(author): Cutls P
Thanks:toneji/popn_ja/ .emoji-img { width: 2.3rem !important; diff --git a/app/css/userdata.css b/app/css/userdata.css index c18efe04..ab3de24d 100644 --- a/app/css/userdata.css +++ b/app/css/userdata.css @@ -24,21 +24,20 @@ } #his-float-data { height: 100%; - overflow-y: hidden; - + overflow-y: hidden; } #his-leftside { - width: 28.4rem; - max-width: 30vw; + width: 28.4rem; + max-width: 30vw; } #his-float-timeline { - max-width: 47.5rem; - min-width: calc(100% - 29.4rem); + max-width: 47.5rem; + width: calc(100% - 28.4rem); height: 100%; overflow-y: hidden; } #his-basic-prof { - display: flex; + display: flex; min-height: 10rem; } #his-field { @@ -150,7 +149,7 @@ background-color: var(--bg); } #hisdropdown li a { - color: white; + color: var(--text); } #hisdropdown li:hover { background-color: var(--active); @@ -160,11 +159,14 @@ text-align: center; font-size: 1.5rem; display: flex; - justify-content: center; - align-items: center; + justify-content: center; + align-items: center; } #his-data-title .material-icons { position: relative; - top: 7px; - margin-right: 3px; + top: 5px; + margin-right: 3px; +} +#his-data-title a { + color: white; } \ No newline at end of file diff --git a/app/js/common/version.js b/app/js/common/version.js index fcf6a0ff..3fbf5b0c 100644 --- a/app/js/common/version.js +++ b/app/js/common/version.js @@ -5,20 +5,6 @@ function verck(ver, jp) { $('body').addClass(localStorage.getItem('platform')) var date = new Date() var showVer = false - //Spotify - if (localStorage.getItem('spotify')) { - localStorage.removeItem('spotify') - localStorage.removeItem('spotify-refresh') - var spDc = 'Spotify NowPlaying sysytem was changed, please re-login to Spotify' - if(lang.language == 'ja') { - spDc = 'Spotify NowPlayingの機能が変更されたため、もう一度ログインしてください' - } - Swal.fire({ - type: 'info', - title: spDc, - }) - } - //Spotify(e) if (localStorage.getItem('ver') != ver && localStorage.getItem('winstore')) { showVer = true console.log('%c Thank you for your update🎉', 'color: red;font-size:200%;') @@ -44,10 +30,7 @@ function verck(ver, jp) { localStorage.setItem('ver', ver) if (!showVer) { console.log(showVer) - if ( - date.getFullYear() * 100 + date.getMonth() + 1 >= localStorage.getItem('showSupportMe') || - !localStorage.getItem('showSupportMe') - ) { + if (!localStorage.getItem('showSupportMe')) { if (date.getMonth() == 11) { var yrs = date.getFullYear() + 1 var nextmonth = yrs * 100 + 1 @@ -55,21 +38,35 @@ function verck(ver, jp) { var yrs = date.getFullYear() var nextmonth = yrs * 100 + date.getMonth() + 2 } - if (lang.language != 'ja') { - $('#support-btm-ja').addClass('hide') - $('#support-btm-en').removeClass('hide') - } localStorage.setItem('showSupportMe', nextmonth) - $('#support-btm').removeClass('hide') - $('#support-btm').animate( - { - bottom: '0' - }, - { - duration: 300 + } else { + if ( + date.getFullYear() * 100 + date.getMonth() + 1 >= localStorage.getItem('showSupportMe') + ) { + if (date.getMonth() == 11) { + var yrs = date.getFullYear() + 1 + var nextmonth = yrs * 100 + 1 + } else { + var yrs = date.getFullYear() + var nextmonth = yrs * 100 + date.getMonth() + 2 } - ) + localStorage.setItem('showSupportMe', nextmonth) + if (lang.language != 'ja') { + $('#support-btm-ja').addClass('hide') + $('#support-btm-en').removeClass('hide') + } + $('#support-btm').removeClass('hide') + $('#support-btm').animate( + { + bottom: '0' + }, + { + duration: 300 + } + ) + } } + } var platform = localStorage.getItem('platform') console.log('Your platform:' + platform) @@ -114,11 +111,6 @@ function verck(ver, jp) { .then(function(mess) { console.table(mess) if (mess) { - //askjp_jp_ua: 2019年10月24日、mstdn.jpによるユーザーエージェントアクセス制限 - if (jp && mess.jp_ua && !localStorage.getItem('askjp_jp_ua')) { - localStorage.setItem('askjp_jp_ua', true) - $('#askjp_jp_ua').removeClass('hide') - } var platform = localStorage.getItem('platform') if (platform == 'darwin') { var newest = mess.desk_mac diff --git a/app/js/post/emoji.js b/app/js/post/emoji.js index 5fe9cdc3..5b73f5b7 100644 --- a/app/js/post/emoji.js +++ b/app/js/post/emoji.js @@ -19,7 +19,7 @@ function emojiToggle(reaction) { if (width) { width = width.replace('px', '') * 1 + 300 } else { - width = 600 + width = reaction ? 300 : 600 } $('#post-box').css('width', width + 'px') $('#suggest').html('') diff --git a/app/js/tl/directory.js b/app/js/tl/directory.js index 5c7c318a..73679e1d 100644 --- a/app/js/tl/directory.js +++ b/app/js/tl/directory.js @@ -38,9 +38,10 @@ function directory(isMore) { } if (isMore) { var addOffset = $("#dir-contents .cvo").length + $("#dir-contents").append(`
`) } else { var addOffset = 0 - $("#dir-contents").html("") + $("#dir-contents").html(`
`) } var start = "https://" + domain + "/api/v1/directory?order=" + order + "&local=" + local_only + "&offset=" + addOffset console.log(start) @@ -51,19 +52,20 @@ function directory(isMore) { Authorization: "Bearer " + at } }) - .then(function(response) { + .then(function (response) { + $("#dir-contents .progress").remove() if (!response.ok) { - response.text().then(function(text) { + response.text().then(function (text) { setLog(response.url, response.status, text) }) } return response.json() }) - .catch(function(error) { + .catch(function (error) { setLog(start, "JSON", error) console.error(error) }) - .then(function(json) { + .then(function (json) { if (json) { $("#moreDir").removeClass("disabled") var html = userparse(json, null, acct_id, "dir", null) diff --git a/app/js/tl/notification.js b/app/js/tl/notification.js index 0d92ee92..53733270 100644 --- a/app/js/tl/notification.js +++ b/app/js/tl/notification.js @@ -44,6 +44,7 @@ function notfColumn(acct_id, tlid, sys) { if (httpreq.readyState === 4) { var json = httpreq.response if (this.status !== 200) { + $('#landing_' + tlid).append(`
${this.status}
${escapeHTML(this.response)}`) setLog(start, this.status, this.response) } var max_id = httpreq.getResponseHeader('link') @@ -88,7 +89,7 @@ function notfColumn(acct_id, tlid, sys) { }) templete = templete + '
' $('#timeline_' + tlid).html(templete) - $('#landing_' + tlid).hide() + // $('#landing_' + tlid).hide() jQuery('time.timeago').timeago() } $('#notf-box').addClass('fetched') @@ -156,6 +157,8 @@ function notfCommon(acct_id, tlid, sys, stream) { console.log('header to get param:' + response.headers.get('link')) if (!response.ok) { response.text().then(function(text) { + console.log('notf error', 'div[data-notf=' + acct_id + '] .landing') + $('div[data-notf=' + acct_id + '] .landing').append(`
${response.status}
${escapeHTML(text)}`) setLog(response.url, response.status, text) }) } @@ -202,7 +205,7 @@ function notfCommon(acct_id, tlid, sys, stream) { } }) $('div[data-notf=' + acct_id + ']').html(templete) - $('#landing_' + tlid).hide() + // $('#landing_' + tlid).hide() jQuery('time.timeago').timeago() } $('#notf-box').addClass('fetched') @@ -232,6 +235,7 @@ function notfWS(misskey, acct_id, tlid, domain, at) { $('i[data-notf=' + acct_id + ']').removeClass('red-text') } websocketNotf[acct_id].onmessage = function(mess) { + $('#landing_' + tlid).hide() //console.log(["Receive Streaming API(Notf):" + acct_id + "(" + domain + ")", JSON.parse(JSON.parse(mess.data).payload)]); var popup = localStorage.getItem('popup') if (!popup) { @@ -356,7 +360,7 @@ function notfmore(tlid) { moreloading = false templete = templete + '
' $('#timeline_' + tlid).append(templete) - $('#landing_' + tlid).hide() + // $('#landing_' + tlid).hide() jQuery('time.timeago').timeago() } $('#notf-box').addClass('fetched') diff --git a/app/js/tl/parse.js b/app/js/tl/parse.js index 4f3f4103..263f401e 100644 --- a/app/js/tl/parse.js +++ b/app/js/tl/parse.js @@ -631,7 +631,7 @@ function parse(obj, mix, acct_id, tlid, popup, mutefilter, type, onlyContent) { var mty = media.remote_url.match(/.+(\..+)$/)[1] viewer = viewer + - `
[${lang.lang_parse_unknown}(${mty})] ` + `[${lang.lang_parse_unknown}(${mty})]${media.url ? `open_in_new` : ''} ` } else if (media.type == 'audio') { viewer = viewer + @@ -1317,7 +1317,7 @@ function userparse(obj, auth, acct_id, tlid, popup) { class="sml gray" style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;user-select:auto; cursor:text;" > - @ ${toot.acct}${locked} + @${toot.acct}${locked}
@@ -1552,6 +1552,7 @@ function mastodonBaseStreaming(acct_id) { $('.notice_icon_acct_' + acct_id).removeClass('red-text') } mastodonBaseWs[domain].onmessage = function (mess) { + $(`div[data-acct=${acct_id}] .landing`).hide() const typeA = JSON.parse(mess.data).event if (typeA == 'delete') { $(`[unique-id=${JSON.parse(mess.data).payload}]`).hide() diff --git a/app/js/tl/src.js b/app/js/tl/src.js index 3d50a809..94235651 100644 --- a/app/js/tl/src.js +++ b/app/js/tl/src.js @@ -13,7 +13,21 @@ function searchMenu() { //検索取得 function src(mode, offset) { if (!offset) { - $('#src-contents').html('') + $('#src-contents').html(` +
+
+
+
+
+
+
+
+
+
+
+
+
+ `) var add = '' } else { var add = '&type=accounts&offset=' + $('#src-accts .cvo').length @@ -48,24 +62,27 @@ function src(mode, offset) { Authorization: 'Bearer ' + at } }) - .then(function(response) { + .then(function (response) { + if (!offset) { + $('#src-contents').html(``) + } if (!response.ok) { - response.text().then(function(text) { + response.text().then(function (text) { setLog(response.url, response.status, text) }) } return response.json() }) - .catch(function(error) { + .catch(function (error) { src('v1') return false }) - .then(function(json) { + .then(function (json) { console.log(['Search', json]) //ハッシュタグ if (json.hashtags[0]) { var tags = '' - Object.keys(json.hashtags).forEach(function(key4) { + Object.keys(json.hashtags).forEach(function (key4) { var tag = json.hashtags[key4] if (mode) { tags = @@ -116,7 +133,7 @@ function tsAdd(q) { parseColumn('add') } function tootsearch(tlid, q) { - if(!q || q=='undefined') { + if (!q || q == 'undefined') { return false } var start = 'https://tootsearch.chotto.moe/api/v1/search?from=0&sort=created_at%3Adesc&q=' + q @@ -129,20 +146,20 @@ function tootsearch(tlid, q) { 'content-type': 'application/json' } }) - .then(function(response) { + .then(function (response) { if (!response.ok) { - response.text().then(function(text) { + response.text().then(function (text) { setLog(response.url, response.status, text) }) } return response.json() }) - .catch(function(error) { + .catch(function (error) { todo(error) setLog(start, 'JSON', error) console.error(error) }) - .then(function(raw) { + .then(function (raw) { var templete = '' var json = raw.hits.hits var max_id = raw['hits'].length @@ -180,20 +197,20 @@ function moreTs(tlid, q) { 'content-type': 'application/json' } }) - .then(function(response) { + .then(function (response) { if (!response.ok) { - response.text().then(function(text) { + response.text().then(function (text) { setLog(response.url, response.status, text) }) } return response.json() }) - .catch(function(error) { + .catch(function (error) { todo(error) setLog(start, 'JSON', error) console.error(error) }) - .then(function(raw) { + .then(function (raw) { var templete = '' var json = raw.hits.hits var max_id = raw['hits'].length @@ -256,8 +273,8 @@ function graphDrawCore(his, tag, acct_id) {
+ tag.name + )}','${acct_id}','add')" class="pointer" title="${escapeHTML(tag.name)}"> #${escapeHTML(tag.name)}
@@ -290,21 +307,21 @@ function trend() { Authorization: 'Bearer ' + at } }) - .then(function(response) { + .then(function (response) { if (!response.ok) { - response.text().then(function(text) { + response.text().then(function (text) { setLog(response.url, response.status, text) }) } return response.json() }) - .catch(function(error) { + .catch(function (error) { setLog(start, 'JSON', error) console.error(error) }) - .then(function(json) { + .then(function (json) { var tags = '' - Object.keys(json).forEach(function(keye) { + Object.keys(json).forEach(function (keye) { var tag = json[keye] var his = tag.history tags = graphDrawCore(his, tag, acct_id) @@ -327,18 +344,18 @@ function doSrc(type) { $('#pageSrc').addClass('hide') $('#pageSrc').removeClass('keep') var q = $('.srcQ').text() - if(type == 'web') { + if (type == 'web') { var start = localStorage.getItem('srcUrl') - if(!start) { + if (!start) { start = 'https://google.com/search?q={q}' } start = start.replace(/{q}/, q) postMessage(["openUrl", start], "*") - } else if(type == 'ts') { + } else if (type == 'ts') { tsAdd(q) - } else if(type == 'copy') { + } else if (type == 'copy') { execCopy(q) - } else if(type == 'toot') { + } else if (type == 'toot') { brInsert(q) } } \ No newline at end of file diff --git a/app/js/tl/tag.js b/app/js/tl/tag.js index 1d088bb0..235f833f 100644 --- a/app/js/tl/tag.js +++ b/app/js/tl/tag.js @@ -10,6 +10,7 @@ if (location.search) { } //よく使うタグ function tagShow(tag, elm) { + tag = decodeURIComponent(tag) const tagTL = lang.lang_parse_tagTL.replace('{{tag}}', '#' + tag) const tagPin = lang.lang_parse_tagpin.replace('{{tag}}', '#' + tag) const tagToot = lang.lang_parse_tagtoot.replace('{{tag}}', '#' + tag) diff --git a/app/js/tl/tl.js b/app/js/tl/tl.js index ef143277..63cbc24c 100644 --- a/app/js/tl/tl.js +++ b/app/js/tl/tl.js @@ -182,6 +182,7 @@ function tl(type, data, acct_id, tlid, delc, voice, mode) { .then(function (response) { if (!response.ok) { response.text().then(function (text) { + $('#landing_' + tlid).append(`
${response.status}
${escapeHTML(text)}`) setLog(response.url, response.status, text) }) } @@ -193,6 +194,7 @@ function tl(type, data, acct_id, tlid, delc, voice, mode) { console.error(error) }) .then(function (json) { + if(!json) return true console.log(['Result of getting timeline of ' + tlid, json]) $('#landing_' + tlid).hide() var mute = getFilterTypeByAcct(acct_id, type) diff --git a/app/js/ui/img.js b/app/js/ui/img.js index 62259547..e96296a8 100644 --- a/app/js/ui/img.js +++ b/app/js/ui/img.js @@ -21,7 +21,7 @@ function imgv(id, key, acct_id) { if (remote_img == 'yes') { murl = ourl } - $(document).ready(function() { + $(document).ready(function () { if (type == 'image') { $('#imagemodal').modal('open') imageXhr(id, key, murl) @@ -62,7 +62,7 @@ function imgCont(type) { $('#imgsec').text(0) $('#imgmodal').attr('src', '../../img/loading.svg') var type = $('#' + id + '-image-' + key).attr('data-type') - $(document).ready(function() { + $(document).ready(function () { if (type == 'image') { imageXhr(id, key, murl) $('#imagewrap').dragScroll() // ドラッグスクロール設定 @@ -77,16 +77,22 @@ function imgCont(type) { } function imageXhr(id, key, murl) { var startTime = new Date() + $('#imgmodal-progress div').removeClass('determinate') + $('#imgmodal-progress div').addClass('indeterminate') + $('#imgmodal-progress').removeClass('hide') xhr = new XMLHttpRequest() xhr.open('GET', murl, true) xhr.responseType = 'arraybuffer' xhr.addEventListener( 'progress', - function(event) { + function (event) { if (event.lengthComputable) { var total = event.total var now = event.loaded var per = (now / total) * 100 + $('#imgmodal-progress div').removeClass('indeterminate') + $('#imgmodal-progress div').addClass('determinate') + $('#imgmodal-progress div').css('width', `${per}%`) $('#imgprog').text(Math.floor(per)) } }, @@ -94,31 +100,35 @@ function imageXhr(id, key, murl) { ) xhr.addEventListener( 'loadend', - function(event) { + function (event) { var total = event.total $('#imgbyte').text(Math.floor(total / 1024)) var now = event.loaded var per = (now / total) * 100 $('#imgprog').text(Math.floor(per)) + $('#imgmodal-progress').addClass('hide') + $('#imgmodal-progress div').css('width', '0%') + $('#imgmodal-progress div').removeClass('determinate') + $('#imgmodal-progress div').addClass('indeterminate') }, false ) xhr.addEventListener( 'error', - function(event) { + function (event) { $('#imgmodal').attr('src', murl) }, false ) - xhr.onreadystatechange = function() { + xhr.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { r = new FileReader() r.readAsDataURL(this.response) - r.onload = function() { + r.onload = function () { var b64 = r.result var element = new Image() var width - element.onload = function() { + element.onload = function () { var width = element.naturalWidth var height = element.naturalHeight calcNiceAspect(width, height) @@ -146,8 +156,8 @@ function imageXhr(id, key, murl) { xhr.responseType = 'blob' xhr.send() } -function calcNiceAspect( width, height ) { - if(width < 650) { +function calcNiceAspect(width, height) { + if (width < 650) { width = 650 } var windowH = $(window).height() @@ -156,7 +166,7 @@ function calcNiceAspect( width, height ) { $('#imagemodal img').css('width', 'auto') if (height < windowH) { $('#imagemodal').css('height', height + 100 + 'px') - $('#imagemodal img').css('height', height + 'px') + $('#imagemodal img').css('height', height + 'px') if (width > windowW * 0.8) { $('#imagemodal').css('width', '80vw') $('#imagemodal img').css('width', 'auto') @@ -188,11 +198,11 @@ function zoom(z) { $('#imagewrap img').css('height', hgt + 'px') } //スマホ対応ドラッグ移動システム -(function() { - $.fn.dragScroll = function() { +(function () { + $.fn.dragScroll = function () { var target = this $(this) - .mousedown(function(event) { + .mousedown(function (event) { $(this) .data('down', true) .data('x', event.clientX) @@ -207,7 +217,7 @@ function zoom(z) { }) // ウィンドウから外れてもイベント実行 $(document) - .mousemove(function(event) { + .mousemove(function (event) { if ($(target).data('down') == true) { // スクロール target.scrollLeft($(target).data('scrollLeft') + $(target).data('x') - event.clientX) @@ -215,11 +225,11 @@ function zoom(z) { return false // 文字列選択を抑止 } }) - .mouseup(function(event) { + .mouseup(function (event) { $(target).data('down', false) }) $(this) - .on('touchstart', function(event) { + .on('touchstart', function (event) { $(this) .data('down', true) .data('x', getX(event)) @@ -232,7 +242,7 @@ function zoom(z) { overflow: 'hidden', // スクロールバー非表示 cursor: 'move' }) //指が触れたか検知 - $(this).on('touchmove', function(event) { + $(this).on('touchmove', function (event) { if ($(target).data('down') === true) { // スクロール target.scrollLeft($(target).data('scrollLeft') + $(target).data('x') - getX(event)) @@ -241,7 +251,7 @@ function zoom(z) { } else { } }) //指が動いたか検知 - $(this).on('touchend', function(event) { + $(this).on('touchend', function (event) { $(target).data('down', false) }) @@ -258,7 +268,7 @@ function getY(event) { } //マウスホイールで拡大 var element = document.getElementById('imagemodal') -element.onmousewheel = function(e) { +element.onmousewheel = function (e) { var delta = e.wheelDelta if (delta > 0) { zoom(1.1) diff --git a/app/js/ui/layout.js b/app/js/ui/layout.js index ec3ba26d..40850eae 100644 --- a/app/js/ui/layout.js +++ b/app/js/ui/layout.js @@ -281,7 +281,7 @@ function parseColumn(target, dontclose) { excludeNotf = excludeNotf + '
' notfDomain = 'dummy' notfKey = 'dummy' - var excludeHome ='' + var excludeHome = '' } else if (acct.type == 'home') { var excludeNotf = '' var excludeHome = ` @@ -452,8 +452,20 @@ function parseColumn(target, dontclose) {
-
- ${lang.lang_layout_nodata} +
+
+
+
+
+
+
+
+
+
+
+
+
+
` diff --git a/app/js/userdata/showOnTL.js b/app/js/userdata/showOnTL.js index b3a3cd4d..c33e9327 100644 --- a/app/js/userdata/showOnTL.js +++ b/app/js/userdata/showOnTL.js @@ -26,6 +26,16 @@ function udgEx(user, acct_id) { } var at = localStorage.getItem("acct_" + acct_id + "_at") var start = "https://" + domain + "/api/v2/search?resolve=true&q=" + encodeURIComponent(user) + Swal.fire({ + title: 'Loading...', + html: lang.lang_details_fetch, + showConfirmButton: false, + showCloseButton: true, + onBeforeOpen: () => { + Swal.showLoading() + }, + onClose: () => { }, + }).then((result) => { }) fetch(start, { method: "GET", headers: { @@ -35,6 +45,7 @@ function udgEx(user, acct_id) { }) .then(function (response) { if (!response.ok) { + Swal.close() response.text().then(function (text) { setLog(response.url, response.status, text) }) @@ -49,14 +60,15 @@ function udgEx(user, acct_id) { .then(function (json) { if (json.accounts[0]) { var id = json.accounts[0].id - udg(id, acct_id) + udg(id, acct_id, true) } else { + Swal.close() postMessage(["openUrl", user], "*") } }) return true } -function udg(user, acct_id) { +function udg(user, acct_id, isSwal) { reset() if (!user) { user = localStorage.getItem("user-id_" + acct_id) @@ -77,6 +89,7 @@ function udg(user, acct_id) { } }) .then(function (response) { + if(isSwal) Swal.close() if (!response.ok) { response.text().then(function (text) { setLog(response.url, response.status, text) @@ -151,7 +164,7 @@ function udg(user, acct_id) { const title = $('.column-first').html() $("#my-data-nav .anc-link").removeClass("active-back") $('.column-first').addClass("active-back") - $('#his-data-title').html(title) + $('#his-data-title').html(title) $("#his-data").css("background-image", "url(" + json.header + ")") $("#his-sta").text(json.statuses_count) $("#his-follow").text(json.following_count) @@ -564,7 +577,7 @@ $("#my-data-nav .anc-link").on("click", function () { let title = $(this).html() if (target === '#his-tl') $("#util-add").removeClass("hide") if (target != '#his-tl') $("#util-add").addClass("hide") - $('#his-data-title').html(title) + $('#his-data-title').html(title) $("#my-data-nav .anc-link").removeClass("active-back") $(this).addClass("active-back") $(target).show() diff --git a/app/view/make/index.sample.html b/app/view/make/index.sample.html index 0f270693..beb3cf9e 100644 --- a/app/view/make/index.sample.html +++ b/app/view/make/index.sample.html @@ -458,7 +458,7 @@
-
+
@@useOtherAcct1@@(/@@useOtherAcct2@@)
@@ -740,11 +740,13 @@
- +
+
+

diff --git a/app/view/make/setting.sample.html b/app/view/make/setting.sample.html index 64ea3ad9..0eeb07f5 100644 --- a/app/view/make/setting.sample.html +++ b/app/view/make/setting.sample.html @@ -684,9 +684,9 @@ class="material-icons left">list@@help@@/Docs GitHub - Main author: Cutls@cutls.com + style="padding-top:5px;">Main author: Cutls@1m.cutls.com
TheDesk @ @@gitHash@@ -