Back up Chrome extension gjapjdfoanfgoeliolnigeieiibnefkp
@@ -0,0 +1,12 @@
|
|||||||
|
# Google Meet Transcripts & AI Summary
|
||||||
|
|
||||||
|
Backup of the unpacked Chrome extension source installed on this machine.
|
||||||
|
|
||||||
|
- Extension ID: `gjapjdfoanfgoeliolnigeieiibnefkp`
|
||||||
|
- Version: `4.3.12`
|
||||||
|
- Description: Google Meet Transcription, AI Summary and Insight. Get the most out of Google Meet!
|
||||||
|
- Original source path: `D:\projects\google_meet_captions\Google Meet Transcripts & AI Summary`
|
||||||
|
|
||||||
|
The `releases/` directory contains a ZIP backup of the extension source.
|
||||||
|
|
||||||
|
MCP integration is planned.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
//!function(e,t,c,r,n,s){e.GoogleAnalyticsObject=r,e[r]=e[r]||function(){(e[r].q=e[r].q||[]).push(arguments)},e[r].l=1*new Date,n=t.createElement(c),s=t.getElementsByTagName(c)[0],n.async=1,n.src=chrome.runtime.getURL("analytics/analyticsSource.js"),n.id="laxis-track",s.parentNode.insertBefore(n,s)}(window,document,"script","ga");let firstScript=document.getElementsByTagName("script")[1],s=document.createElement("script");s.src=chrome.runtime.getURL("analytics/load.js"),firstScript.parentNode.insertBefore(s,firstScript);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
let currentRight="1px",currentTop="100px",startTime=new Date,sessionList=[],bookmarkList=[{color:"crimson",enable:!1,name:"Important",code:"#E94B4B",attributes:{width:"15",height:"18",viewBox:"0 0 15 18",fill:"none"},content:[{type:"path",attributes:{d:"M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416",fill:"#E94B4B"}},{type:"path",attributes:{d:"M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416",stroke:"#E94B4B","stroke-linecap":"round","stroke-linejoin":"round"}}]},{color:"gold",enable:!1,name:"Follow up",code:"#FFD339",attributes:{width:"15",height:"18",viewBox:"0 0 15 18",fill:"none"},content:[{type:"path",attributes:{d:"M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416",fill:"#FFD339"}},{type:"path",attributes:{d:"M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416",stroke:"#FFD339","stroke-linecap":"round","stroke-linejoin":"round"}}]},{color:"yellowGreen",enable:!1,name:"Action",code:"#9CCC65",attributes:{width:"15",height:"18",viewBox:"0 0 15 18",fill:"none"},content:[{type:"path",attributes:{d:"M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416",fill:"#9CCC65"}},{type:"path",attributes:{d:"M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416",stroke:"#9CCC65","stroke-linecap":"round","stroke-linejoin":"round"}}]}];const dateStr=(startTime.getMonth()>8?startTime.getMonth()+1:"0"+(startTime.getMonth()+1))+"-"+(startTime.getDate()>9?startTime.getDate():"0"+startTime.getDate())+"-"+startTime.getFullYear();let autoSaveInterval,meetingStatus=0;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
const CACHE=[],KEY_TRANSCRIPT_IDS="hangouts",CURRENT_INTERVAL="current_interval",ERROR_SAVING="error_saving",APPLICATION_SPEECH_IDS="speeches",SEARCH_TEXT_NO_MEETING_NAME="Meeting details";let SPEAKER_NAME_MAP,TRANSCRIPT_FORMAT_SPEAKER,TRANSCRIPT_FORMAT_SPEAKER_JOIN,TRANSCRIPT_FORMAT_SESSION_JOIN,TRANSCRIPT_FORMAT_MEETING,DEBUG;const XPATH_SELECTOR_PARTICIPANTS="//div[@aria-label='Show everyone']//*[@d='M15 8c0-1.42-.5-2.73-1.33-3.76.42-.14.86-.24 1.33-.24 2.21 0 4 1.79 4 4s-1.79 4-4 4c-.43 0-.84-.09-1.23-.21-.03-.01-.06-.02-.1-.03A5.98 5.98 0 0 0 15 8zm1.66 5.13C18.03 14.06 19 15.32 19 17v3h4v-3c0-2.18-3.58-3.47-6.34-3.87zM9 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m0 9c-2.7 0-5.8 1.29-6 2.01V18h12v-1c-.2-.71-3.3-2-6-2M9 4c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4zm0 9c2.67 0 8 1.34 8 4v3H1v-3c0-2.66 5.33-4 8-4z']",XPATH_SELECTOR_PARTICIPANTS_V20210602="//button[@aria-label='Show everyone'] | //button[@aria-label='Mostrar a todos'] | //button[@aria-label='显示所有人'] |//button[@aria-label='顯示所有參與者'] |//button[@aria-label='顯示所有人'] | //button[@aria-label='Alle anzeigen'] | //button[@aria-label='Afficher tout le monde'] | //button[@aria-label='全員を表示'] | //button[@aria-label='Mostra tutti'] | //button[@aria-label='Mostrar todas as pessoas'] | //button[@aria-label='Mostrar todos']",XPATH_MEETING_DETAILS='//div[contains(@jscontroller,"rYZP8b")] | //div[@aria-label="Meeting details"]',XPATH_MEETING_DETAILS_V20210602="//button[@aria-label='Meeting details']",XPATH_SELECTOR_CHAT="//div[@aria-label='Chat with everyone']//*[@d='M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H4V4h16v12z']",XPATH_SELECTOR_CHAT_V20210602="//button[@aria-label='Chat with everyone'] | //button[@aria-label='Chatear con todos'] | //button[@aria-label='与所有人聊天'] | //button[@aria-label='與所有參與者進行即時通訊'] | //button[@aria-label='同所有人即時通訊'] | //button[@aria-label='Mit allen chatten'] | //button[@aria-label='Clavarder avec tout le monde'] | //button[@aria-label='全員とチャット'] | //button[@aria-label='Chatta con tutti'] | //button[@aria-label='Conversar com todos'] | //button[@aria-label='Discuter avec tous les participants'] | //button[@aria-label='Chat com todos']",turnOnText=["Turn on captions","Untertitel aktivieren","Activer les sous-titres","Activar subtítulos","Attiva sottotitoli","字幕をオンにする","开启字幕","開啟字幕"],turnOffText=["Turn off captions","Untertitel deaktivieren","Désactiver les sous-titres","Desactivar subtítulos","Disattiva sottotitoli","字幕をオフにする","关闭字幕","關閉字幕"],XPATH_TURN_ON_CAPTIONS_BUTTON=turnOnText.map((t=>`//div[text()='${t}']/ancestor::div[@role='button']`)).join(" | "),XPATH_TURN_ON_CAPTIONS_BUTTON_V20210602=turnOnText.map((t=>`//button[contains(@aria-label, '${t}')]`)).join(" | "),XPATH_TURN_OFF_CAPTIONS_BUTTON=turnOffText.map((t=>`//div[text()='${t}']/ancestor::div[@role='button']`)).join(" | "),XPATH_TURN_OFF_CAPTIONS_BUTTON_V20210602=turnOffText.map((t=>`//button[contains(@aria-label, '${t}')]`)).join(" | "),XPATH_CAPTION_OPEN_TOAST="//div[contains(@id, 'J9Hpafc')]",XPATH_CAPTION_OPEN_TOAST_V20210602="//div[contains(@id, 'J9Hpafc')]",XPATH_TITLE="//div[contains(@jscontroller,'WEGDee')]",XPATH_TITLE_V20220324="//div[contains(@jscontroller,'yEvoid')]",XPATH_TITLE_TOOLTIP="//div[contains(@id,'tooltip-c15')]";let captionsContainer=null,closedCaptionsAttachInterval=null,isTranscribing=!1,weTurnedCaptionsOn=!1,currentTranscriptId=null,currentSessionIndex=null,firstStart=!0,loadLocalStorage=0,startTimeStored=null,loginStatus=0,appUser="You";const SHORTCUT_KEY="DEBUG";
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
const domainUrl="https://app.laxis.tech",extensionId=chrome.runtime.id,loginUrl=domainUrl+"/login?source=chrome-extension&extensionId="+extensionId,upgradeUrl=domainUrl+"/settings/plan",signupUrl=domainUrl+"/signup?source=chrome-extension&extensionId="+extensionId,googleMeetUrl="https://meet.google.com/*";
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
const addTutorialPanel = () => {
|
||||||
|
var e, t;
|
||||||
|
e = chrome.runtime.getURL("feature/utilities/packages/html2pdf.bundle.min.js"), (t = document.createElement("script")).type = "application/javascript", t.src = e, document.head.appendChild(t);
|
||||||
|
const n = document.getElementById("laxis-root");
|
||||||
|
let l = document.getElementById("laxis-mainPanel");
|
||||||
|
if (l) l.style.display = "block";
|
||||||
|
else {
|
||||||
|
l = document.createElement("div"), l.setAttribute("id", "laxis-mainPanel"), l.classList.add("panelBase"), l.style.width = "300px", l.style.backgroundColor = "#454953";
|
||||||
|
const e = document.createElement("div");
|
||||||
|
e.setAttribute("name", "laxis-rootHeader"), e.style.cursor = "move", e.style.width = "300px", e.style.height = "50px", e.style.backgroundColor = "#454953", e.style.borderRadius = "12px 12px 0 0", e.style.display = "flex", e.style.alignItems = "center", e.style.justifyContent = "space-between";
|
||||||
|
const t = document.createElement("div");
|
||||||
|
t.style.display = "flex", t.style.alignItems = "center", t.style.paddingLeft = "8px";
|
||||||
|
const i = document.createElement("img");
|
||||||
|
i.src = chrome.runtime.getURL("image/logo.png"), i.addEventListener("click", (function() {
|
||||||
|
window.open(`${domainUrl}/login`)
|
||||||
|
})), i.alt = "none", i.style.height = "30px", i.style.width = "90px", i.style.marginLeft = "-16px", i.style.cursor = "pointer", i.style.zIndex = "999", t.appendChild(i), e.appendChild(t);
|
||||||
|
const o = document.createElement("div");
|
||||||
|
o.style.display = "flex", o.style.alignItems = "center";
|
||||||
|
const d = document.createElement("div");
|
||||||
|
d.classList.add("imageContainer"), d.title = "Minimize", d.addEventListener("click", minimize);
|
||||||
|
const a = createCollapseIcon();
|
||||||
|
d.appendChild(a), o.appendChild(d), e.appendChild(o), l.appendChild(e);
|
||||||
|
let s = document.createElement("div");
|
||||||
|
s.style.padding = "24px", s.style.fontSize = "14px", s.style.color = "#ffffff", s.style.backgroundColor = "#292c35", s.style.borderRadius = "0 0 12px 12px";
|
||||||
|
let c = document.createElement("div");
|
||||||
|
c.innerHTML = "Highlight with colors", s.appendChild(c);
|
||||||
|
let r = document.createElement("div");
|
||||||
|
r.style.display = "flex", r.style.alignItems = "center", r.style.justifyContent = "center", bookmarkList.forEach((e => {
|
||||||
|
let t = document.createElement("div");
|
||||||
|
t.classList.add("tutorialContainer"), t.style.border = "1px solid #9e9e9e", t.style.backgroundColor = "#454953", t.style.display = "flex", t.style.alignItems = "center", t.style.justifyContent = "center";
|
||||||
|
let n = createSVGIcon(e.attributes, e.content);
|
||||||
|
t.appendChild(n), r.appendChild(t)
|
||||||
|
})), s.appendChild(r);
|
||||||
|
let p = document.createElement("div");
|
||||||
|
p.style.textAlign = "center", p.innerHTML = "Use the three main color to hightlight any paragraph during the meeting.", s.appendChild(p);
|
||||||
|
let m = document.createElement("div");
|
||||||
|
m.innerHTML = "Select language", m.style.paddingTop = "32px", s.appendChild(m);
|
||||||
|
let u = document.createElement("div");
|
||||||
|
u.style.display = "flex", u.style.alignItems = "center", u.style.justifyContent = "center";
|
||||||
|
const y = document.createElement("div");
|
||||||
|
y.classList.add("tutorialContainer"), y.style.display = "flex", y.style.alignItems = "center", y.style.justifyContent = "center";
|
||||||
|
const g = createCaptionOnIcon();
|
||||||
|
y.appendChild(g), u.appendChild(y), s.appendChild(u);
|
||||||
|
let h = document.createElement("div");
|
||||||
|
h.style.textAlign = "center", h.innerHTML = "Laxis supports 69 languages in Google Meet", s.appendChild(h);
|
||||||
|
let x = document.createElement("div");
|
||||||
|
x.style.paddingTop = "32px", x.innerHTML = "Download", s.appendChild(x);
|
||||||
|
let C = document.createElement("div");
|
||||||
|
C.style.display = "flex", C.style.justifyContent = "center";
|
||||||
|
let v = document.createElement("div");
|
||||||
|
v.classList.add("tutorialContainer"), v.style.display = "flex", v.style.alignItems = "center", v.style.justifyContent = "center";
|
||||||
|
let E = createDownloadIcon();
|
||||||
|
v.appendChild(E), C.appendChild(v), s.appendChild(C);
|
||||||
|
let b = document.createElement("div");
|
||||||
|
b.style.textAlign = "center", b.innerHTML = "Laxis provides multiple formats for downloading the transcripts.", s.appendChild(b), l.appendChild(s), n.appendChild(l), dragElement(n)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function addRoot() {
|
||||||
|
const e = document.createElement("div");
|
||||||
|
e.setAttribute("id", "laxis-root"), e.style.position = "absolute", e.style.zIndex = "2000", e.style.right = currentRight, e.style.top = currentTop, e.style.height = "10px", e.style.width = "10px", document.body.appendChild(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMiniPanel() {
|
||||||
|
const e = document.getElementById("laxis-root"),
|
||||||
|
t = document.createElement("div");
|
||||||
|
t.setAttribute("id", "laxis-miniPanel"), t.classList.add("panelBase"), t.style.width = "60px", t.style.paddingBottom = "16px", t.style.backgroundColor = "#292c35";
|
||||||
|
const n = document.createElement("div");
|
||||||
|
n.setAttribute("name", "laxis-rootHeader"), n.style.cursor = "move", n.classList.add("col-12"), n.style.height = "50px", n.style.width = "50px", n.style.marginBottom = "-10px", n.style.cursor = "move", n.style.zIndex = "999";
|
||||||
|
const l = document.createElement("img");
|
||||||
|
l.src = chrome.runtime.getURL("image/logo.png"), l.addEventListener("click", (function() {
|
||||||
|
window.open(`${domainUrl}/login`)
|
||||||
|
})), l.style.cursor = "pointer", l.style.marginTop = "10px", l.style.height = "25px", l.style.width = "75px", l.style.marginLeft = "-16px", l.alt = "none", n.appendChild(l), t.appendChild(n);
|
||||||
|
const i = document.createElement("div");
|
||||||
|
i.title = "Expand", i.id = "laxis-expandPanel", i.classList.add("miniButtonContainer"), i.addEventListener("click", addTutorialPanel);
|
||||||
|
const o = createExpandIcon();
|
||||||
|
o.id = "expandInputIcon", i.appendChild(o), t.appendChild(i), e.appendChild(t), dragElement(e)
|
||||||
|
}
|
||||||
|
const addCaptionPanel = () => {
|
||||||
|
const e = findButtonContainer(),
|
||||||
|
t = document.getElementById("laxis-root");
|
||||||
|
if (e && !e.__gmt_button_added) {
|
||||||
|
e.__gmt_button_added = !0;
|
||||||
|
const n = document.getElementById("laxis-miniPanel"),
|
||||||
|
l = document.createElement("div");
|
||||||
|
l.title = "Captions settings", l.setAttribute("id", "laxis-caption-toggle-mini"), l.classList.add("miniButtonContainer"), l.addEventListener("click", getToSettings);
|
||||||
|
const i = createCaptionOnIcon();
|
||||||
|
i.id = "captionIconMini", l.appendChild(i), n.appendChild(l);
|
||||||
|
const o = document.createElement("div");
|
||||||
|
o.title = "Download", o.setAttribute("id", "laxis-download-menu-mini"), o.classList.add("miniButtonContainer"), o.addEventListener("click", displayMenu);
|
||||||
|
const d = createDownloadIcon();
|
||||||
|
d.id = "downloadIconMini", d.style.width = "20px", d.style.height = "20px", o.appendChild(d), n.appendChild(o);
|
||||||
|
const a = document.createElement("div");
|
||||||
|
a.style.margin = "12px 5px 0px", a.style.padding = "6px 12px", a.style.borderRadius = "12px", a.style.backgroundColor = "#3e4149";
|
||||||
|
for (let e = 0; e < bookmarkList.length; e++) {
|
||||||
|
const t = document.createElement("div"),
|
||||||
|
n = document.createElement("div");
|
||||||
|
t.style.display = "flex", t.style.flexDirection = "column", t.style.alignItems = "center", n.title = `Highlight as ${bookmarkList[e].name}`, n.classList.add("flagContainerMini"), n.id = `laxis-highlight-${bookmarkList[e].code}-mini`, n.onclick = () => {
|
||||||
|
highlight(e)
|
||||||
|
};
|
||||||
|
const l = createSVGIcon(bookmarkList[e].attributes, bookmarkList[e].content);
|
||||||
|
n.appendChild(l), t.appendChild(n), a.appendChild(t)
|
||||||
|
}
|
||||||
|
n.appendChild(a), n.style.display = "block";
|
||||||
|
let s = document.getElementById("laxis-mainPanel");
|
||||||
|
s && t.removeChild(s);
|
||||||
|
const c = document.createElement("div");
|
||||||
|
c.setAttribute("id", "laxis-mainPanel"), c.classList.add("panelBase"), c.style.width = "300px", c.style.display = "none";
|
||||||
|
const r = document.createElement("div");
|
||||||
|
r.setAttribute("name", "laxis-rootHeader"), r.style.cursor = "move", r.style.width = "300px", r.style.height = "50px", r.style.backgroundColor = "#454953", r.style.borderRadius = "12px 12px 0 0", r.style.display = "flex", r.style.alignItems = "center", r.style.justifyContent = "space-between";
|
||||||
|
const p = document.createElement("div");
|
||||||
|
p.style.display = "flex", p.style.alignItems = "center", p.style.paddingLeft = "8px";
|
||||||
|
const m = document.createElement("img");
|
||||||
|
m.src = chrome.runtime.getURL("image/logo.png"), m.alt = "none", m.addEventListener("click", (function() {
|
||||||
|
window.open(`${domainUrl}/login`)
|
||||||
|
})), m.style.height = "30px", m.style.marginLeft = "-16px", m.style.cursor = "pointer", m.style.zIndex = "999", p.appendChild(m), r.appendChild(p);
|
||||||
|
const u = document.createElement("div");
|
||||||
|
u.style.display = "flex", u.style.alignItems = "center";
|
||||||
|
const y = document.createElement("div");
|
||||||
|
y.title = "Retrieve local data", y.setAttribute("id", "laxis-repair"), y.classList.add("imageContainer"), y.style.display = "none", y.addEventListener("click", extractLocalStorage);
|
||||||
|
const g = document.createElement("img");
|
||||||
|
g.id = "restoreIcon", g.src = chrome.runtime.getURL("image/repair.svg"), g.style.width = "15px", g.style.height = "18px", y.appendChild(g), u.appendChild(y);
|
||||||
|
const h = document.createElement("div");
|
||||||
|
h.title = "Captions settings", h.setAttribute("id", "laxis-caption-toggle"), h.classList.add("imageContainer"), h.addEventListener("click", getToSettings);
|
||||||
|
const x = createCaptionOnIcon();
|
||||||
|
x.id = "captionIcon", h.appendChild(x), u.appendChild(h);
|
||||||
|
const C = document.createElement("div");
|
||||||
|
C.title = "Auto-Scroll", C.setAttribute("id", "laxis-autoScroll");
|
||||||
|
const v = document.createElement("input");
|
||||||
|
v.type = "hidden", v.value = 1, v.setAttribute("id", "autoscroll"), v.onchange = () => autoScroll(), C.appendChild(v), C.classList.add("imageContainer"), C.addEventListener("click", (function() {
|
||||||
|
let e = document.getElementById("autoscroll");
|
||||||
|
"0" === e.value.toString() ? e.value = 1 : e.value = 0, autoScroll()
|
||||||
|
}));
|
||||||
|
const E = createAutoScrollIcon();
|
||||||
|
E.style.width = "15px", E.style.height = "15px", C.appendChild(E), u.appendChild(C);
|
||||||
|
const b = document.createElement("div");
|
||||||
|
b.title = "Download", b.id = "laxis-openDownloadMenu", b.classList.add("imageContainer"), b.addEventListener("click", displayMenu);
|
||||||
|
const f = createDownloadIcon();
|
||||||
|
f.style.width = "15px", f.style.height = "15px", b.appendChild(f), u.appendChild(b);
|
||||||
|
const L = document.createElement("div");
|
||||||
|
L.title = "Minimize", L.id = "laxis-minimizePanel", L.classList.add("imageContainer"), L.addEventListener("click", minimize);
|
||||||
|
const k = createCollapseIcon();
|
||||||
|
k.style.width = "15px", k.style.height = "15px", L.appendChild(k), u.appendChild(L), r.appendChild(u), c.appendChild(r);
|
||||||
|
const I = document.createElement("div");
|
||||||
|
I.style.width = "300px", I.style.backgroundColor = "#292c35", I.style.paddingTop = "8px";
|
||||||
|
const w = document.createElement("div");
|
||||||
|
w.id = "login-prompt", w.style.display = "none", w.style.margin = "0px 8px", w.style.padding = "4px", w.style.textAlign = "center", w.addEventListener("click", signup), w.style.cursor = "pointer", w.innerHTML = "Please <span style='color:#2196f3'>log in</span> to enable autosave to Laxis Cloud.", w.style.borderRadius = "12px", w.style.border = "1px solid rgba(255, 255, 255, 0.5)", w.style.backgroundColor = "#454953", w.style.color = "#ffffff", w.style.fontSize = "10px";
|
||||||
|
const T = document.createElement("div");
|
||||||
|
T.id = "google-meet-quota", T.style.display = "none", T.style.margin = "0px 8px", T.style.padding = "4px", T.style.textAlign = "center", T.addEventListener("click", upgrade), T.style.cursor = "pointer", T.innerHTML = "Used Google Meet Quota: ", T.style.borderRadius = "12px", T.style.border = "1px solid rgba(255, 255, 255, 0.5)", T.style.backgroundColor = "#454953", T.style.color = "#ffffff", T.style.fontSize = "10px";
|
||||||
|
const M = document.createElement("div");
|
||||||
|
M.id = "meeting-name", M.style.fontWeight = "bold", M.style.padding = "8px", M.style.color = "#FFFFFF", I.appendChild(w), I.appendChild(T), I.appendChild(M);
|
||||||
|
const B = document.createElement("div");
|
||||||
|
B.style.paddingTop = "8px", B.style.width = "25%", I.style.paddingBottom = "8px", c.appendChild(I);
|
||||||
|
const S = document.createElement("div");
|
||||||
|
S.setAttribute("id", "feature"), S.style.width = "300px", S.style.backgroundColor = "#292c35", S.style.borderRadius = "0 0 12px 12px";
|
||||||
|
const A = document.createElement("div");
|
||||||
|
A.setAttribute("id", "caption"), A.style.height = "350px", A.style.width = "300px", A.style.overflowY = "auto", A.style.overflowX = "hidden", A.style.color = "#FFFFFF", A.style.paddingRight = "8px", A.onwheel = () => {
|
||||||
|
v.value = 0
|
||||||
|
}, S.appendChild(A);
|
||||||
|
const H = document.createElement("div");
|
||||||
|
H.id = "highlight-laxis", H.style.width = "300px", H.style.backgroundColor = "#292c35", H.style.display = "flex", H.style.justifyContent = "space-around", H.style.borderTop = "1px solid #e0e0e0", H.style.paddingTop = "10px", H.style.paddingBottom = "10px", H.classList.add("popup"), H.style.borderRadius = "0 0 12px 12px";
|
||||||
|
for (let e = 0; e < bookmarkList.length; e++) {
|
||||||
|
const t = document.createElement("div"),
|
||||||
|
n = document.createElement("div");
|
||||||
|
t.style.display = "flex", t.style.flexDirection = "column", t.style.alignItems = "center", n.style.textAlign = "center", n.style.fontSize = "10px", n.style.color = "#9e9e9e", n.style.marginTop = "4px", n.innerHTML = bookmarkList[e].name, n.id = `laxis-highlight-${bookmarkList[e].code}-title`;
|
||||||
|
const l = document.createElement("div");
|
||||||
|
l.title = `Highlight as ${bookmarkList[e].name}`, l.classList.add("flagContainer"), l.id = `laxis-highlight-${bookmarkList[e].code}`;
|
||||||
|
const i = createSVGIcon(bookmarkList[e].attributes, bookmarkList[e].content);
|
||||||
|
l.appendChild(i), l.onclick = () => {
|
||||||
|
highlight(e)
|
||||||
|
}, t.appendChild(l), t.appendChild(n), H.appendChild(t)
|
||||||
|
}
|
||||||
|
let N = document.createElement("div");
|
||||||
|
N.id = "popup", N.className = "popupText", N.innerHTML = "Test", N.onclick = () => {
|
||||||
|
clearTimeout(notificationsTimeout), N.classList.remove("show")
|
||||||
|
}, H.appendChild(N), S.appendChild(H), c.appendChild(S), t.appendChild(c), dragElement(t), autoScroll(), document.getElementById("laxis-downloadMenu") || addDownloadMenu(), checkCaptionStatusInterval = setInterval(checkCaptionStatus, 500), turnOnCaptions(), debug("turned on caption"), removeCaptionPanel(), checkToken(), autoSaveInterval = setInterval((() => {
|
||||||
|
let e = document.getElementById("autoSaveCheck");
|
||||||
|
e && e.checked && Export2App(!0).catch((e => {
|
||||||
|
console.error(e);
|
||||||
|
const t = get(ERROR_SAVING) || [];
|
||||||
|
set(ERROR_SAVING, [...t, e])
|
||||||
|
}))
|
||||||
|
}), 3e5), setTimeout(updateMeetingName, 500), clearInterval(checkOngoingMeeting)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addDownloadMenu = () => {
|
||||||
|
let e = document.createElement("div");
|
||||||
|
e.id = "laxis-downloadMenu", e.className = "modal", e.style.display = "none";
|
||||||
|
let t = document.createElement("div");
|
||||||
|
t.className = "modal-content", t.id = "laxis-downloadMenuContent";
|
||||||
|
let n = document.createElement("div");
|
||||||
|
n.className = "modal-header", n.innerHTML = "Download", t.appendChild(n);
|
||||||
|
let l = document.createElement("div"),
|
||||||
|
i = document.createElement("div");
|
||||||
|
i.className = "modal-body", i.innerHTML = "File Type<select name='extension' id='extension' value='txt'><option value='txt'>txt</option><option value='app'>Laxis Cloud</option><option value='doc'>doc</option><option value='pdf'>pdf</option></select>", l.appendChild(i);
|
||||||
|
let o = document.createElement("div");
|
||||||
|
o.className = "modal-body", o.innerHTML = "<div>Highlights</div><div><input type='checkbox' name='highlightCheck' id='highlightCheck' checked='true'/></div>", l.appendChild(o);
|
||||||
|
let d = document.createElement("div");
|
||||||
|
d.className = "modal-body", d.innerHTML = "<div>Timestamps</div><div><input type='checkbox' name='timestampCheck' id='timestampCheck'/></div>", l.appendChild(d);
|
||||||
|
let a = document.createElement("div");
|
||||||
|
a.className = "modal-body", a.title = "Autosave to Laxis every 5 minutes", a.style.cursor = "help", a.innerHTML = "<div>Autosave to Laxis Cloud</div><div><input type='checkbox' name='autoSaveCheck' id='autoSaveCheck'/></div>", l.appendChild(a), t.appendChild(l);
|
||||||
|
let s = document.createElement("div");
|
||||||
|
s.className = "modal-footer";
|
||||||
|
let c = document.createElement("button");
|
||||||
|
c.classList.add("modal-button"), c.id = "laxis-close-menu", c.style.border = "solid 2px #292c35", c.style.backgroundColor = "#454953", c.innerHTML = "Cancel", c.onclick = () => {
|
||||||
|
document.getElementById("laxis-downloadMenu").style.display = "none"
|
||||||
|
}, s.appendChild(c);
|
||||||
|
let r = document.createElement("button");
|
||||||
|
r.classList.add("modal-button"), r.style.backgroundColor = "#292c35", r.style.boxShadow = "box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.29)", r.innerHTML = "Download", r.addEventListener("click", downloadTranscript), r.setAttribute("id", "laxis-confirm-download"), s.appendChild(r), t.appendChild(s), e.appendChild(t);
|
||||||
|
const p = document.getElementById("laxis-root");
|
||||||
|
p && p.appendChild(e)
|
||||||
|
},
|
||||||
|
minimize = () => {
|
||||||
|
const e = document.getElementById("laxis-mainPanel"),
|
||||||
|
t = document.getElementById("laxis-miniPanel");
|
||||||
|
e.style.display = "none", t.style.display = "block"
|
||||||
|
},
|
||||||
|
autoScroll = () => {
|
||||||
|
let e = document.getElementById("laxis-autoScroll");
|
||||||
|
e.style.border = "1px solid #2196f3";
|
||||||
|
const t = document.getElementById("caption"),
|
||||||
|
n = document.getElementById("autoscroll"),
|
||||||
|
l = setInterval((function() {
|
||||||
|
"0" === n.value.toString() ? (clearInterval(l), e.style.border = "1px solid #292c35") : t.scrollTop = t.scrollHeight
|
||||||
|
}), 1e3)
|
||||||
|
},
|
||||||
|
updateMeetingName = () => {
|
||||||
|
const e = document.getElementById("meeting-name");
|
||||||
|
getMeetingName() ? (e.innerHTML = getMeetingName(), chrome.runtime.sendMessage({
|
||||||
|
type: "meetingName",
|
||||||
|
meetingName: getMeetingName()
|
||||||
|
})) : (e.innerHTML = getDefaultName(), chrome.runtime.sendMessage({
|
||||||
|
type: "meetingName",
|
||||||
|
meetingName: getDefaultName()
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
highlight = e => {
|
||||||
|
let t = document.getElementById("highlight-laxis"),
|
||||||
|
n = document.getElementById("popup"),
|
||||||
|
l = document.getElementById("laxis-miniPanel");
|
||||||
|
weTurnedCaptionsOn ? bookmarkList.forEach(((l, i) => {
|
||||||
|
const o = t.childNodes[i].childNodes[0],
|
||||||
|
d = t.childNodes[i].childNodes[1],
|
||||||
|
a = document.getElementById(`laxis-highlight-${bookmarkList[i].code}-mini`);
|
||||||
|
i === e ? l.enable ? (l.enable = !1, o.style.backgroundColor = "", a.style.backgroundColor = "", d.style.color = "#9e9e9e", clearTimeout(notificationsTimeout), n.classList.remove("show")) : (l.enable = !0, o.style.backgroundColor = "#696969", a.style.backgroundColor = "#696969", d.style.color = "#ffffff", n.innerHTML = "Your conversation is being highlighted.", n.style.backgroundColor = "#454953", n.style.color = l.code, n.classList.add("show"), clearTimeout(notificationsTimeout), notificationsTimeout = setTimeout((() => {
|
||||||
|
n.classList.remove("show")
|
||||||
|
}), notificationsTimeoutDuration)) : (l.enable = !1, o.style.backgroundColor = "", a.style.backgroundColor = "", d.style.color = "#9e9e9e")
|
||||||
|
})) : (l.style.display && alert("Your caption is turned off"), n.style.backgroundColor = "#818388", n.style.color = "#292c35", n.innerHTML = "Your caption is turned off", n.classList.add("show"), clearTimeout(notificationsTimeout), notificationsTimeout = setTimeout((() => {
|
||||||
|
n.classList.remove("show")
|
||||||
|
}), notificationsTimeoutDuration))
|
||||||
|
};
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
const stopTranscribing = () => {
|
||||||
|
debug("call stopTranscribing"), notificationsOff(), clearInterval(closedCaptionsAttachInterval), closedCaptionsAttachInterval = null, captionContainerChildObserver.disconnect(), captionContainerAttributeObserver.disconnect()
|
||||||
|
},
|
||||||
|
startTranscribing = () => {
|
||||||
|
debug("call startTranscribing"), currentSessionIndex = null, closedCaptionsAttachInterval = setInterval(tryTo(closedCaptionsAttachLoop, "attach to captions"), 1e3), setCurrentTranscriptDetails()
|
||||||
|
},
|
||||||
|
toggleTranscribing = () => {
|
||||||
|
debug("call toggleTranscribing"), isTranscribing ? stopTranscribing() : startTranscribing(), isTranscribing = !isTranscribing
|
||||||
|
},
|
||||||
|
turnOnCaptions = () => {
|
||||||
|
const t = getElementWithXPathFallback(document, XPATH_TURN_ON_CAPTIONS_BUTTON, XPATH_TURN_ON_CAPTIONS_BUTTON_V20210602);
|
||||||
|
return debug("captionsButtonOn", t), t && (t.click(), notificationsOn()), t
|
||||||
|
},
|
||||||
|
turnOffCaptions = () => {
|
||||||
|
const t = getElementWithXPathFallback(document, XPATH_TURN_OFF_CAPTIONS_BUTTON, XPATH_TURN_OFF_CAPTIONS_BUTTON_V20210602);
|
||||||
|
return debug("captionsButtonOff", t), t && (t.click(), notificationsOff()), t
|
||||||
|
},
|
||||||
|
turnOnCaptionNotificationsOn = () => {
|
||||||
|
const t = document.getElementById("popup");
|
||||||
|
t.style.backgroundColor = "#818388", t.style.color = "#292c35", t.innerHTML = "Please turn on captions", t.classList.add("show"), clearTimeout(notificationsTimeout), notificationsTimeout = setTimeout((() => {
|
||||||
|
t.classList.remove("show")
|
||||||
|
}), 500)
|
||||||
|
},
|
||||||
|
notificationsOn = () => {
|
||||||
|
const t = document.getElementById("laxis-caption-toggle"),
|
||||||
|
n = document.getElementById("laxis-caption-toggle-mini"),
|
||||||
|
i = document.getElementById("captionIcon"),
|
||||||
|
o = document.getElementById("captionIconMini");
|
||||||
|
t.removeChild(i), n.removeChild(o);
|
||||||
|
const e = createCaptionOnIcon(),
|
||||||
|
c = createCaptionOnIcon();
|
||||||
|
e.id = "captionIcon", e.style.width = "15px", e.style.height = "15px", t.appendChild(e), c.id = "captionIconMini", c.style.width = "15px", c.style.height = "15px", n.appendChild(c);
|
||||||
|
const s = document.getElementById("popup");
|
||||||
|
s.style.backgroundColor = "#818388", s.style.color = "#292c35", s.innerHTML = "Your caption is turned on", s.classList.add("show"), clearTimeout(notificationsTimeout), notificationsTimeout = setTimeout((() => {
|
||||||
|
s.classList.remove("show")
|
||||||
|
}), notificationsTimeoutDuration)
|
||||||
|
},
|
||||||
|
notificationsOff = () => {
|
||||||
|
const t = document.getElementById("laxis-caption-toggle"),
|
||||||
|
n = document.getElementById("laxis-caption-toggle-mini"),
|
||||||
|
i = document.getElementById("captionIcon"),
|
||||||
|
o = document.getElementById("captionIconMini");
|
||||||
|
t.removeChild(i), n.removeChild(o);
|
||||||
|
const e = createCaptionOffIcon(),
|
||||||
|
c = createCaptionOffIcon();
|
||||||
|
e.id = "captionIcon", e.style.width = "15px", e.style.height = "15px", t.appendChild(e), c.id = "captionIconMini", c.style.width = "15px", c.style.height = "15px", n.appendChild(c);
|
||||||
|
const s = document.getElementById("popup");
|
||||||
|
s.style.backgroundColor = "#818388", s.style.color = "#292c35", s.innerHTML = "Your caption is turned off", s.classList.add("show"), clearTimeout(notificationsTimeout), notificationsTimeout = setTimeout((() => {
|
||||||
|
s.classList.remove("show")
|
||||||
|
}), notificationsTimeoutDuration)
|
||||||
|
},
|
||||||
|
toggleCaptions = () => {
|
||||||
|
debug("call toggleCaptions"), weTurnedCaptionsOn ? turnOffCaptions() : turnOnCaptions(), weTurnedCaptionsOn = !weTurnedCaptionsOn
|
||||||
|
};
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
const findCaptionsContainer = () => {
|
||||||
|
let e = document.querySelector('div[jsname="dsyhDe"]');
|
||||||
|
return e || (e = document.querySelector('div[jscontroller="D1tHje"] > div > div:first-child')), e && (captionContainerChildObserver.observe(e, {
|
||||||
|
childList: !0,
|
||||||
|
subtree: !0,
|
||||||
|
characterData: !0
|
||||||
|
}), captionContainerAttributeObserver.observe(e, {
|
||||||
|
attributes: !0,
|
||||||
|
subtree: !1,
|
||||||
|
attributeOldValue: !0
|
||||||
|
}), Array.from(e.children).forEach(tryTo((e => {
|
||||||
|
updateCurrentTranscriptSession(e)
|
||||||
|
}), "handling child node")), debug("Final CaptionsContainer", e)), e
|
||||||
|
},
|
||||||
|
findCaptionsContainerObsolete = () => {
|
||||||
|
captionContainerChildObserver.disconnect(), captionContainerAttributeObserver.disconnect();
|
||||||
|
const e = {},
|
||||||
|
t = Array.from(document.querySelectorAll("img")).filter((e => e.src.match(/\.googleusercontent\.com\//)));
|
||||||
|
for (let n of t) n.className in e || (e[n.className] = []), e[n.className].push(n);
|
||||||
|
const n = [];
|
||||||
|
for (let t of Object.values(e)) {
|
||||||
|
let e = 0;
|
||||||
|
for (let n of t) {
|
||||||
|
const t = document.evaluate("..//span", n.parentElement, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE);
|
||||||
|
let r;
|
||||||
|
for (; r = t.iterateNext();)
|
||||||
|
if (0 === r.children.length && r.textContent.length > 3) {
|
||||||
|
e += 1;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e !== t.length) continue;
|
||||||
|
let r = null;
|
||||||
|
if (t.length >= 2) {
|
||||||
|
const e = [...t];
|
||||||
|
let n = null,
|
||||||
|
o = !1;
|
||||||
|
do {
|
||||||
|
for (let t in e) {
|
||||||
|
if (!e[t].parent) {
|
||||||
|
o = !0;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
e[t] = e[t].parent, 0 === t ? n = e[t] : n && n !== e[t] && (n = null), debug("current", n)
|
||||||
|
}
|
||||||
|
} while (null === n && !1 === o);
|
||||||
|
r = n
|
||||||
|
} else {
|
||||||
|
let e = t[0];
|
||||||
|
for (; null === r && e;) e.getAttribute("jscontroller") ? r = e : e = e.parentNode
|
||||||
|
}
|
||||||
|
if (r) {
|
||||||
|
const e = r?.firstChild?.firstChild?.tagName;
|
||||||
|
debug("first grand child tag name", e);
|
||||||
|
const t = "IMG" === e ? r : r.firstChild.firstChild;
|
||||||
|
debug("caption container candidate", t), null !== t && n.push(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (1 === n.length) return captionContainerChildObserver.observe(n[0], {
|
||||||
|
childList: !0,
|
||||||
|
subtree: !0,
|
||||||
|
characterData: !0
|
||||||
|
}), captionContainerAttributeObserver.observe(n[0], {
|
||||||
|
attributes: !0,
|
||||||
|
subtree: !1,
|
||||||
|
attributeOldValue: !0
|
||||||
|
}), Array.from(n[0].children).forEach(tryTo((e => {
|
||||||
|
updateCurrentTranscriptSession(e)
|
||||||
|
}), "handling child node")), debug("Final CaptionsContainer", n[0]), n[0]
|
||||||
|
},
|
||||||
|
captionContainerChildObserver = new MutationObserver(tryTo((e => {
|
||||||
|
for (let t of e)
|
||||||
|
if (debug("mutation target", t.target), t.target === captionsContainer) {
|
||||||
|
debug("update with added nodes");
|
||||||
|
for (let e of t.addedNodes) updateCurrentTranscriptSession(e)
|
||||||
|
} else {
|
||||||
|
const e = Array.from(t.addedNodes).filter((e => "SPAN" === e.nodeName || "#text" === e.nodeName)),
|
||||||
|
n = Array.from(t.removedNodes).filter((e => "SPAN" === e.nodeName || "#text" === e.nodeName));
|
||||||
|
if (debug("addedSpansOrTexts", e), "characterData" === t.type || e.length > 0 || n.length > 0) {
|
||||||
|
let e = t.target;
|
||||||
|
for (; e && e.parentNode !== captionsContainer;) e = e.parentNode;
|
||||||
|
if (!e) {
|
||||||
|
debug("could not find root for", t.target);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (debug("update with parent node"), e.querySelector("button")) {
|
||||||
|
let t = Array.from(e.children),
|
||||||
|
n = t.slice(0, t.length - 1).slice(-4);
|
||||||
|
for (let e of n) updateCurrentTranscriptSession(e)
|
||||||
|
} else updateCurrentTranscriptSession(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}), "executing observer")),
|
||||||
|
captionContainerAttributeObserver = new MutationObserver(tryTo((e => {
|
||||||
|
for (let t of e)
|
||||||
|
if ("style" === t.attributeName) {
|
||||||
|
const e = t.target.getAttribute("style");
|
||||||
|
"display: none;" === t.oldValue && "" === e && (currentSessionIndex = null)
|
||||||
|
}
|
||||||
|
}), "executing observer"));
|
||||||
|
let isCaptionTurnedOn = !1;
|
||||||
|
const closedCaptionsAttachLoop = () => {
|
||||||
|
if (captionsContainer = findCaptionsContainer(), captionsContainer) debug("attached to closed captions"), isCaptionTurnedOn = !0, clearInterval(closedCaptionsAttachInterval);
|
||||||
|
else if (!hasCaptionButtons) {
|
||||||
|
if (isCaptionTurnedOn) return;
|
||||||
|
if (getElementWithXPathFallback(document, XPATH_CAPTION_OPEN_TOAST, XPATH_CAPTION_OPEN_TOAST_V20210602)) return popup.classList.remove("show"), isCaptionTurnedOn = !0, notificationsOn(), void clearInterval(closedCaptionsAttachInterval);
|
||||||
|
isCaptionTurnedOn || turnOnCaptionNotificationsOn()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeCaptionPanel = () => {
|
||||||
|
// debug("start remove caption panel");
|
||||||
|
// const e = document.querySelector('div[jscontroller="D1tHje"]');
|
||||||
|
// debug("googleMeetCaptionsPanel", e), e && (e.style = "height: 0px", turnOffCaptions(), setTimeout((() => {
|
||||||
|
// turnOnCaptions()
|
||||||
|
// }), 500))
|
||||||
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
const parents=e=>{const t=[e];for(;e;e=e.parentNode)t.unshift(e);return t},getCommonAncestor=(e,t)=>{const n=parents(e),o=parents(t);if(n[0]===o[0])for(let e=0;e<n.length;e++)if(n[e]!==o[e])return n[e-1]},xpath=(e,t=document)=>document.evaluate(e,t,null,XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue,findButtonContainer=()=>{const e=getElementWithXPathFallback(document,XPATH_MEETING_DETAILS,XPATH_MEETING_DETAILS_V20210602),t=getElementWithXPathFallback(document,XPATH_SELECTOR_CHAT,XPATH_SELECTOR_CHAT_V20210602);return getCommonAncestor(e,t)},getElementWithXPathFallback=(e,t,n)=>xpath(t,e)||xpath(n,e),displayMenu=()=>{document.getElementById("laxis-downloadMenu").style.display="block"},dragElement=e=>{let t=0,n=0,o=0,l=0;function u(e){(e=e||window.event).preventDefault(),o=e.clientX,l=e.clientY,document.onmouseup=c,document.onmousemove=a}function a(u){(u=u||window.event).preventDefault(),t=o-u.clientX,n=l-u.clientY,o=u.clientX,l=u.clientY,e.style.top=e.offsetTop-n+"px",e.style.left=e.offsetLeft-t+"px",currentTop=e.style.top,currentRight=e.style.right}function c(){document.onmouseup=null,document.onmousemove=null}document.getElementsByName(e.id+"Header")?document.getElementsByName(e.id+"Header").forEach((e=>{e.onmousedown=u})):e.onmousedown=u};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
window.__gmt_get=t=>get(`setting.${t}`),window.__gmt_set=(t,e)=>{set(`setting.${t}`,e),syncSettings()},window.__gmt_remove=t=>{remove(`setting.${t}`),syncSettings()};const syncSettings=()=>{TRANSCRIPT_FORMAT_MEETING=getOrSet("setting.transcript-format-meeting","# $year$-$month$-$day$ $name$\n\n$text$"),TRANSCRIPT_FORMAT_SESSION_JOIN=getOrSet("setting.transcript-format-session-join","\n\n...\n\n"),TRANSCRIPT_FORMAT_SPEAKER=getOrSet("setting.transcript-format-speaker","$hour$:$minute$:$second$\n $name$: $text$"),TRANSCRIPT_FORMAT_SPEAKER_JOIN=getOrSet("setting.transcript-format-speaker-join","\n\n"),SPEAKER_NAME_MAP=getOrSet("setting.speaker-name-map",{}),DEBUG=getOrSet("setting.debug",!1)};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
const makeFullKey=e=>`__laxis_${e}`,makeTranscriptKey=(...e)=>{const[t,r,o]=e,n=[`hangout_${t}`];return e.length>=2&&(n.push(`session_${r}`),e.length>=3&&n.push(`speaker_${o}`)),n.join("_")},get=e=>{const t=window.localStorage.getItem(makeFullKey(e));return"string"==typeof t||t instanceof String?(debug(e,t),JSON.parse(t)):t},set=(e,t,r=!1)=>{const o=makeFullKey(e),n=JSON.stringify(t),a=makeFullKey("rotationKeys");let s=JSON.parse(window.localStorage.getItem(a))||[],i=new Set(s);for(;;)try{window.localStorage.setItem(o,n),r&&(i.add(o),window.localStorage.setItem(a,JSON.stringify(Array.from(i))));break}catch(e){if(e instanceof DOMException&&("QuotaExceededError"===e.name||e.code===DOMException.QUOTA_EXCEEDED_ERR)){if(console.log("Local storage quota exceeded! Deleting old keys to make room for new ones. This may take a while..."),debug("Local storage quota exceeded! Deleting old keys to make room for new ones. This may take a while..."),i.size>0){for(let e=0;e<5&&i.size>0;e++){const e=i.values().next().value;i.delete(e),window.localStorage.removeItem(e)}window.localStorage.setItem(a,JSON.stringify(Array.from(i)));continue}console.error("No keys available to delete.");break}console.error("Unexpected error:",e);break}},remove=e=>{debug(`remove ${makeFullKey(e)}`),window.localStorage.removeItem(makeFullKey(e))},getOrSet=(e,t)=>{const r=get(e);return null==r?(set(e,t),t):r},increment=e=>{const t=get(e);if(null==t)return set(e,0),0;{let r=t+1;return set(e,r),r}},setSpeaker=e=>{set(makeTranscriptKey(e.transcriptId,e.sessionIndex,e.speakerIndex),{image:e.image,person:e.person,text:e.text,startedAt:e.startedAt,endedAt:e.endedAt,highlight:e.highlight},!0)},getTranscript=e=>{const t=get(makeTranscriptKey(e))||0;let r=[];const o=get(makeTranscriptKey(e,t))||0;for(let n=0;n<=o;n+=1){const o=get(makeTranscriptKey(e,t,n));if(o&&o.text&&o.text.match(/\S/g)){startTimeStored||(startTimeStored=new Date(o.startedAt),startTime=new Date(o.startedAt));const a={transcriptId:e,sessionIndex:t,speakerIndex:n,person:o.person in SPEAKER_NAME_MAP?SPEAKER_NAME_MAP[o.person]:o.person,startedAt:new Date(o.startedAt),endedAt:new Date(o.endedAt),image:o.image,text:o.text,highlight:o.highlight};r.push(a)}}return r},deleteTranscript=e=>{const t=get(makeTranscriptKey(e));for(let r=0;r<=t;r+=1){const t=get(makeTranscriptKey(e,r));for(let o=0;o<=t;o+=1)remove(makeTranscriptKey(e,r,o));remove(makeTranscriptKey(e,r))}remove(makeTranscriptKey(e)),get(makeTranscriptKey(`${e}_name`))&&remove(makeTranscriptKey(`${e}_name`));let r=get(KEY_TRANSCRIPT_IDS)||[],o=get(APPLICATION_SPEECH_IDS)||[];const n=r.indexOf(e),a=o.findIndex((t=>t.ext===e));r.splice(n,1),o.splice(a,1),debug("would set transcript to",r),debug("would set transcript pairs to",o),set(KEY_TRANSCRIPT_IDS,r),set(APPLICATION_SPEECH_IDS,o);const s=document.querySelector(`#${e}`);if(s){const e=s.parentNode;e.removeChild(s),0===e.children.length&&(e.parentNode.removeChild(e.previousSibling),e.parentNode.removeChild(e))}else debug(`transcriptNode doesn't exist for ${e}`)},deletePreviousTranscripts=()=>{let e=get(KEY_TRANSCRIPT_IDS)||[];if(e.length>1)for(let t of e)t!==currentTranscriptId&&deleteTranscript(t)};
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
const getTranscriptText = (e, t) => {
|
||||||
|
let o = [];
|
||||||
|
sessionList.forEach((e => {
|
||||||
|
o.unshift(e)
|
||||||
|
}));
|
||||||
|
let n = "<div>",
|
||||||
|
i = {};
|
||||||
|
n += "<div style='font-size:20pt; color: #2F5496'>Transcripts<br></div>", o.forEach(((s, a) => {
|
||||||
|
if (s.text && s.text.length && (0 === a || s.startedAt !== o[a - 1].startedAt)) {
|
||||||
|
let o = "",
|
||||||
|
a = "You" === s.person ? appUser : s.person;
|
||||||
|
if (s.highlight.length && e && (o = s.highlight[0], s.highlight[0])) {
|
||||||
|
let e = s.highlight[0],
|
||||||
|
t = i[e] ? i[e] : [];
|
||||||
|
t.push({
|
||||||
|
text: s.text,
|
||||||
|
time: getTimeStr(startTime, s.startedAt),
|
||||||
|
person: a
|
||||||
|
}), i[e] = t
|
||||||
|
}
|
||||||
|
if (n += "<div style='font-size:11pt'>", n = n + "<i style='color:#9e9e9e'>" + a, t && (n += ` (${getTimeStr(startTime,s.startedAt)})`), n += ": </i>", e && o.length) {
|
||||||
|
const e = bookmarkList.find((e => e.color === o)).code;
|
||||||
|
n += `<div style="color:${e}; display:inline">`
|
||||||
|
}
|
||||||
|
n += s.text, e && o.length && (n += "</div>"), n += "<br><br></div>"
|
||||||
|
}
|
||||||
|
})), n += "</div>";
|
||||||
|
let s = "";
|
||||||
|
return e && (s += "<div>", s += "<div style='font-size:20pt; color: #2F5496'>Highlights<br></div>", Object.keys(i).forEach((e => {
|
||||||
|
let t = bookmarkList.find((t => t.color === e)),
|
||||||
|
o = t.name,
|
||||||
|
n = t.code;
|
||||||
|
s += "<div>", s += `<span style="color:${n}; font-weight:bold; font-size:14pt">${o}:<br></span>`, i[e].forEach((e => {
|
||||||
|
s += `<div style='font-size:11pt'><i style='color:#9e9e9e'>${e.person} (${e.time}): </i>${e.text}<br><br></div>`
|
||||||
|
})), s += "</div>"
|
||||||
|
})), s += "</div>"), `<div style='font-family:calibri'><div style='font-size:14pt'>${startTime}<br></div>` + s + n + "</div>"
|
||||||
|
},
|
||||||
|
Export2Txt = (e, t = "") => {
|
||||||
|
let o = document.createElement("a"),
|
||||||
|
n = e.replaceAll("<br>", "\n"),
|
||||||
|
i = document.createElement("div");
|
||||||
|
i.style.display = "none", i.innerHTML = n;
|
||||||
|
let s = i.innerText;
|
||||||
|
const a = new File([s], "filename"),
|
||||||
|
d = URL.createObjectURL(a);
|
||||||
|
return o.href = d, o.download = `${t}.txt`, document.body.appendChild(o), o.click(), document.body.removeChild(o), Promise.resolve(1)
|
||||||
|
},
|
||||||
|
Export2Pdf = (e, t = "") => {
|
||||||
|
const o = window.html2pdf;
|
||||||
|
t = t ? t + ".pdf" : `${getDefaultName()}.pdf`;
|
||||||
|
let n = document.createElement("div");
|
||||||
|
n.innerHTML = e, document.body.appendChild(n);
|
||||||
|
const i = {
|
||||||
|
margin: [8, 16, 8, 16],
|
||||||
|
filename: `${t}.pdf`,
|
||||||
|
enableLinks: !1,
|
||||||
|
pagebreak: {
|
||||||
|
avoid: ["div"],
|
||||||
|
mode: ["css"]
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
type: "jpeg",
|
||||||
|
quality: 1
|
||||||
|
},
|
||||||
|
html2canvas: {
|
||||||
|
allowTaint: !0,
|
||||||
|
dpi: 144,
|
||||||
|
letterRendering: !0,
|
||||||
|
logging: !1,
|
||||||
|
scale: 2,
|
||||||
|
scrollX: 0,
|
||||||
|
scrollY: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new Promise(((e, t) => {
|
||||||
|
o().from(n).set(i).toPdf().get("pdf").then((e => {
|
||||||
|
const t = e.internal.getNumberOfPages();
|
||||||
|
for (let o = 1; o < t + 1; o++) e.setPage(o), e.setFontSize(14), e.text(`${o}/${t}`, e.internal.pageSize.getWidth() - 10, e.internal.pageSize.getHeight() - 5);
|
||||||
|
document.body.removeChild(n)
|
||||||
|
})).save().then((() => {
|
||||||
|
e("Downloaded")
|
||||||
|
})).catch((e => t(e)))
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
Export2Word = (e, t = "") => {
|
||||||
|
var o = "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word' xmlns='http://www.w3.org/TR/REC-html40'><head><meta charset='utf-8'><title>Export HTML To Doc</title></head><body>" + e + "</body></html>",
|
||||||
|
n = new Blob(["\ufeff", o], {
|
||||||
|
type: "application/msword"
|
||||||
|
}),
|
||||||
|
i = "data:application/vnd.ms-word;charset=utf-8," + encodeURIComponent(o);
|
||||||
|
t = t ? `${t}.doc` : `${getDefaultName()}.doc`;
|
||||||
|
var s = document.createElement("a");
|
||||||
|
return document.body.appendChild(s), navigator.msSaveOrOpenBlob ? navigator.msSaveOrOpenBlob(n, t) : (s.href = i, s.download = t, s.click()), document.body.removeChild(s), Promise.resolve(1)
|
||||||
|
},
|
||||||
|
disableSaveToLaxisCloud = e => {
|
||||||
|
const t = document.getElementById("laxis-confirm-download");
|
||||||
|
t && (t.disabled = e, t.style.color = t.disabled ? "#999" : "");
|
||||||
|
const o = document.getElementById("extension");
|
||||||
|
o && (o.onchange = () => {
|
||||||
|
t && (t.disabled = e && "app" === o.value, t.style.color = t.disabled ? "#999" : "")
|
||||||
|
});
|
||||||
|
const n = document.getElementById("autoSaveCheck");
|
||||||
|
n && (n.disabled = e)
|
||||||
|
},
|
||||||
|
displayGoogleMeetQuota = (e, t) => {
|
||||||
|
const o = document.getElementById("google-meet-quota");
|
||||||
|
o && -1 !== t && 0 !== t && (e < t ? (o.innerHTML = `Autosave to Laxis cloud: ${e.toFixed(0)} / ${t.toFixed(0)} minutes. <br/> Please <span style='color: #2196f3;'>upgrade</span> to enjoy unlimited autosave.`, disableSaveToLaxisCloud(!1)) : (o.innerHTML = `Autosave to Laxis cloud: <span style='color: #E94B4B;'>${e.toFixed(0)} / ${t.toFixed(0)}</span> minutes. <br/> Please <span style='color: #2196f3;'>upgrade</span> to enjoy unlimited autosave.`, disableSaveToLaxisCloud(!0)), o.style.display = "block")
|
||||||
|
},
|
||||||
|
reDisplayPrompt = () => {
|
||||||
|
const e = document.getElementById("login-prompt");
|
||||||
|
e && (e.style.display = "block"), chrome.storage.local.remove("token")
|
||||||
|
},
|
||||||
|
addRemindLogin = () => {
|
||||||
|
console.log("add login");
|
||||||
|
const e = document.getElementById("laxis-miniPanel"),
|
||||||
|
t = document.getElementById("laxis-expandPanel"),
|
||||||
|
o = document.createElement("div");
|
||||||
|
o.title = "Login to autosave notes", o.id = "laxis-remindLogin", o.style.width = "40px", o.style.height = "40px", o.classList.add("miniButtonContainer"), o.style.border = "0", o.addEventListener("click", signup), o.style.padding = "0";
|
||||||
|
const n = createRemindLoginIcon();
|
||||||
|
n.id = "remindLoginIcon", o.appendChild(n), n.id = "remindLoginIcon", o.style.display = "none", e.insertBefore(o, t)
|
||||||
|
},
|
||||||
|
reDisplayRemindLogin = () => {
|
||||||
|
console.log("redisplay");
|
||||||
|
const e = document.getElementById("laxis-remindLogin");
|
||||||
|
e && (e.style.display = "block"), chrome.storage.local.remove("token")
|
||||||
|
},
|
||||||
|
getTopics = (e, t) => window.fetch(`${domainUrl}/api/v2/templates/${e}/topics`, t),
|
||||||
|
Export2App = async (e, t = !1) => new Promise(((o, n) => {
|
||||||
|
chrome.storage.local.get(["token"], (function(i) {
|
||||||
|
if (i.token) {
|
||||||
|
let s = document.getElementById("laxis-openDownloadMenu"),
|
||||||
|
a = document.getElementById("laxis-download-menu-mini");
|
||||||
|
s.classList.add("loading"), a.classList.add("loading"), window.fetch(`${domainUrl}/api/v2/templates?quick-note=true`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${i.token}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
}).then((s => {
|
||||||
|
200 === s.status ? s.json().then((s => {
|
||||||
|
s.items.length ? getTopics(s.items[0].id, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${i.token}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
}).then((a => {
|
||||||
|
a.json().then((a => {
|
||||||
|
const d = a.items;
|
||||||
|
let l = [];
|
||||||
|
if (getTranscript(currentTranscriptId).forEach((({
|
||||||
|
image: t,
|
||||||
|
person: o,
|
||||||
|
text: n,
|
||||||
|
startedAt: i,
|
||||||
|
endedAt: s,
|
||||||
|
highlight: a
|
||||||
|
}) => {
|
||||||
|
let r = [];
|
||||||
|
if (a && e) {
|
||||||
|
const e = bookmarkList.find((e => e.color === a[0]));
|
||||||
|
if (e) {
|
||||||
|
const t = d.find((t => t.color.toLowerCase() === e.code.toLowerCase()));
|
||||||
|
t && (r = [t.id])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n && l.push({
|
||||||
|
imageUrl: t,
|
||||||
|
person: "You" === o ? appUser : o,
|
||||||
|
startedAt: i,
|
||||||
|
endedAt: s || i,
|
||||||
|
highlights: r,
|
||||||
|
text: n
|
||||||
|
})
|
||||||
|
})), l.length) {
|
||||||
|
let e = JSON.stringify({
|
||||||
|
meetingId: currentTranscriptId,
|
||||||
|
meetingName: document.getElementById("meeting-name").innerText,
|
||||||
|
templateId: s.items[0].id,
|
||||||
|
transcripts: l,
|
||||||
|
isEnded: t
|
||||||
|
}),
|
||||||
|
a = {
|
||||||
|
Authorization: `Bearer ${i.token}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
d = get(APPLICATION_SPEECH_IDS) || [],
|
||||||
|
r = d.findIndex((e => e.ext === currentTranscriptId));
|
||||||
|
if (-1 === r) window.fetch(`${domainUrl}/api/v1/speeches/google-meet`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: a,
|
||||||
|
body: e
|
||||||
|
}).then((e => {
|
||||||
|
200 === e.status ? e.json().then((e => {
|
||||||
|
set(APPLICATION_SPEECH_IDS, [...d, {
|
||||||
|
ext: currentTranscriptId,
|
||||||
|
app: e.id
|
||||||
|
}]), chrome.runtime.sendMessage({
|
||||||
|
type: "transcriptId",
|
||||||
|
transcriptId: e.id
|
||||||
|
}), o(e.id)
|
||||||
|
})) : 401 === e.status ? (e.json().then((e => {
|
||||||
|
saveLog(`Export2App 401 fail 1 ${i.token} ${e.id} ${e.message}`)
|
||||||
|
})), reDisplayPrompt(), n("Expired token")) : e.json().then((e => {
|
||||||
|
n(e.message)
|
||||||
|
}))
|
||||||
|
})).catch((e => {
|
||||||
|
n(e)
|
||||||
|
}));
|
||||||
|
else {
|
||||||
|
let t = d[r].app;
|
||||||
|
window.fetch(`${domainUrl}/api/v1/speeches/google-meet/${t}`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: a,
|
||||||
|
body: e
|
||||||
|
}).then((e => {
|
||||||
|
200 === e.status ? e.json().then((() => {
|
||||||
|
o(t)
|
||||||
|
})) : 401 === e.status ? (e.json().then((e => {
|
||||||
|
saveLog(`Export2App 401 fail 2 ${i.token} ${t} ${e.message}`)
|
||||||
|
})), reDisplayPrompt(), n("Expired token")) : e.json().then((e => {
|
||||||
|
n(e.message)
|
||||||
|
}))
|
||||||
|
})).catch((e => {
|
||||||
|
n(e)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
} else n("Empty transcript")
|
||||||
|
}))
|
||||||
|
})).catch((e => n(e))) : n("No quick note template")
|
||||||
|
})) : 401 === s.status ? (s.json().then((e => {
|
||||||
|
saveLog(`Export2App 401 fail 3 ${e.message} ${i.token}`)
|
||||||
|
})), reDisplayPrompt(), n("Expired token")) : s.json().then((e => n(e.message)))
|
||||||
|
})).catch((e => {
|
||||||
|
n(e)
|
||||||
|
})).finally((() => {
|
||||||
|
s.classList.remove("loading"), a.classList.remove("loading"), s.classList.add("finishing"), a.classList.add("finishing"), setTimeout((() => {
|
||||||
|
s.classList.remove("finishing"), a.classList.remove("finishing")
|
||||||
|
}), 3e3)
|
||||||
|
}))
|
||||||
|
} else n("Not logged in")
|
||||||
|
}))
|
||||||
|
})), downloadTranscript = () => {
|
||||||
|
const e = document.getElementById("meeting-name").innerText,
|
||||||
|
t = document.getElementById("laxis-confirm-download");
|
||||||
|
t.innerHTML = "Downloading...";
|
||||||
|
const o = document.getElementById("highlightCheck").checked,
|
||||||
|
n = document.getElementById("timestampCheck").checked,
|
||||||
|
i = document.getElementById("extension").value.toString(),
|
||||||
|
s = getTranscriptText(o, n);
|
||||||
|
let a;
|
||||||
|
switch (i) {
|
||||||
|
case "pdf":
|
||||||
|
a = () => Export2Pdf(s, e);
|
||||||
|
break;
|
||||||
|
case "doc":
|
||||||
|
a = () => Export2Word(s, e);
|
||||||
|
break;
|
||||||
|
case "txt":
|
||||||
|
a = () => Export2Txt(s, e);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
a = () => Export2App(o)
|
||||||
|
}
|
||||||
|
a().then((e => {
|
||||||
|
"app" === i && window.open(`${domainUrl}/transcript/${e}`, "_blank")
|
||||||
|
})).catch((e => {
|
||||||
|
window.alert(e);
|
||||||
|
const t = get(ERROR_SAVING) || [];
|
||||||
|
set(ERROR_SAVING, [...t, e])
|
||||||
|
})).finally((() => {
|
||||||
|
t.innerHTML = "Download";
|
||||||
|
const e = document.getElementById("laxis-downloadMenu");
|
||||||
|
e && (e.style.display = "none")
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
|
||||||
|
function saveLog(e) {
|
||||||
|
const t = {
|
||||||
|
message: e,
|
||||||
|
time: (new Date).toISOString()
|
||||||
|
};
|
||||||
|
chrome.storage.local.get("logs", (function(e) {
|
||||||
|
var o = structuredClone(e.logs);
|
||||||
|
void 0 === o ? o = [t] : o.push(t), chrome.storage.local.set({
|
||||||
|
logs: o
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.stringSimilarity=e():t.stringSimilarity=e()}(self,(function(){return t={138:t=>{function e(t,e){if((t=t.replace(/\s+/g,""))===(e=e.replace(/\s+/g,"")))return 1;if(t.length<2||e.length<2)return 0;let r=new Map;for(let e=0;e<t.length-1;e++){const n=t.substring(e,e+2),o=r.has(n)?r.get(n)+1:1;r.set(n,o)}let n=0;for(let t=0;t<e.length-1;t++){const o=e.substring(t,t+2),s=r.has(o)?r.get(o):0;s>0&&(r.set(o,s-1),n++)}return 2*n/(t.length+e.length-2)}t.exports={compareTwoStrings:e,findBestMatch:function(t,r){if(!function(t,e){return"string"==typeof t&&!!Array.isArray(e)&&!!e.length&&!e.find((function(t){return"string"!=typeof t}))}(t,r))throw new Error("Bad arguments: First argument should be a string, second should be an array of strings");const n=[];let o=0;for(let s=0;s<r.length;s++){const i=r[s],f=e(t,i);n.push({target:i,rating:f}),f>n[o].rating&&(o=s)}return{ratings:n,bestMatch:n[o],bestMatchIndex:o}}}}},e={},function r(n){if(e[n])return e[n].exports;var o=e[n]={exports:{}};return t[n](o,o.exports,r),o.exports}(138);var t,e}));
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
const pad=t=>t<10?`0${t}`:t,debug=(...t)=>{DEBUG&&console.log("[laxis debug]",...t)},tryTo=(t,e)=>async(...n)=>{try{return await t(...n)}catch(t){console.error(`error ${e}:`,t)}},getTimeStr=(t,e)=>{const n=new Date(e)-t,o=Math.trunc(n/1e3)%60,a=Math.trunc(n/1e3/60);return pad(a)+":"+pad(o)},signup=()=>{window.open(loginUrl)},upgrade=()=>{window.open(upgradeUrl)},getDefaultName=()=>{const t=new Date,e=t.getDate(),n=t.getMonth(),o=t.getFullYear(),a=t.getHours(),r=t.getMinutes();return`Meeting_${o}${pad(n+1)}${pad(e)}_${pad(a)}${pad(r)}`};function onShortcut(t){var e="";document.addEventListener("keydown",(function(n){if(n.shiftKey){if((e+=""+n.key)===SHORTCUT_KEY)return t();SHORTCUT_KEY.indexOf(e)&&(e=""+n.key)}}))}onShortcut((function(){const t=document.getElementById("laxis-repair");t&&(t.style.display="block")}));const getCurrentLanguage=()=>{const t=xpath('//button[contains(@jsname,"gnzhTe")]',document);if(t){const e=t.ariaLabel;return e.substring(0,e.length-17)}return""},getToSettings=()=>{const t='//div[contains(@jscontroller,"bZ0mod")]';if(xpath('//div[contains(@aria-label, "Settings")]',document)){const t=xpath('//button[contains(@aria-label, "Close dialog")]',document);if(t)return void t.click()}else{const e=xpath('//button[contains(@aria-label, "More options") and contains(@jscontroller, "PIVayb")]',document);e&&e.click();let n=!1;const o=xpath(t,document);if(o&&"none"!==o?.style?.display&&(o.style.display="none",n=!0),!n){let e=setInterval((()=>{const n=xpath(t,document);n&&"none"!==n?.style?.display&&(n.style.display="none",clearInterval(e))}),[50])}let a=setInterval((()=>{const t=xpath('//i[contains(text(), "settings")]',document);if(t){t.click(),clearInterval(a);let e=setInterval((()=>{const t=xpath('//button[contains(@aria-label, "Captions")]',document);t&&(t.click(),clearInterval(e))}),[50])}}),[50])}},extractLocalStorage=()=>{const t=(t,e="")=>{let n=document.createElement("a");const o=new File([t],"filename"),a=URL.createObjectURL(o);return n.href=a,n.download=`${e}.json`,document.body.appendChild(n),n.click(),document.body.removeChild(n),Promise.resolve(1)};console.log((()=>{var e,n={};for(e in window.localStorage)e.includes("laxis")&&(value=window.localStorage.getItem(e),n[e]=value);if(!chrome||!chrome.storage)return t(JSON.stringify(n),"dumplocalStorage"),n;chrome.storage.local.get(null,(function(e){for(var o in e)return n[o]=e[o],t(JSON.stringify(n),"dumplocalStorage"),n}))})())};
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="15" height="18" viewBox="0 0 15 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416" fill="#E94B4B"/>
|
||||||
|
<path d="M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416" stroke="#E94B4B" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="15" height="18" viewBox="0 0 15 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416" fill="#FFD339"/>
|
||||||
|
<path d="M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416" stroke="#FFD339" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="15" height="18" viewBox="0 0 15 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416" fill="#9CCC65"/>
|
||||||
|
<path d="M1 11.8277H13.5105C13.682 11.8277 13.8499 11.7788 13.9945 11.6867C14.1392 11.5947 14.2546 11.4634 14.3274 11.3081C14.4001 11.1528 14.427 10.98 14.4051 10.81C14.3832 10.64 14.3132 10.4797 14.2035 10.3479L10.9254 6.41387L14.2035 2.47979C14.3132 2.34805 14.3832 2.18778 14.4051 2.01773C14.427 1.84769 14.4001 1.67492 14.3274 1.51965C14.2546 1.36438 14.1392 1.23304 13.9945 1.14101C13.8499 1.04898 13.682 1.00006 13.5105 1H1V17.2416" stroke="#9CCC65" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="160" width="160" version="1.0">
|
||||||
|
<g fill="#fff">
|
||||||
|
<path d="m80 15c-35.88 0-65 29.12-65 65s29.12 65 65 65 65-29.12 65-65-29.12-65-65-65zm0 10c30.36 0 55 24.64 55 55s-24.64 55-55 55-55-24.64-55-55 24.64-55 55-55z"/>
|
||||||
|
<path d="m57.373 18.231a9.3834 9.1153 0 1 1 -18.767 0 9.3834 9.1153 0 1 1 18.767 0z" transform="matrix(1.1989 0 0 1.2342 21.214 28.75)"/>
|
||||||
|
<path d="m90.665 110.96c-0.069 2.73 1.211 3.5 4.327 3.82l5.008 0.1v5.12h-39.073v-5.12l5.503-0.1c3.291-0.1 4.082-1.38 4.327-3.82v-30.813c0.035-4.879-6.296-4.113-10.757-3.968v-5.074l30.665-1.105"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 669 B |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 667 B |
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg fill="#9e9e9e" height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
viewBox="0 0 81.159 81.159" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path d="M74.175,5.262c-1.068-1.069-2.527-1.659-4.107-1.659c-1.775,0-3.563,0.748-4.934,2.058l-5.884,4.776l-0.229,0.208
|
||||||
|
c-1.301,1.299-1.813,3.124-1.498,4.962L43.806,28.926l-2.302-1.992c1.65-6.453,1.447-15.049-4.118-20.614
|
||||||
|
C33.311,2.245,28.097,0,22.706,0c-2.143,0-4.261,0.358-6.296,1.063c-0.932,0.323-1.646,1.083-1.909,2.034s-0.042,1.969,0.59,2.726
|
||||||
|
l7.393,8.836l-0.364,5.683l-6.144,0.701l-8.771-7.338c-0.757-0.634-1.776-0.855-2.727-0.59c-0.951,0.264-1.711,0.978-2.034,1.91
|
||||||
|
c-2.396,6.919-0.285,14.371,5.792,20.444c3.274,3.276,7.988,5.007,13.63,5.007c0.413,0,0.829-0.021,1.245-0.041
|
||||||
|
c-0.209,0.182-0.419,0.362-0.617,0.56L5.641,57.847c-4.679,4.679-4.679,12.291,0,16.97l2.827,2.827
|
||||||
|
c2.266,2.267,5.28,3.515,8.485,3.515s6.219-1.248,8.485-3.515L42.29,60.791c0.934-0.933,1.669-1.982,2.223-3.103l14.969,17.296
|
||||||
|
c0.048,0.055,0.098,0.107,0.148,0.159c1.678,1.677,4.196,2.601,7.094,2.601c3.521,0,7.095-1.385,9.326-3.615
|
||||||
|
c3.922-3.922,5.158-12.267,1.012-16.416c-0.053-0.051-0.104-0.101-0.159-0.146L55.108,38.709L67.682,25.76
|
||||||
|
c0.346,0.059,0.692,0.088,1.041,0.088c1.506,0,2.896-0.563,3.916-1.582l4.984-6.113c1.141-1.192,1.855-2.695,2.021-4.251
|
||||||
|
c0.193-1.822-0.398-3.568-1.621-4.79L74.175,5.262z M38.048,56.549L21.196,73.402c-1.133,1.133-2.64,1.757-4.243,1.757
|
||||||
|
s-3.109-0.624-4.243-1.757l-2.827-2.827c-2.339-2.34-2.339-6.146,0-8.484l16.853-16.854c1.133-1.133,2.64-1.757,4.242-1.757
|
||||||
|
c0.471,0,0.932,0.062,1.379,0.165l7.438,8.595C39.813,53.797,39.234,55.363,38.048,56.549z M71.806,69.887
|
||||||
|
c-1.111,1.111-3.154,1.857-5.084,1.857c-1.211,0-2.246-0.293-2.793-0.789L32.121,34.203c-0.797-0.921-2.073-1.269-3.225-0.88
|
||||||
|
c-2.24,0.754-4.671,1.152-7.031,1.152c-3.958,0-7.292-1.154-9.387-3.25c-1.896-1.896-4.559-5.25-4.957-9.432l5.59,4.677
|
||||||
|
c0.63,0.528,1.447,0.773,2.266,0.68l9.915-1.132c1.443-0.165,2.561-1.339,2.653-2.789l0.601-9.384
|
||||||
|
c0.049-0.769-0.199-1.526-0.693-2.116l-4.789-5.724c3.663,0.1,7.229,1.709,10.077,4.557c3.918,3.919,3.833,11.259,2.095,16.421
|
||||||
|
c-0.389,1.154-0.041,2.429,0.88,3.226l36.757,31.808C74.206,63.476,73.891,67.801,71.806,69.887z M73.261,14.035l-4.707,5.772
|
||||||
|
c-0.049-0.019-0.104-0.045-0.164-0.081l-2.037-1.21l-15.787,16.26l-2.207-1.909l16.41-15.935l-1.209-2.035
|
||||||
|
c-0.035-0.062-0.063-0.117-0.08-0.165l5.541-4.499l0.23-0.208c0.299-0.297,0.598-0.4,0.784-0.417l3.646,3.646
|
||||||
|
C73.669,13.404,73.572,13.723,73.261,14.035z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -0,0 +1 @@
|
|||||||
|
const script=document.createElement("script");script.setAttribute("type","text/javascript");const filePath=chrome.runtime.getURL("runtime.js");script.setAttribute("src",filePath),document.body.appendChild(script);
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
try {
|
||||||
|
importScripts("config/share.js"), importScripts("config/panel.js")
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
let meetingId = null,
|
||||||
|
transcriptId = null,
|
||||||
|
meetingName = null,
|
||||||
|
username = "";
|
||||||
|
chrome.storage.session.setAccessLevel({
|
||||||
|
accessLevel: "TRUSTED_AND_UNTRUSTED_CONTEXTS"
|
||||||
|
});
|
||||||
|
const getTopics = (e, t) => fetch(`${domainUrl}/api/v2/templates/${e}/topics`, t);
|
||||||
|
chrome.tabs.onRemoved.addListener(((e, t) => {
|
||||||
|
chrome.storage.session.get(["sessionList"], (e => {
|
||||||
|
if (e.sessionList) {
|
||||||
|
let t = e.sessionList;
|
||||||
|
console.log(t), chrome.storage.local.get(["token"], (e => {
|
||||||
|
if (e.token) {
|
||||||
|
let o = e.token;
|
||||||
|
fetch(`${domainUrl}/api/v2/templates?quick-note=true`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${o}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
}).then((e => {
|
||||||
|
200 === e.status ? e.json().then((e => {
|
||||||
|
e.items.length ? getTopics(e.items[0].id, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${o}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
}).then((s => {
|
||||||
|
s.json().then((s => {
|
||||||
|
const n = s.items;
|
||||||
|
let r = [];
|
||||||
|
if (t.forEach((({
|
||||||
|
image: e,
|
||||||
|
person: t,
|
||||||
|
text: o,
|
||||||
|
startedAt: s,
|
||||||
|
endedAt: i,
|
||||||
|
highlight: a
|
||||||
|
}) => {
|
||||||
|
let c = [];
|
||||||
|
if (a) {
|
||||||
|
const e = bookmarkList.find((e => e.color === a[0]));
|
||||||
|
if (e) {
|
||||||
|
const t = n.find((t => t.color.toLowerCase() === e.code.toLowerCase()));
|
||||||
|
t && (c = [t.id])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
o && r.push({
|
||||||
|
imageUrl: e,
|
||||||
|
person: "You" === t ? username : t,
|
||||||
|
startedAt: s,
|
||||||
|
endedAt: i || s,
|
||||||
|
highlights: c,
|
||||||
|
text: o
|
||||||
|
})
|
||||||
|
})), r.length) {
|
||||||
|
let t = JSON.stringify({
|
||||||
|
meetingId: meetingId,
|
||||||
|
meetingName: meetingName,
|
||||||
|
templateId: e.items[0].id,
|
||||||
|
transcripts: r,
|
||||||
|
isEnded: !0
|
||||||
|
}),
|
||||||
|
s = {
|
||||||
|
Authorization: `Bearer ${o}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
};
|
||||||
|
transcriptId ? fetch(`${domainUrl}/api/v1/speeches/google-meet/${transcriptId}`, {
|
||||||
|
method: "PUT",
|
||||||
|
headers: s,
|
||||||
|
body: t
|
||||||
|
}).then((e => {
|
||||||
|
200 === e.status ? (console.log("save success"), chrome.tabs.create({
|
||||||
|
url: `${domainUrl}/transcript/${transcriptId}`
|
||||||
|
})) : 401 === e.status ? console.log("Expired token") : e.json().then((e => {
|
||||||
|
console.log(e.message)
|
||||||
|
}))
|
||||||
|
})).catch((e => {
|
||||||
|
console.log(e)
|
||||||
|
})) : fetch(`${domainUrl}/api/v1/speeches/google-meet`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: s,
|
||||||
|
body: t
|
||||||
|
}).then((e => {
|
||||||
|
200 === e.status ? (chrome.tabs.create({
|
||||||
|
url: `${domainUrl}/transcript/${transcriptId}`
|
||||||
|
}), console.log("success")) : 401 === e.status ? console.log("Expired token") : e.json().then((e => {
|
||||||
|
console.log(e.message)
|
||||||
|
}))
|
||||||
|
})).catch((e => {
|
||||||
|
console.log(e)
|
||||||
|
}))
|
||||||
|
} else console.log("Empty transcript")
|
||||||
|
}))
|
||||||
|
})).catch((e => reject(e))) : console.log("No quick note template")
|
||||||
|
})) : 401 === e.status ? console.log("Expired token") : e.json().then((e => console.log(e.message)))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
})), chrome.runtime.onMessage.addListener((e => {
|
||||||
|
console.log(e), "meetingId" === e.type && (console.log(e.meetingId), meetingId = e.meetingId), "transcriptId" === e.type && (console.log(e.transcriptId), transcriptId = e.transcriptId), "meetingName" === e.type && (meetingName = e.meetingName), "username" === e.type && (username = e.data)
|
||||||
|
})), chrome.runtime.onInstalled.addListener((e => {
|
||||||
|
// e.reason === chrome.runtime.OnInstalledReason.INSTALL && chrome.tabs.create({
|
||||||
|
// url: signupUrl
|
||||||
|
// }, (function(e) {}))
|
||||||
|
})), chrome.runtime.onMessageExternal.addListener((function(e, t, o) {
|
||||||
|
t.origin === domainUrl && (o("extension received the token"), chrome.storage.local.set({
|
||||||
|
token: e.token,
|
||||||
|
refreshToken: e.refreshToken
|
||||||
|
}, (function() {})), chrome.tabs.query({
|
||||||
|
url: googleMeetUrl
|
||||||
|
}, (function(t) {
|
||||||
|
t[0] && chrome.tabs.sendMessage(t[0].id, {
|
||||||
|
token: e.token,
|
||||||
|
refreshToken: e.refreshToken
|
||||||
|
}, (function(e) {}))
|
||||||
|
})))
|
||||||
|
})), chrome.runtime.setUninstallURL("https://www.laxis.tech/uninstall-survey");
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
{
|
||||||
|
"update_url": "https://clients2.google.com/service/update2/crx",
|
||||||
|
|
||||||
|
"manifest_version": 3,
|
||||||
|
"name": "Google Meet Transcripts & AI Summary",
|
||||||
|
"description": "Google Meet Transcription, AI Summary and Insight. Get the most out of Google Meet!",
|
||||||
|
"version": "4.3.12",
|
||||||
|
"icons": {
|
||||||
|
"16": "image/logo16x16.png",
|
||||||
|
"48": "image/logo48x48.png",
|
||||||
|
"128": "image/logo128x128.png"
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"service_worker": "login.js"
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": ["https://meet.google.com/*"],
|
||||||
|
"js": [
|
||||||
|
"feature/utilities/packages/jquery.min.js",
|
||||||
|
"feature/utilities/packages/html2canvas.js",
|
||||||
|
"feature/utilities/packages/html2pdf.bundle.min.js",
|
||||||
|
"feature/utilities/packages/string-similarity.min.js",
|
||||||
|
"feature/utilities/util.js",
|
||||||
|
"inject.js",
|
||||||
|
"style/panel.js",
|
||||||
|
"config/share.js",
|
||||||
|
"config/panel.js",
|
||||||
|
"config/record.js",
|
||||||
|
"feature/record/captionObserver.js",
|
||||||
|
"feature/record/captionControls.js",
|
||||||
|
"feature/record/captionProcessing.js",
|
||||||
|
"feature/record/settings.js",
|
||||||
|
"feature/record/storage.js",
|
||||||
|
"feature/record/dom.js",
|
||||||
|
"feature/record/transcript.js",
|
||||||
|
"feature/record/meetingInfo.js",
|
||||||
|
"feature/panel/main.js",
|
||||||
|
"feature/panel/icons.js",
|
||||||
|
"runtime.js"
|
||||||
|
],
|
||||||
|
"run_at": "document_idle",
|
||||||
|
"all_frames": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"web_accessible_resources": [
|
||||||
|
{
|
||||||
|
"resources": [
|
||||||
|
"runtime.js",
|
||||||
|
"image/bookmark/*.svg",
|
||||||
|
"image/logo.png",
|
||||||
|
"image/info.svg",
|
||||||
|
"image/repair.svg",
|
||||||
|
"style/panel.css"
|
||||||
|
],
|
||||||
|
"matches": ["https://meet.google.com/*"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"permissions": ["storage"],
|
||||||
|
"host_permissions": ["https://meet.google.com/*"]
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
addRoot(),addMiniPanel(),addRemindLogin();const checkOngoingMeeting=setInterval(tryTo(addCaptionPanel,"adding button"),1e3);let notificationsTimeout;const notificationsTimeoutDuration=3e3;let checkCaptionStatusInterval;function saveLog(e){const t={message:e,time:(new Date).toISOString()};chrome.storage.local.get("logs",(function(e){var n=structuredClone(e.logs);void 0===n?n=[t]:n.push(t),chrome.storage.local.set({logs:n})}))}syncSettings(),window.addEventListener("click",(e=>{const t=document.getElementById("laxis-downloadMenu");e.target===t&&(t.style.display="none")})),chrome.runtime.onMessage.addListener((function(e,t,n){if(t.id===extensionId)if(e.token){n("token received by content script");const t={method:"GET",headers:{Authorization:`Bearer ${e.token}`}},o=()=>window.fetch(`${domainUrl}/api/v1/users/info`,t),i=()=>window.fetch(`${domainUrl}/api/v2/templates?quick-note=true`,t),s=e=>window.fetch(`${domainUrl}/api/v2/templates/${e}/topics`,t);Promise.all([o(),i()]).then((t=>{if(200===t[0].status&&200===t[1].status){loginStatus=1;const e=document.getElementById("login-prompt");e&&(e.style.display="none");const n=document.getElementById("laxis-remindLogin");n&&(n.style.display="none"),t[0].json().then((e=>{appUser=`${e.firstName} ${e.lastName}`,chrome.runtime.sendMessage({type:"username",data:`${e.firstName} ${e.lastName}`})})),t[1].json().then((e=>{let t=bookmarkList;s(e.items[0].id).then((e=>e.json().then((e=>{e.items.forEach((e=>{let n=bookmarkList.findIndex((t=>t.code===e.color));if(-1!==n){if(t[n].name=e.name,document.getElementById(`laxis-highlight-${e.color}-title`)){document.getElementById(`laxis-highlight-${e.color}-title`).innerHTML=e.name}let o=document.getElementById(`laxis-highlight-${e.color}`),i=document.getElementById(`laxis-highlight-${e.color}-mini`);o&&(o.title=`Highlight as ${e.name}`),i&&(i.title=`Highlight as ${e.name}`)}}))})))).catch((e=>console.warn(e))),bookmarkList=t}))}else 401===t[0].status||401===t[1].status?(401===t[0].status?t[0].json().then((t=>{saveLog(`chrome.runtime.onMessage.addListener 401 fail ${t.message} ${e.token}`)})):t[1].json().then((t=>{saveLog(`chrome.runtime.onMessage.addListener 401 fail ${t.message} ${e.token}`)})),reDisplayPrompt(),reDisplayRemindLogin()):t[0].json().then((e=>{window.alert(e.message)}))})).catch((e=>{window.alert(e)}))}else saveLog(`chrome.runtime.onMessage.addListener token empty fail ${e.token}`),reDisplayRemindLogin()}));
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panelBase {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 998;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-12 {
|
||||||
|
padding: 8px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*toggle*/
|
||||||
|
/*!*caption hover*!*/
|
||||||
|
/*.highlight-caption:hover {*/
|
||||||
|
/* background-color: #696969;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
/*tooltip*/
|
||||||
|
.popup {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.popup .popupText {
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 90%;
|
||||||
|
background-color: #555;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 7px 0;
|
||||||
|
z-index: 1;
|
||||||
|
bottom: calc(100% + 7px);
|
||||||
|
left: 5%;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #292c35;
|
||||||
|
background-color: #818388;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.popup .show {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip:hover {
|
||||||
|
background-color: #454953;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: solid 1px #c7c7c7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip .tooltiptext {
|
||||||
|
visibility: hidden;
|
||||||
|
width: 100px;
|
||||||
|
background-color: #454953;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
bottom: 100%;
|
||||||
|
left: 98%;
|
||||||
|
margin-left: -100px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip .tooltiptext::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -5px;
|
||||||
|
border-width: 5px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #000000 transparent transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip:hover .tooltiptext {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-tooltip {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-tooltip .tooltiplargetext {
|
||||||
|
visibility: hidden;
|
||||||
|
min-width: 200px;
|
||||||
|
background-color: #454953;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #c7c7c7;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
bottom: 100%;
|
||||||
|
left: 98%;
|
||||||
|
margin-left: -100px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
padding: 2px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-tooltip .tooltiplargetext::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -5px;
|
||||||
|
border-width: 5px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #000000 transparent transparent transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-tooltip:hover .tooltiplargetext {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
display: none; /* Hidden by default */
|
||||||
|
position: absolute; /* Stay in place */
|
||||||
|
z-index: 1500; /* Sit on top */
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 300px; /* Full width */
|
||||||
|
overflow: auto; /* Enable scroll if needed */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modal Content/Box */
|
||||||
|
.modal-content {
|
||||||
|
background-color: #454953;
|
||||||
|
color: #ffffff;
|
||||||
|
border: solid 1px #ffffff;
|
||||||
|
margin-top: 98px;
|
||||||
|
margin-left: 17px;
|
||||||
|
width: 266px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.modal-header {
|
||||||
|
padding: 20px;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
border-bottom: 1px solid #e0e0e0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding-top: 24px;
|
||||||
|
padding-left: 30px;
|
||||||
|
padding-right: 30px;
|
||||||
|
justify-content: space-between;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.modal-footer {
|
||||||
|
border-top: 1px solid #e0e0e0;
|
||||||
|
margin-top: 48px;
|
||||||
|
padding-top: 12px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
padding-left: 30px;
|
||||||
|
padding-right: 30px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
.modal-button {
|
||||||
|
width: 45%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 36px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #ffffff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.miniButtonContainer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-top: 12px;
|
||||||
|
padding: 9px 0 9px 0;
|
||||||
|
background-color: #3e4149;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid #3e4149;
|
||||||
|
}
|
||||||
|
|
||||||
|
.miniButtonContainer:hover {
|
||||||
|
border: 1px solid #2196f3;
|
||||||
|
}
|
||||||
|
.imageContainer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid #292c35;
|
||||||
|
padding: 7px;
|
||||||
|
background-color: #292c35;
|
||||||
|
margin-right: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.imageContainer:hover {
|
||||||
|
border: 1px solid #2196f3;
|
||||||
|
}
|
||||||
|
.tutorialContainer {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
padding: 8px;
|
||||||
|
margin: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #454953;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flagContainer {
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid #9e9e9e;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.flagContainer:hover {
|
||||||
|
border: 1px solid #2196f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flagContainerMini {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 6px 0px;
|
||||||
|
background-color: #292c35;
|
||||||
|
}
|
||||||
|
.flagContainerMini:hover {
|
||||||
|
border: 1px solid #2196f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
border: 1px solid rgb(0, 38, 255);
|
||||||
|
}
|
||||||
|
.finishing {
|
||||||
|
border: 1px solid #2196f3;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
const STYLE=document.createElement("style"),promise=new Promise((e=>{fetch(chrome.runtime.getURL("style/panel.css")).then((e=>e.text())).then((t=>{e(t)}))}));promise.then((e=>{STYLE.innerText=e.toString(),document.body.append(STYLE)}));
|
||||||