mirror of
https://github.com/gr0grig/obsidian-virt-folder.git
synced 2026-07-22 10:30:27 +00:00
7265 lines
202 KiB
JavaScript
7265 lines
202 KiB
JavaScript
/*
|
|
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
if you want to view the source, please visit the github repository of this plugin
|
|
*/
|
|
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
var __publicField = (obj, key, value) => {
|
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
return value;
|
|
};
|
|
|
|
// main.ts
|
|
var main_exports = {};
|
|
__export(main_exports, {
|
|
default: () => VirtFolderPlugin
|
|
});
|
|
module.exports = __toCommonJS(main_exports);
|
|
var import_obsidian9 = require("obsidian");
|
|
|
|
// node_modules/svelte/src/runtime/internal/utils.js
|
|
function noop() {
|
|
}
|
|
var identity = (x) => x;
|
|
function run(fn) {
|
|
return fn();
|
|
}
|
|
function blank_object() {
|
|
return /* @__PURE__ */ Object.create(null);
|
|
}
|
|
function run_all(fns) {
|
|
fns.forEach(run);
|
|
}
|
|
function is_function(thing) {
|
|
return typeof thing === "function";
|
|
}
|
|
function safe_not_equal(a, b) {
|
|
return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function";
|
|
}
|
|
function is_empty(obj) {
|
|
return Object.keys(obj).length === 0;
|
|
}
|
|
function subscribe(store, ...callbacks) {
|
|
if (store == null) {
|
|
for (const callback of callbacks) {
|
|
callback(void 0);
|
|
}
|
|
return noop;
|
|
}
|
|
const unsub = store.subscribe(...callbacks);
|
|
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
|
|
}
|
|
function get_store_value(store) {
|
|
let value;
|
|
subscribe(store, (_) => value = _)();
|
|
return value;
|
|
}
|
|
function component_subscribe(component, store, callback) {
|
|
component.$$.on_destroy.push(subscribe(store, callback));
|
|
}
|
|
function action_destroyer(action_result) {
|
|
return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;
|
|
}
|
|
|
|
// node_modules/svelte/src/runtime/internal/environment.js
|
|
var is_client = typeof window !== "undefined";
|
|
var now = is_client ? () => window.performance.now() : () => Date.now();
|
|
var raf = is_client ? (cb) => requestAnimationFrame(cb) : noop;
|
|
|
|
// node_modules/svelte/src/runtime/internal/loop.js
|
|
var tasks = /* @__PURE__ */ new Set();
|
|
function run_tasks(now2) {
|
|
tasks.forEach((task) => {
|
|
if (!task.c(now2)) {
|
|
tasks.delete(task);
|
|
task.f();
|
|
}
|
|
});
|
|
if (tasks.size !== 0)
|
|
raf(run_tasks);
|
|
}
|
|
function loop(callback) {
|
|
let task;
|
|
if (tasks.size === 0)
|
|
raf(run_tasks);
|
|
return {
|
|
promise: new Promise((fulfill) => {
|
|
tasks.add(task = { c: callback, f: fulfill });
|
|
}),
|
|
abort() {
|
|
tasks.delete(task);
|
|
}
|
|
};
|
|
}
|
|
|
|
// node_modules/svelte/src/runtime/internal/globals.js
|
|
var globals = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : (
|
|
// @ts-ignore Node typings have this
|
|
global
|
|
);
|
|
|
|
// node_modules/svelte/src/runtime/internal/ResizeObserverSingleton.js
|
|
var ResizeObserverSingleton = class {
|
|
/** @param {ResizeObserverOptions} options */
|
|
constructor(options) {
|
|
/**
|
|
* @private
|
|
* @readonly
|
|
* @type {WeakMap<Element, import('./private.js').Listener>}
|
|
*/
|
|
__publicField(this, "_listeners", "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0);
|
|
/**
|
|
* @private
|
|
* @type {ResizeObserver}
|
|
*/
|
|
__publicField(this, "_observer");
|
|
/** @type {ResizeObserverOptions} */
|
|
__publicField(this, "options");
|
|
this.options = options;
|
|
}
|
|
/**
|
|
* @param {Element} element
|
|
* @param {import('./private.js').Listener} listener
|
|
* @returns {() => void}
|
|
*/
|
|
observe(element2, listener) {
|
|
this._listeners.set(element2, listener);
|
|
this._getObserver().observe(element2, this.options);
|
|
return () => {
|
|
this._listeners.delete(element2);
|
|
this._observer.unobserve(element2);
|
|
};
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
_getObserver() {
|
|
var _a;
|
|
return (_a = this._observer) != null ? _a : this._observer = new ResizeObserver((entries) => {
|
|
var _a2;
|
|
for (const entry of entries) {
|
|
ResizeObserverSingleton.entries.set(entry.target, entry);
|
|
(_a2 = this._listeners.get(entry.target)) == null ? void 0 : _a2(entry);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
ResizeObserverSingleton.entries = "WeakMap" in globals ? /* @__PURE__ */ new WeakMap() : void 0;
|
|
|
|
// node_modules/svelte/src/runtime/internal/dom.js
|
|
var is_hydrating = false;
|
|
function start_hydrating() {
|
|
is_hydrating = true;
|
|
}
|
|
function end_hydrating() {
|
|
is_hydrating = false;
|
|
}
|
|
function append(target, node) {
|
|
target.appendChild(node);
|
|
}
|
|
function get_root_for_style(node) {
|
|
if (!node)
|
|
return document;
|
|
const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
|
|
if (root && /** @type {ShadowRoot} */
|
|
root.host) {
|
|
return (
|
|
/** @type {ShadowRoot} */
|
|
root
|
|
);
|
|
}
|
|
return node.ownerDocument;
|
|
}
|
|
function append_empty_stylesheet(node) {
|
|
const style_element = element("style");
|
|
style_element.textContent = "/* empty */";
|
|
append_stylesheet(get_root_for_style(node), style_element);
|
|
return style_element.sheet;
|
|
}
|
|
function append_stylesheet(node, style) {
|
|
append(
|
|
/** @type {Document} */
|
|
node.head || node,
|
|
style
|
|
);
|
|
return style.sheet;
|
|
}
|
|
function insert(target, node, anchor) {
|
|
target.insertBefore(node, anchor || null);
|
|
}
|
|
function detach(node) {
|
|
if (node.parentNode) {
|
|
node.parentNode.removeChild(node);
|
|
}
|
|
}
|
|
function element(name) {
|
|
return document.createElement(name);
|
|
}
|
|
function text(data2) {
|
|
return document.createTextNode(data2);
|
|
}
|
|
function space() {
|
|
return text(" ");
|
|
}
|
|
function empty() {
|
|
return text("");
|
|
}
|
|
function listen(node, event, handler, options) {
|
|
node.addEventListener(event, handler, options);
|
|
return () => node.removeEventListener(event, handler, options);
|
|
}
|
|
function prevent_default(fn) {
|
|
return function(event) {
|
|
event.preventDefault();
|
|
return fn.call(this, event);
|
|
};
|
|
}
|
|
function stop_propagation(fn) {
|
|
return function(event) {
|
|
event.stopPropagation();
|
|
return fn.call(this, event);
|
|
};
|
|
}
|
|
function attr(node, attribute, value) {
|
|
if (value == null)
|
|
node.removeAttribute(attribute);
|
|
else if (node.getAttribute(attribute) !== value)
|
|
node.setAttribute(attribute, value);
|
|
}
|
|
function children(element2) {
|
|
return Array.from(element2.childNodes);
|
|
}
|
|
function set_data(text2, data2) {
|
|
data2 = "" + data2;
|
|
if (text2.data === data2)
|
|
return;
|
|
text2.data = /** @type {string} */
|
|
data2;
|
|
}
|
|
function toggle_class(element2, name, toggle) {
|
|
element2.classList.toggle(name, !!toggle);
|
|
}
|
|
function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {
|
|
return new CustomEvent(type, { detail, bubbles, cancelable });
|
|
}
|
|
function get_custom_elements_slots(element2) {
|
|
const result = {};
|
|
element2.childNodes.forEach(
|
|
/** @param {Element} node */
|
|
(node) => {
|
|
result[node.slot || "default"] = true;
|
|
}
|
|
);
|
|
return result;
|
|
}
|
|
|
|
// node_modules/svelte/src/runtime/internal/style_manager.js
|
|
var managed_styles = /* @__PURE__ */ new Map();
|
|
var active = 0;
|
|
function hash(str) {
|
|
let hash2 = 5381;
|
|
let i = str.length;
|
|
while (i--)
|
|
hash2 = (hash2 << 5) - hash2 ^ str.charCodeAt(i);
|
|
return hash2 >>> 0;
|
|
}
|
|
function create_style_information(doc, node) {
|
|
const info = { stylesheet: append_empty_stylesheet(node), rules: {} };
|
|
managed_styles.set(doc, info);
|
|
return info;
|
|
}
|
|
function create_rule(node, a, b, duration, delay, ease, fn, uid = 0) {
|
|
const step = 16.666 / duration;
|
|
let keyframes = "{\n";
|
|
for (let p = 0; p <= 1; p += step) {
|
|
const t = a + (b - a) * ease(p);
|
|
keyframes += p * 100 + `%{${fn(t, 1 - t)}}
|
|
`;
|
|
}
|
|
const rule = keyframes + `100% {${fn(b, 1 - b)}}
|
|
}`;
|
|
const name = `__svelte_${hash(rule)}_${uid}`;
|
|
const doc = get_root_for_style(node);
|
|
const { stylesheet, rules } = managed_styles.get(doc) || create_style_information(doc, node);
|
|
if (!rules[name]) {
|
|
rules[name] = true;
|
|
stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);
|
|
}
|
|
const animation = node.style.animation || "";
|
|
node.style.animation = `${animation ? `${animation}, ` : ""}${name} ${duration}ms linear ${delay}ms 1 both`;
|
|
active += 1;
|
|
return name;
|
|
}
|
|
function delete_rule(node, name) {
|
|
const previous = (node.style.animation || "").split(", ");
|
|
const next = previous.filter(
|
|
name ? (anim) => anim.indexOf(name) < 0 : (anim) => anim.indexOf("__svelte") === -1
|
|
// remove all Svelte animations
|
|
);
|
|
const deleted = previous.length - next.length;
|
|
if (deleted) {
|
|
node.style.animation = next.join(", ");
|
|
active -= deleted;
|
|
if (!active)
|
|
clear_rules();
|
|
}
|
|
}
|
|
function clear_rules() {
|
|
raf(() => {
|
|
if (active)
|
|
return;
|
|
managed_styles.forEach((info) => {
|
|
const { ownerNode } = info.stylesheet;
|
|
if (ownerNode)
|
|
detach(ownerNode);
|
|
});
|
|
managed_styles.clear();
|
|
});
|
|
}
|
|
|
|
// node_modules/svelte/src/runtime/internal/lifecycle.js
|
|
var current_component;
|
|
function set_current_component(component) {
|
|
current_component = component;
|
|
}
|
|
|
|
// node_modules/svelte/src/runtime/internal/scheduler.js
|
|
var dirty_components = [];
|
|
var binding_callbacks = [];
|
|
var render_callbacks = [];
|
|
var flush_callbacks = [];
|
|
var resolved_promise = /* @__PURE__ */ Promise.resolve();
|
|
var update_scheduled = false;
|
|
function schedule_update() {
|
|
if (!update_scheduled) {
|
|
update_scheduled = true;
|
|
resolved_promise.then(flush);
|
|
}
|
|
}
|
|
function tick() {
|
|
schedule_update();
|
|
return resolved_promise;
|
|
}
|
|
function add_render_callback(fn) {
|
|
render_callbacks.push(fn);
|
|
}
|
|
var seen_callbacks = /* @__PURE__ */ new Set();
|
|
var flushidx = 0;
|
|
function flush() {
|
|
if (flushidx !== 0) {
|
|
return;
|
|
}
|
|
const saved_component = current_component;
|
|
do {
|
|
try {
|
|
while (flushidx < dirty_components.length) {
|
|
const component = dirty_components[flushidx];
|
|
flushidx++;
|
|
set_current_component(component);
|
|
update(component.$$);
|
|
}
|
|
} catch (e) {
|
|
dirty_components.length = 0;
|
|
flushidx = 0;
|
|
throw e;
|
|
}
|
|
set_current_component(null);
|
|
dirty_components.length = 0;
|
|
flushidx = 0;
|
|
while (binding_callbacks.length)
|
|
binding_callbacks.pop()();
|
|
for (let i = 0; i < render_callbacks.length; i += 1) {
|
|
const callback = render_callbacks[i];
|
|
if (!seen_callbacks.has(callback)) {
|
|
seen_callbacks.add(callback);
|
|
callback();
|
|
}
|
|
}
|
|
render_callbacks.length = 0;
|
|
} while (dirty_components.length);
|
|
while (flush_callbacks.length) {
|
|
flush_callbacks.pop()();
|
|
}
|
|
update_scheduled = false;
|
|
seen_callbacks.clear();
|
|
set_current_component(saved_component);
|
|
}
|
|
function update($$) {
|
|
if ($$.fragment !== null) {
|
|
$$.update();
|
|
run_all($$.before_update);
|
|
const dirty = $$.dirty;
|
|
$$.dirty = [-1];
|
|
$$.fragment && $$.fragment.p($$.ctx, dirty);
|
|
$$.after_update.forEach(add_render_callback);
|
|
}
|
|
}
|
|
function flush_render_callbacks(fns) {
|
|
const filtered = [];
|
|
const targets = [];
|
|
render_callbacks.forEach((c) => fns.indexOf(c) === -1 ? filtered.push(c) : targets.push(c));
|
|
targets.forEach((c) => c());
|
|
render_callbacks = filtered;
|
|
}
|
|
|
|
// node_modules/svelte/src/runtime/internal/transitions.js
|
|
var promise;
|
|
function wait() {
|
|
if (!promise) {
|
|
promise = Promise.resolve();
|
|
promise.then(() => {
|
|
promise = null;
|
|
});
|
|
}
|
|
return promise;
|
|
}
|
|
function dispatch(node, direction, kind) {
|
|
node.dispatchEvent(custom_event(`${direction ? "intro" : "outro"}${kind}`));
|
|
}
|
|
var outroing = /* @__PURE__ */ new Set();
|
|
var outros;
|
|
function group_outros() {
|
|
outros = {
|
|
r: 0,
|
|
c: [],
|
|
p: outros
|
|
// parent group
|
|
};
|
|
}
|
|
function check_outros() {
|
|
if (!outros.r) {
|
|
run_all(outros.c);
|
|
}
|
|
outros = outros.p;
|
|
}
|
|
function transition_in(block, local) {
|
|
if (block && block.i) {
|
|
outroing.delete(block);
|
|
block.i(local);
|
|
}
|
|
}
|
|
function transition_out(block, local, detach2, callback) {
|
|
if (block && block.o) {
|
|
if (outroing.has(block))
|
|
return;
|
|
outroing.add(block);
|
|
outros.c.push(() => {
|
|
outroing.delete(block);
|
|
if (callback) {
|
|
if (detach2)
|
|
block.d(1);
|
|
callback();
|
|
}
|
|
});
|
|
block.o(local);
|
|
} else if (callback) {
|
|
callback();
|
|
}
|
|
}
|
|
var null_transition = { duration: 0 };
|
|
function create_bidirectional_transition(node, fn, params, intro) {
|
|
const options = { direction: "both" };
|
|
let config = fn(node, params, options);
|
|
let t = intro ? 0 : 1;
|
|
let running_program = null;
|
|
let pending_program = null;
|
|
let animation_name = null;
|
|
let original_inert_value;
|
|
function clear_animation() {
|
|
if (animation_name)
|
|
delete_rule(node, animation_name);
|
|
}
|
|
function init2(program, duration) {
|
|
const d = (
|
|
/** @type {Program['d']} */
|
|
program.b - t
|
|
);
|
|
duration *= Math.abs(d);
|
|
return {
|
|
a: t,
|
|
b: program.b,
|
|
d,
|
|
duration,
|
|
start: program.start,
|
|
end: program.start + duration,
|
|
group: program.group
|
|
};
|
|
}
|
|
function go(b) {
|
|
const {
|
|
delay = 0,
|
|
duration = 300,
|
|
easing = identity,
|
|
tick: tick2 = noop,
|
|
css
|
|
} = config || null_transition;
|
|
const program = {
|
|
start: now() + delay,
|
|
b
|
|
};
|
|
if (!b) {
|
|
program.group = outros;
|
|
outros.r += 1;
|
|
}
|
|
if ("inert" in node) {
|
|
if (b) {
|
|
if (original_inert_value !== void 0) {
|
|
node.inert = original_inert_value;
|
|
}
|
|
} else {
|
|
original_inert_value = /** @type {HTMLElement} */
|
|
node.inert;
|
|
node.inert = true;
|
|
}
|
|
}
|
|
if (running_program || pending_program) {
|
|
pending_program = program;
|
|
} else {
|
|
if (css) {
|
|
clear_animation();
|
|
animation_name = create_rule(node, t, b, duration, delay, easing, css);
|
|
}
|
|
if (b)
|
|
tick2(0, 1);
|
|
running_program = init2(program, duration);
|
|
add_render_callback(() => dispatch(node, b, "start"));
|
|
loop((now2) => {
|
|
if (pending_program && now2 > pending_program.start) {
|
|
running_program = init2(pending_program, duration);
|
|
pending_program = null;
|
|
dispatch(node, running_program.b, "start");
|
|
if (css) {
|
|
clear_animation();
|
|
animation_name = create_rule(
|
|
node,
|
|
t,
|
|
running_program.b,
|
|
running_program.duration,
|
|
0,
|
|
easing,
|
|
config.css
|
|
);
|
|
}
|
|
}
|
|
if (running_program) {
|
|
if (now2 >= running_program.end) {
|
|
tick2(t = running_program.b, 1 - t);
|
|
dispatch(node, running_program.b, "end");
|
|
if (!pending_program) {
|
|
if (running_program.b) {
|
|
clear_animation();
|
|
} else {
|
|
if (!--running_program.group.r)
|
|
run_all(running_program.group.c);
|
|
}
|
|
}
|
|
running_program = null;
|
|
} else if (now2 >= running_program.start) {
|
|
const p = now2 - running_program.start;
|
|
t = running_program.a + running_program.d * easing(p / running_program.duration);
|
|
tick2(t, 1 - t);
|
|
}
|
|
}
|
|
return !!(running_program || pending_program);
|
|
});
|
|
}
|
|
}
|
|
return {
|
|
run(b) {
|
|
if (is_function(config)) {
|
|
wait().then(() => {
|
|
const opts = { direction: b ? "in" : "out" };
|
|
config = config(opts);
|
|
go(b);
|
|
});
|
|
} else {
|
|
go(b);
|
|
}
|
|
},
|
|
end() {
|
|
clear_animation();
|
|
running_program = pending_program = null;
|
|
}
|
|
};
|
|
}
|
|
|
|
// node_modules/svelte/src/runtime/internal/each.js
|
|
function ensure_array_like(array_like_or_iterator) {
|
|
return (array_like_or_iterator == null ? void 0 : array_like_or_iterator.length) !== void 0 ? array_like_or_iterator : Array.from(array_like_or_iterator);
|
|
}
|
|
function outro_and_destroy_block(block, lookup) {
|
|
transition_out(block, 1, 1, () => {
|
|
lookup.delete(block.key);
|
|
});
|
|
}
|
|
function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block2, next, get_context) {
|
|
let o = old_blocks.length;
|
|
let n = list.length;
|
|
let i = o;
|
|
const old_indexes = {};
|
|
while (i--)
|
|
old_indexes[old_blocks[i].key] = i;
|
|
const new_blocks = [];
|
|
const new_lookup = /* @__PURE__ */ new Map();
|
|
const deltas = /* @__PURE__ */ new Map();
|
|
const updates = [];
|
|
i = n;
|
|
while (i--) {
|
|
const child_ctx = get_context(ctx, list, i);
|
|
const key = get_key(child_ctx);
|
|
let block = lookup.get(key);
|
|
if (!block) {
|
|
block = create_each_block2(key, child_ctx);
|
|
block.c();
|
|
} else if (dynamic) {
|
|
updates.push(() => block.p(child_ctx, dirty));
|
|
}
|
|
new_lookup.set(key, new_blocks[i] = block);
|
|
if (key in old_indexes)
|
|
deltas.set(key, Math.abs(i - old_indexes[key]));
|
|
}
|
|
const will_move = /* @__PURE__ */ new Set();
|
|
const did_move = /* @__PURE__ */ new Set();
|
|
function insert2(block) {
|
|
transition_in(block, 1);
|
|
block.m(node, next);
|
|
lookup.set(block.key, block);
|
|
next = block.first;
|
|
n--;
|
|
}
|
|
while (o && n) {
|
|
const new_block = new_blocks[n - 1];
|
|
const old_block = old_blocks[o - 1];
|
|
const new_key = new_block.key;
|
|
const old_key = old_block.key;
|
|
if (new_block === old_block) {
|
|
next = new_block.first;
|
|
o--;
|
|
n--;
|
|
} else if (!new_lookup.has(old_key)) {
|
|
destroy(old_block, lookup);
|
|
o--;
|
|
} else if (!lookup.has(new_key) || will_move.has(new_key)) {
|
|
insert2(new_block);
|
|
} else if (did_move.has(old_key)) {
|
|
o--;
|
|
} else if (deltas.get(new_key) > deltas.get(old_key)) {
|
|
did_move.add(new_key);
|
|
insert2(new_block);
|
|
} else {
|
|
will_move.add(old_key);
|
|
o--;
|
|
}
|
|
}
|
|
while (o--) {
|
|
const old_block = old_blocks[o];
|
|
if (!new_lookup.has(old_block.key))
|
|
destroy(old_block, lookup);
|
|
}
|
|
while (n)
|
|
insert2(new_blocks[n - 1]);
|
|
run_all(updates);
|
|
return new_blocks;
|
|
}
|
|
|
|
// node_modules/svelte/src/shared/boolean_attributes.js
|
|
var _boolean_attributes = (
|
|
/** @type {const} */
|
|
[
|
|
"allowfullscreen",
|
|
"allowpaymentrequest",
|
|
"async",
|
|
"autofocus",
|
|
"autoplay",
|
|
"checked",
|
|
"controls",
|
|
"default",
|
|
"defer",
|
|
"disabled",
|
|
"formnovalidate",
|
|
"hidden",
|
|
"inert",
|
|
"ismap",
|
|
"loop",
|
|
"multiple",
|
|
"muted",
|
|
"nomodule",
|
|
"novalidate",
|
|
"open",
|
|
"playsinline",
|
|
"readonly",
|
|
"required",
|
|
"reversed",
|
|
"selected"
|
|
]
|
|
);
|
|
var boolean_attributes = /* @__PURE__ */ new Set([..._boolean_attributes]);
|
|
|
|
// node_modules/svelte/src/runtime/internal/Component.js
|
|
function create_component(block) {
|
|
block && block.c();
|
|
}
|
|
function mount_component(component, target, anchor) {
|
|
const { fragment, after_update } = component.$$;
|
|
fragment && fragment.m(target, anchor);
|
|
add_render_callback(() => {
|
|
const new_on_destroy = component.$$.on_mount.map(run).filter(is_function);
|
|
if (component.$$.on_destroy) {
|
|
component.$$.on_destroy.push(...new_on_destroy);
|
|
} else {
|
|
run_all(new_on_destroy);
|
|
}
|
|
component.$$.on_mount = [];
|
|
});
|
|
after_update.forEach(add_render_callback);
|
|
}
|
|
function destroy_component(component, detaching) {
|
|
const $$ = component.$$;
|
|
if ($$.fragment !== null) {
|
|
flush_render_callbacks($$.after_update);
|
|
run_all($$.on_destroy);
|
|
$$.fragment && $$.fragment.d(detaching);
|
|
$$.on_destroy = $$.fragment = null;
|
|
$$.ctx = [];
|
|
}
|
|
}
|
|
function make_dirty(component, i) {
|
|
if (component.$$.dirty[0] === -1) {
|
|
dirty_components.push(component);
|
|
schedule_update();
|
|
component.$$.dirty.fill(0);
|
|
}
|
|
component.$$.dirty[i / 31 | 0] |= 1 << i % 31;
|
|
}
|
|
function init(component, options, instance3, create_fragment3, not_equal, props, append_styles = null, dirty = [-1]) {
|
|
const parent_component = current_component;
|
|
set_current_component(component);
|
|
const $$ = component.$$ = {
|
|
fragment: null,
|
|
ctx: [],
|
|
// state
|
|
props,
|
|
update: noop,
|
|
not_equal,
|
|
bound: blank_object(),
|
|
// lifecycle
|
|
on_mount: [],
|
|
on_destroy: [],
|
|
on_disconnect: [],
|
|
before_update: [],
|
|
after_update: [],
|
|
context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),
|
|
// everything else
|
|
callbacks: blank_object(),
|
|
dirty,
|
|
skip_bound: false,
|
|
root: options.target || parent_component.$$.root
|
|
};
|
|
append_styles && append_styles($$.root);
|
|
let ready = false;
|
|
$$.ctx = instance3 ? instance3(component, options.props || {}, (i, ret, ...rest) => {
|
|
const value = rest.length ? rest[0] : ret;
|
|
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
|
|
if (!$$.skip_bound && $$.bound[i])
|
|
$$.bound[i](value);
|
|
if (ready)
|
|
make_dirty(component, i);
|
|
}
|
|
return ret;
|
|
}) : [];
|
|
$$.update();
|
|
ready = true;
|
|
run_all($$.before_update);
|
|
$$.fragment = create_fragment3 ? create_fragment3($$.ctx) : false;
|
|
if (options.target) {
|
|
if (options.hydrate) {
|
|
start_hydrating();
|
|
const nodes = children(options.target);
|
|
$$.fragment && $$.fragment.l(nodes);
|
|
nodes.forEach(detach);
|
|
} else {
|
|
$$.fragment && $$.fragment.c();
|
|
}
|
|
if (options.intro)
|
|
transition_in(component.$$.fragment);
|
|
mount_component(component, options.target, options.anchor);
|
|
end_hydrating();
|
|
flush();
|
|
}
|
|
set_current_component(parent_component);
|
|
}
|
|
var SvelteElement;
|
|
if (typeof HTMLElement === "function") {
|
|
SvelteElement = class extends HTMLElement {
|
|
constructor($$componentCtor, $$slots, use_shadow_dom) {
|
|
super();
|
|
/** The Svelte component constructor */
|
|
__publicField(this, "$$ctor");
|
|
/** Slots */
|
|
__publicField(this, "$$s");
|
|
/** The Svelte component instance */
|
|
__publicField(this, "$$c");
|
|
/** Whether or not the custom element is connected */
|
|
__publicField(this, "$$cn", false);
|
|
/** Component props data */
|
|
__publicField(this, "$$d", {});
|
|
/** `true` if currently in the process of reflecting component props back to attributes */
|
|
__publicField(this, "$$r", false);
|
|
/** @type {Record<string, CustomElementPropDefinition>} Props definition (name, reflected, type etc) */
|
|
__publicField(this, "$$p_d", {});
|
|
/** @type {Record<string, Function[]>} Event listeners */
|
|
__publicField(this, "$$l", {});
|
|
/** @type {Map<Function, Function>} Event listener unsubscribe functions */
|
|
__publicField(this, "$$l_u", /* @__PURE__ */ new Map());
|
|
this.$$ctor = $$componentCtor;
|
|
this.$$s = $$slots;
|
|
if (use_shadow_dom) {
|
|
this.attachShadow({ mode: "open" });
|
|
}
|
|
}
|
|
addEventListener(type, listener, options) {
|
|
this.$$l[type] = this.$$l[type] || [];
|
|
this.$$l[type].push(listener);
|
|
if (this.$$c) {
|
|
const unsub = this.$$c.$on(type, listener);
|
|
this.$$l_u.set(listener, unsub);
|
|
}
|
|
super.addEventListener(type, listener, options);
|
|
}
|
|
removeEventListener(type, listener, options) {
|
|
super.removeEventListener(type, listener, options);
|
|
if (this.$$c) {
|
|
const unsub = this.$$l_u.get(listener);
|
|
if (unsub) {
|
|
unsub();
|
|
this.$$l_u.delete(listener);
|
|
}
|
|
}
|
|
}
|
|
async connectedCallback() {
|
|
this.$$cn = true;
|
|
if (!this.$$c) {
|
|
let create_slot = function(name) {
|
|
return () => {
|
|
let node;
|
|
const obj = {
|
|
c: function create() {
|
|
node = element("slot");
|
|
if (name !== "default") {
|
|
attr(node, "name", name);
|
|
}
|
|
},
|
|
/**
|
|
* @param {HTMLElement} target
|
|
* @param {HTMLElement} [anchor]
|
|
*/
|
|
m: function mount(target, anchor) {
|
|
insert(target, node, anchor);
|
|
},
|
|
d: function destroy(detaching) {
|
|
if (detaching) {
|
|
detach(node);
|
|
}
|
|
}
|
|
};
|
|
return obj;
|
|
};
|
|
};
|
|
await Promise.resolve();
|
|
if (!this.$$cn || this.$$c) {
|
|
return;
|
|
}
|
|
const $$slots = {};
|
|
const existing_slots = get_custom_elements_slots(this);
|
|
for (const name of this.$$s) {
|
|
if (name in existing_slots) {
|
|
$$slots[name] = [create_slot(name)];
|
|
}
|
|
}
|
|
for (const attribute of this.attributes) {
|
|
const name = this.$$g_p(attribute.name);
|
|
if (!(name in this.$$d)) {
|
|
this.$$d[name] = get_custom_element_value(name, attribute.value, this.$$p_d, "toProp");
|
|
}
|
|
}
|
|
for (const key in this.$$p_d) {
|
|
if (!(key in this.$$d) && this[key] !== void 0) {
|
|
this.$$d[key] = this[key];
|
|
delete this[key];
|
|
}
|
|
}
|
|
this.$$c = new this.$$ctor({
|
|
target: this.shadowRoot || this,
|
|
props: {
|
|
...this.$$d,
|
|
$$slots,
|
|
$$scope: {
|
|
ctx: []
|
|
}
|
|
}
|
|
});
|
|
const reflect_attributes = () => {
|
|
this.$$r = true;
|
|
for (const key in this.$$p_d) {
|
|
this.$$d[key] = this.$$c.$$.ctx[this.$$c.$$.props[key]];
|
|
if (this.$$p_d[key].reflect) {
|
|
const attribute_value = get_custom_element_value(
|
|
key,
|
|
this.$$d[key],
|
|
this.$$p_d,
|
|
"toAttribute"
|
|
);
|
|
if (attribute_value == null) {
|
|
this.removeAttribute(this.$$p_d[key].attribute || key);
|
|
} else {
|
|
this.setAttribute(this.$$p_d[key].attribute || key, attribute_value);
|
|
}
|
|
}
|
|
}
|
|
this.$$r = false;
|
|
};
|
|
this.$$c.$$.after_update.push(reflect_attributes);
|
|
reflect_attributes();
|
|
for (const type in this.$$l) {
|
|
for (const listener of this.$$l[type]) {
|
|
const unsub = this.$$c.$on(type, listener);
|
|
this.$$l_u.set(listener, unsub);
|
|
}
|
|
}
|
|
this.$$l = {};
|
|
}
|
|
}
|
|
// We don't need this when working within Svelte code, but for compatibility of people using this outside of Svelte
|
|
// and setting attributes through setAttribute etc, this is helpful
|
|
attributeChangedCallback(attr2, _oldValue, newValue) {
|
|
var _a;
|
|
if (this.$$r)
|
|
return;
|
|
attr2 = this.$$g_p(attr2);
|
|
this.$$d[attr2] = get_custom_element_value(attr2, newValue, this.$$p_d, "toProp");
|
|
(_a = this.$$c) == null ? void 0 : _a.$set({ [attr2]: this.$$d[attr2] });
|
|
}
|
|
disconnectedCallback() {
|
|
this.$$cn = false;
|
|
Promise.resolve().then(() => {
|
|
if (!this.$$cn) {
|
|
this.$$c.$destroy();
|
|
this.$$c = void 0;
|
|
}
|
|
});
|
|
}
|
|
$$g_p(attribute_name) {
|
|
return Object.keys(this.$$p_d).find(
|
|
(key) => this.$$p_d[key].attribute === attribute_name || !this.$$p_d[key].attribute && key.toLowerCase() === attribute_name
|
|
) || attribute_name;
|
|
}
|
|
};
|
|
}
|
|
function get_custom_element_value(prop, value, props_definition, transform) {
|
|
var _a;
|
|
const type = (_a = props_definition[prop]) == null ? void 0 : _a.type;
|
|
value = type === "Boolean" && typeof value !== "boolean" ? value != null : value;
|
|
if (!transform || !props_definition[prop]) {
|
|
return value;
|
|
} else if (transform === "toAttribute") {
|
|
switch (type) {
|
|
case "Object":
|
|
case "Array":
|
|
return value == null ? null : JSON.stringify(value);
|
|
case "Boolean":
|
|
return value ? "" : null;
|
|
case "Number":
|
|
return value == null ? null : value;
|
|
default:
|
|
return value;
|
|
}
|
|
} else {
|
|
switch (type) {
|
|
case "Object":
|
|
case "Array":
|
|
return value && JSON.parse(value);
|
|
case "Boolean":
|
|
return value;
|
|
case "Number":
|
|
return value != null ? +value : value;
|
|
default:
|
|
return value;
|
|
}
|
|
}
|
|
}
|
|
var SvelteComponent = class {
|
|
constructor() {
|
|
/**
|
|
* ### PRIVATE API
|
|
*
|
|
* Do not use, may change at any time
|
|
*
|
|
* @type {any}
|
|
*/
|
|
__publicField(this, "$$");
|
|
/**
|
|
* ### PRIVATE API
|
|
*
|
|
* Do not use, may change at any time
|
|
*
|
|
* @type {any}
|
|
*/
|
|
__publicField(this, "$$set");
|
|
}
|
|
/** @returns {void} */
|
|
$destroy() {
|
|
destroy_component(this, 1);
|
|
this.$destroy = noop;
|
|
}
|
|
/**
|
|
* @template {Extract<keyof Events, string>} K
|
|
* @param {K} type
|
|
* @param {((e: Events[K]) => void) | null | undefined} callback
|
|
* @returns {() => void}
|
|
*/
|
|
$on(type, callback) {
|
|
if (!is_function(callback)) {
|
|
return noop;
|
|
}
|
|
const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []);
|
|
callbacks.push(callback);
|
|
return () => {
|
|
const index = callbacks.indexOf(callback);
|
|
if (index !== -1)
|
|
callbacks.splice(index, 1);
|
|
};
|
|
}
|
|
/**
|
|
* @param {Partial<Props>} props
|
|
* @returns {void}
|
|
*/
|
|
$set(props) {
|
|
if (this.$$set && !is_empty(props)) {
|
|
this.$$.skip_bound = true;
|
|
this.$$set(props);
|
|
this.$$.skip_bound = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
// node_modules/svelte/src/shared/version.js
|
|
var PUBLIC_VERSION = "4";
|
|
|
|
// node_modules/svelte/src/runtime/store/index.js
|
|
var subscriber_queue = [];
|
|
function writable(value, start = noop) {
|
|
let stop;
|
|
const subscribers = /* @__PURE__ */ new Set();
|
|
function set(new_value) {
|
|
if (safe_not_equal(value, new_value)) {
|
|
value = new_value;
|
|
if (stop) {
|
|
const run_queue = !subscriber_queue.length;
|
|
for (const subscriber of subscribers) {
|
|
subscriber[1]();
|
|
subscriber_queue.push(subscriber, value);
|
|
}
|
|
if (run_queue) {
|
|
for (let i = 0; i < subscriber_queue.length; i += 2) {
|
|
subscriber_queue[i][0](subscriber_queue[i + 1]);
|
|
}
|
|
subscriber_queue.length = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function update2(fn) {
|
|
set(fn(value));
|
|
}
|
|
function subscribe2(run2, invalidate = noop) {
|
|
const subscriber = [run2, invalidate];
|
|
subscribers.add(subscriber);
|
|
if (subscribers.size === 1) {
|
|
stop = start(set, update2) || noop;
|
|
}
|
|
run2(value);
|
|
return () => {
|
|
subscribers.delete(subscriber);
|
|
if (subscribers.size === 0 && stop) {
|
|
stop();
|
|
stop = null;
|
|
}
|
|
};
|
|
}
|
|
return { set, update: update2, subscribe: subscribe2 };
|
|
}
|
|
|
|
// components/stores.ts
|
|
var plugin = writable();
|
|
var getPlugin = () => get_store_value(plugin);
|
|
var data = writable();
|
|
var active_id = writable();
|
|
|
|
// data.ts
|
|
var NoteData = class {
|
|
constructor(base) {
|
|
this.base = base;
|
|
}
|
|
onStartApp() {
|
|
this.base.rescan();
|
|
}
|
|
onCreate(file) {
|
|
this.base.add_note(file);
|
|
}
|
|
onChange(file) {
|
|
this.base.update_note(file);
|
|
}
|
|
onRename(file, oldPath) {
|
|
this.base.rename_note(file, oldPath);
|
|
}
|
|
onDelete(file) {
|
|
this.base.remove_note(file.path);
|
|
}
|
|
};
|
|
|
|
// base_scanner.ts
|
|
var import_obsidian2 = require("obsidian");
|
|
|
|
// onenote.ts
|
|
var OneNote = class {
|
|
constructor(id, mtime, ctime, name, title) {
|
|
this.utime = 0;
|
|
// created or used as folder
|
|
this.parents = [];
|
|
this.children = [];
|
|
this.is_pinned = false;
|
|
this.icon = "";
|
|
this.highlight_color = "";
|
|
this.highlight_opacity = 0;
|
|
this.metadata = {};
|
|
this.id = id;
|
|
this.mtime = mtime;
|
|
this.name = name;
|
|
this.title = title;
|
|
this.utime = ctime;
|
|
}
|
|
clear() {
|
|
this.parents = [];
|
|
this.children = [];
|
|
this.is_pinned = false;
|
|
this.highlight_color = "";
|
|
this.highlight_opacity = 0;
|
|
this.metadata = {};
|
|
this.mtime = 0;
|
|
this.utime = 0;
|
|
}
|
|
is_no_parents() {
|
|
return this.parents.length == 0;
|
|
}
|
|
is_no_children() {
|
|
return this.children.length == 0;
|
|
}
|
|
has_children() {
|
|
return this.children.length > 0;
|
|
}
|
|
count_children() {
|
|
return this.children.length;
|
|
}
|
|
};
|
|
|
|
// settings.ts
|
|
var import_obsidian = require("obsidian");
|
|
var SortTypes = /* @__PURE__ */ ((SortTypes2) => {
|
|
SortTypes2["file_name"] = "file_name";
|
|
SortTypes2["note_title"] = "note_title";
|
|
SortTypes2["creation_time"] = "creation_time";
|
|
SortTypes2["modification_time"] = "modification_time";
|
|
SortTypes2["custom"] = "custom";
|
|
return SortTypes2;
|
|
})(SortTypes || {});
|
|
var DEFAULT_SETTINGS = {
|
|
ignorePath: "",
|
|
ignoreTags: "",
|
|
includePath: "",
|
|
includeTags: "",
|
|
propertyName: "Folders",
|
|
titleProp: "",
|
|
iconProp: "vf_icon",
|
|
cmdShowTitle: false,
|
|
sortTreeBy: "file_name" /* file_name */,
|
|
sortTreeRev: false,
|
|
hideOrphans: false,
|
|
expandOnClick: false,
|
|
UseWikiLinks: true,
|
|
folderAsString: false,
|
|
confirmDelete: true,
|
|
autoReveal: false,
|
|
autoCollapse: false,
|
|
lastSeenVersion: "",
|
|
tagHighlights: [],
|
|
exposeMetadata: false,
|
|
customOrder: {}
|
|
};
|
|
var VirtFolderSettingTab = class extends import_obsidian.PluginSettingTab {
|
|
constructor(app, plugin2) {
|
|
super(app, plugin2);
|
|
this.plugin = plugin2;
|
|
this.init_settings();
|
|
}
|
|
init_settings() {
|
|
this.update_filter(this.plugin.settings.ignorePath);
|
|
this.update_ignored_tags(this.plugin.settings.ignoreTags);
|
|
this.update_include_paths(this.plugin.settings.includePath);
|
|
this.update_include_tags(this.plugin.settings.includeTags);
|
|
this.update_prop_name(this.plugin.settings.propertyName);
|
|
this.update_title(this.plugin.settings.titleProp);
|
|
this.update_icon_prop(this.plugin.settings.iconProp);
|
|
this.update_tag_highlights();
|
|
this.plugin.base.settings.set_expose_metadata(this.plugin.settings.exposeMetadata);
|
|
this.update_hide_orphans(this.plugin.settings.hideOrphans);
|
|
}
|
|
display() {
|
|
let { containerEl } = this;
|
|
containerEl.empty();
|
|
new import_obsidian.Setting(containerEl).setName("YAML for note's folders").setDesc("The name can contain letters, numbers, minus sign, underscore and dots").addText((text2) => {
|
|
text2.setValue(this.plugin.settings.propertyName);
|
|
text2.setPlaceholder("Folders");
|
|
text2.onChange(async (value) => {
|
|
let style = text2.inputEl.style;
|
|
if (this.is_valid_prop_name(value)) {
|
|
style.borderColor = "";
|
|
this.plugin.settings.propertyName = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_prop_name(value);
|
|
} else {
|
|
style.borderColor = this.get_css_var("--background-modifier-error");
|
|
}
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("YAML for note's title").setDesc("Leave the field blank to take the title from the file name. Case-sensitive").addText((text2) => {
|
|
text2.setValue(this.plugin.settings.titleProp);
|
|
text2.setPlaceholder("Title");
|
|
text2.onChange(async (value) => {
|
|
let style = text2.inputEl.style;
|
|
if (this.is_empty_str(value) || this.is_valid_prop_name(value)) {
|
|
style.borderColor = "";
|
|
this.plugin.settings.titleProp = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_title(value);
|
|
} else {
|
|
style.borderColor = this.get_css_var("--background-modifier-error");
|
|
}
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("YAML for note's icon").setDesc("The name can contain letters, numbers, minus sign, underscore and dots").addText((text2) => {
|
|
text2.setValue(this.plugin.settings.iconProp);
|
|
text2.setPlaceholder("vf_icon");
|
|
text2.onChange(async (value) => {
|
|
let style = text2.inputEl.style;
|
|
if (this.is_valid_prop_name(value)) {
|
|
style.borderColor = "";
|
|
this.plugin.settings.iconProp = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_icon_prop(value);
|
|
} else {
|
|
style.borderColor = this.get_css_var("--background-modifier-error");
|
|
}
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Use title in commands").setDesc("Display note's title instead of file name when displaying command results").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.cmdShowTitle);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.cmdShowTitle = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Sorting").setDesc("Note sorting criteria in the tree view").addDropdown((dc) => {
|
|
for (let key of Object.keys(SortTypes)) {
|
|
dc.addOption(key, key);
|
|
}
|
|
dc.setValue(this.plugin.settings.sortTreeBy);
|
|
dc.onChange(async (value) => {
|
|
this.plugin.settings.sortTreeBy = SortTypes[value];
|
|
await this.plugin.saveSettings();
|
|
this.update_note_list();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Reverse sort order").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.sortTreeRev);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.sortTreeRev = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_note_list();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Hide orphans").setDesc("Do not list orphan notes (notes with no parents and no children) in the tree").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.hideOrphans);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.hideOrphans = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_hide_orphans(value);
|
|
this.update_note_list();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Expand/collapse on title click").setDesc("When off, clicking a note's title only opens it; expanding or collapsing its children works via the arrow icon only").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.expandOnClick);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.expandOnClick = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("List of ignored paths").setDesc("Each line is interpreted as the start of an ignored path").addTextArea((textArea) => {
|
|
textArea.setValue(this.plugin.settings.ignorePath).setPlaceholder("Enter one or more paths relative to the archive root").onChange(async (value) => {
|
|
this.plugin.settings.ignorePath = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_filter(value);
|
|
this.update_counter();
|
|
this.update_note_list();
|
|
});
|
|
textArea.inputEl.setAttr("rows", 6);
|
|
textArea.inputEl.setAttr("cols", 40);
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("List of ignored tags").setDesc("Notes with any of these tags will be hidden from the tree. One tag per line, # is optional").addTextArea((textArea) => {
|
|
textArea.setValue(this.plugin.settings.ignoreTags).setPlaceholder("fleeting\n#daily").onChange(async (value) => {
|
|
this.plugin.settings.ignoreTags = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_ignored_tags(value);
|
|
this.update_counter();
|
|
this.update_note_list();
|
|
});
|
|
textArea.inputEl.setAttr("rows", 4);
|
|
textArea.inputEl.setAttr("cols", 40);
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("List of included paths").setDesc("If set, only notes whose path starts with one of these lines are shown. Leave empty to show all paths").addTextArea((textArea) => {
|
|
textArea.setValue(this.plugin.settings.includePath).setPlaceholder("Enter one or more paths relative to the archive root").onChange(async (value) => {
|
|
this.plugin.settings.includePath = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_include_paths(value);
|
|
this.update_counter();
|
|
this.update_note_list();
|
|
});
|
|
textArea.inputEl.setAttr("rows", 6);
|
|
textArea.inputEl.setAttr("cols", 40);
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("List of included tags").setDesc("If set, only notes with one of these tags are shown. Combined with included paths (a note matching either is shown). One tag per line, # is optional").addTextArea((textArea) => {
|
|
textArea.setValue(this.plugin.settings.includeTags).setPlaceholder("project\n#area").onChange(async (value) => {
|
|
this.plugin.settings.includeTags = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_include_tags(value);
|
|
this.update_counter();
|
|
this.update_note_list();
|
|
});
|
|
textArea.inputEl.setAttr("rows", 4);
|
|
textArea.inputEl.setAttr("cols", 40);
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Hidden files").addText((text2) => {
|
|
text2.setValue("0").setDisabled(true);
|
|
this.counter = text2;
|
|
});
|
|
this.update_counter();
|
|
new import_obsidian.Setting(containerEl).setName("Use [[WikiLinks]] in YAML").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.UseWikiLinks);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.UseWikiLinks = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_note_list();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Use string for single folder link").setDesc("Write the folder property as a string instead of a list when a note has only one parent").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.folderAsString);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.folderAsString = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Confirm before deleting").setDesc("Show confirmation dialog before deleting a note").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.confirmDelete);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.confirmDelete = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Auto reveal active file").setDesc("Automatically reveal the active file in the tree when opening any file").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.autoReveal);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.autoReveal = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Auto collapse other folders").setDesc("When revealing the active file, collapse the branches that are not on the path to it").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.autoCollapse);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.autoCollapse = value;
|
|
await this.plugin.saveSettings();
|
|
});
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Expose frontmatter as data attributes").setDesc("Add note properties as data-* attributes on tree items for CSS styling").addToggle((tg) => {
|
|
tg.setValue(this.plugin.settings.exposeMetadata);
|
|
tg.onChange(async (value) => {
|
|
this.plugin.settings.exposeMetadata = value;
|
|
await this.plugin.saveSettings();
|
|
this.plugin.base.settings.set_expose_metadata(value);
|
|
this.update_note_list();
|
|
});
|
|
});
|
|
containerEl.createEl("h3", { text: "Tag highlights" });
|
|
new import_obsidian.Setting(containerEl).setName("Add tag highlight").setDesc("Highlight notes in the tree based on their tags").addText((text2) => {
|
|
text2.setPlaceholder("#tag");
|
|
text2.inputEl.addEventListener("keydown", async (e) => {
|
|
if (e.key !== "Enter")
|
|
return;
|
|
let value = text2.getValue().trim();
|
|
if (!value)
|
|
return;
|
|
if (!value.startsWith("#"))
|
|
value = "#" + value;
|
|
if (this.plugin.settings.tagHighlights.some((h) => h.tag === value)) {
|
|
text2.inputEl.style.borderColor = this.get_css_var("--background-modifier-error");
|
|
return;
|
|
}
|
|
this.plugin.settings.tagHighlights.push({ tag: value, color: "#7f6df2", opacity: 0.3 });
|
|
await this.plugin.saveSettings();
|
|
this.update_tag_highlights();
|
|
this.update_note_list();
|
|
this.display();
|
|
});
|
|
});
|
|
for (let i = 0; i < this.plugin.settings.tagHighlights.length; i++) {
|
|
let hl = this.plugin.settings.tagHighlights[i];
|
|
new import_obsidian.Setting(containerEl).setName(hl.tag).addColorPicker((cp) => {
|
|
cp.setValue(hl.color);
|
|
cp.onChange(async (value) => {
|
|
hl.color = value;
|
|
await this.plugin.saveSettings();
|
|
this.update_tag_highlights();
|
|
this.update_note_list();
|
|
});
|
|
}).addSlider((sl) => {
|
|
sl.setLimits(5, 100, 5);
|
|
sl.setValue(hl.opacity * 100);
|
|
sl.setDynamicTooltip();
|
|
sl.onChange(async (value) => {
|
|
hl.opacity = value / 100;
|
|
await this.plugin.saveSettings();
|
|
this.update_tag_highlights();
|
|
this.update_note_list();
|
|
});
|
|
}).addExtraButton((btn) => {
|
|
btn.setIcon("trash");
|
|
btn.setTooltip("Remove");
|
|
btn.onClick(async () => {
|
|
this.plugin.settings.tagHighlights.splice(i, 1);
|
|
await this.plugin.saveSettings();
|
|
this.update_tag_highlights();
|
|
this.update_note_list();
|
|
this.display();
|
|
});
|
|
});
|
|
}
|
|
}
|
|
update_counter() {
|
|
let count = this.plugin.base.get_filtered_count();
|
|
this.counter.setValue(count.toString());
|
|
}
|
|
update_note_list() {
|
|
this.plugin.base.rescan();
|
|
this.plugin.update_data();
|
|
}
|
|
update_filter(value) {
|
|
let filter = this.parse_text_area(value);
|
|
this.plugin.base.settings.set_filter(filter);
|
|
}
|
|
update_ignored_tags(value) {
|
|
let tags = this.parse_text_area(value).map((t) => t.startsWith("#") ? t : "#" + t);
|
|
this.plugin.base.settings.set_ignored_tags(tags);
|
|
}
|
|
update_include_paths(value) {
|
|
let paths = this.parse_text_area(value);
|
|
this.plugin.base.settings.set_include_paths(paths);
|
|
}
|
|
update_include_tags(value) {
|
|
let tags = this.parse_text_area(value).map((t) => t.startsWith("#") ? t : "#" + t);
|
|
this.plugin.base.settings.set_include_tags(tags);
|
|
}
|
|
parse_text_area(value) {
|
|
return value.split(/\r|\n/).map((n) => n.trim()).filter((n) => n);
|
|
}
|
|
is_empty_str(name) {
|
|
return name === "";
|
|
}
|
|
is_valid_prop_name(name) {
|
|
let regexp = /^[\p{L}\p{N}_.-]+$/u;
|
|
return regexp.test(name);
|
|
}
|
|
update_prop_name(name) {
|
|
if (!this.is_valid_prop_name(name))
|
|
return;
|
|
this.plugin.base.settings.set_prop(name);
|
|
this.update_note_list();
|
|
}
|
|
update_title(value) {
|
|
if (this.is_empty_str(value) || this.is_valid_prop_name(value)) {
|
|
this.plugin.base.settings.set_title(value);
|
|
this.update_note_list();
|
|
}
|
|
}
|
|
update_icon_prop(value) {
|
|
if (this.is_valid_prop_name(value)) {
|
|
this.plugin.base.settings.set_icon_prop(value);
|
|
this.update_note_list();
|
|
}
|
|
}
|
|
update_tag_highlights() {
|
|
this.plugin.base.settings.set_tag_highlights(this.plugin.settings.tagHighlights);
|
|
}
|
|
update_hide_orphans(value) {
|
|
this.plugin.base.settings.set_hide_orphans(value);
|
|
}
|
|
get_css_var(variable) {
|
|
let el = document.querySelector("body");
|
|
if (!el)
|
|
return "";
|
|
let style = window.getComputedStyle(el);
|
|
if (!style)
|
|
return "";
|
|
return style.getPropertyValue(variable);
|
|
}
|
|
};
|
|
|
|
// base_scanner.ts
|
|
function _is_string(value) {
|
|
return typeof value === "string";
|
|
}
|
|
function _frontmatter_to_string(value) {
|
|
if (value === null || value === void 0)
|
|
return null;
|
|
if (typeof value === "string")
|
|
return value;
|
|
if (typeof value === "boolean" || typeof value === "number")
|
|
return String(value);
|
|
if (Array.isArray(value))
|
|
return value.filter((v) => typeof v !== "object").map((v) => String(v)).join(",");
|
|
return null;
|
|
}
|
|
var ScanSettings = class {
|
|
constructor() {
|
|
this.filter = [];
|
|
this.ignored_tags = [];
|
|
this.include_paths = [];
|
|
this.include_tags = [];
|
|
this.title = "";
|
|
this.icon_prop = "vf_icon";
|
|
this.tag_highlights = [];
|
|
this.expose_metadata = false;
|
|
this.hide_orphans = false;
|
|
this.prop_regexp = void 0;
|
|
}
|
|
set_filter(filter) {
|
|
this.filter = filter;
|
|
}
|
|
set_ignored_tags(tags) {
|
|
this.ignored_tags = tags;
|
|
}
|
|
set_include_paths(paths) {
|
|
this.include_paths = paths;
|
|
}
|
|
set_include_tags(tags) {
|
|
this.include_tags = tags;
|
|
}
|
|
set_title(title) {
|
|
this.title = title;
|
|
}
|
|
set_icon_prop(prop) {
|
|
this.icon_prop = prop;
|
|
}
|
|
set_tag_highlights(highlights) {
|
|
this.tag_highlights = highlights;
|
|
}
|
|
set_expose_metadata(value) {
|
|
this.expose_metadata = value;
|
|
}
|
|
set_hide_orphans(value) {
|
|
this.hide_orphans = value;
|
|
}
|
|
set_prop(prop) {
|
|
let regexp_str = `^${prop}(\\.\\d+){0,1}$`;
|
|
this.prop_regexp = new RegExp(regexp_str);
|
|
}
|
|
is_valid() {
|
|
return typeof this.prop_regexp !== "undefined";
|
|
}
|
|
};
|
|
var BaseScanner = class {
|
|
constructor(app, plugin2) {
|
|
this.app = app;
|
|
this.plugin = plugin2;
|
|
this.note_list = {};
|
|
this.top_list = [];
|
|
this.orphans_list = [];
|
|
this.last_active = ["1"];
|
|
this.settings = new ScanSettings();
|
|
}
|
|
test_prop_name(prop_name) {
|
|
if (!this.settings.prop_regexp)
|
|
return false;
|
|
return this.settings.prop_regexp.test(prop_name.trim());
|
|
}
|
|
restore_utime(old_list) {
|
|
for (let id in old_list) {
|
|
if (id in this.note_list) {
|
|
let new_ut = this.note_list[id].utime;
|
|
let old_ut = old_list[id].utime;
|
|
if (old_ut > new_ut) {
|
|
this.note_list[id].utime = old_ut;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
rescan() {
|
|
if (!this.settings.is_valid())
|
|
return;
|
|
let old_list = this.note_list;
|
|
this.init_note_list();
|
|
this.build_links();
|
|
this.build_top();
|
|
this.sort_links();
|
|
this.restore_utime(old_list);
|
|
}
|
|
get_filtered_count() {
|
|
return this.app.vault.getMarkdownFiles().length - this.get_filtered_list().length;
|
|
}
|
|
get_filtered_list() {
|
|
return this.app.vault.getMarkdownFiles().filter((file) => {
|
|
for (let filter of this.settings.filter) {
|
|
if (file.path.startsWith(filter))
|
|
return false;
|
|
}
|
|
if (this.settings.ignored_tags.length > 0) {
|
|
let cache = this.app.metadataCache.getFileCache(file);
|
|
if (cache) {
|
|
let tags = (0, import_obsidian2.getAllTags)(cache);
|
|
if (tags) {
|
|
for (let tag of tags) {
|
|
if (this.settings.ignored_tags.includes(tag))
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!this._is_included(file))
|
|
return false;
|
|
return true;
|
|
});
|
|
}
|
|
_is_included(file) {
|
|
let paths = this.settings.include_paths;
|
|
let tags = this.settings.include_tags;
|
|
if (paths.length === 0 && tags.length === 0)
|
|
return true;
|
|
for (let p of paths) {
|
|
if (file.path.startsWith(p))
|
|
return true;
|
|
}
|
|
if (tags.length > 0) {
|
|
let cache = this.app.metadataCache.getFileCache(file);
|
|
if (cache) {
|
|
let file_tags = (0, import_obsidian2.getAllTags)(cache);
|
|
if (file_tags) {
|
|
for (let tag of file_tags) {
|
|
if (tags.includes(tag))
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
get_meta_value(file, prop) {
|
|
let metadata = this.app.metadataCache.getFileCache(file);
|
|
if ((metadata == null ? void 0 : metadata.frontmatter) && prop in metadata.frontmatter) {
|
|
let value = metadata.frontmatter[prop];
|
|
if (typeof value === "string")
|
|
return value;
|
|
if (Array.isArray(value) && value.length > 0) {
|
|
let first = value[0];
|
|
if (typeof first === "string")
|
|
return first;
|
|
}
|
|
return null;
|
|
}
|
|
return null;
|
|
}
|
|
// can we get it from Note class?
|
|
get_note_title(file) {
|
|
let name = file.basename;
|
|
let title = this.get_meta_value(file, this.settings.title);
|
|
return title ? title : name;
|
|
}
|
|
link_to_title(value) {
|
|
let link_file = this.app.metadataCache.getFirstLinkpathDest(value, "");
|
|
if (!link_file)
|
|
return value;
|
|
return this.get_note_title(link_file);
|
|
}
|
|
link_to_ctime(value) {
|
|
let link_file = this.app.metadataCache.getFirstLinkpathDest(value, "");
|
|
if (!link_file)
|
|
return 0;
|
|
return link_file.stat.ctime;
|
|
}
|
|
link_to_mtime(value) {
|
|
let link_file = this.app.metadataCache.getFirstLinkpathDest(value, "");
|
|
if (!link_file)
|
|
return 0;
|
|
return link_file.stat.mtime;
|
|
}
|
|
init_note_list() {
|
|
this.note_list = {};
|
|
for (let file of this.get_filtered_list()) {
|
|
let file_id = file.path;
|
|
this.note_list[file_id] = new OneNote(
|
|
file_id,
|
|
file.stat.mtime,
|
|
file.stat.ctime,
|
|
file.basename,
|
|
this.get_note_title(file)
|
|
);
|
|
}
|
|
}
|
|
_build_note_links(file) {
|
|
let file_id = file.path;
|
|
if (!(file_id in this.note_list))
|
|
return;
|
|
let metadata = this.app.metadataCache.getFileCache(file);
|
|
if (!metadata)
|
|
return;
|
|
if (metadata.frontmatterLinks) {
|
|
for (let link of metadata.frontmatterLinks) {
|
|
if (!this.test_prop_name(link.key))
|
|
continue;
|
|
let link_file = this.app.metadataCache.getFirstLinkpathDest(link.link, "");
|
|
if (!link_file)
|
|
continue;
|
|
let link_id = link_file.path;
|
|
if (link_id === file_id)
|
|
continue;
|
|
if (!(link_id in this.note_list))
|
|
continue;
|
|
this.note_list[file_id].parents.push(link_id);
|
|
this.note_list[link_id].children.push(file_id);
|
|
}
|
|
}
|
|
if (metadata.frontmatter) {
|
|
if ("vf_pinned" in metadata.frontmatter) {
|
|
let value = metadata.frontmatter["vf_pinned"];
|
|
this.note_list[file_id].is_pinned = value != "0" && value != "false" && value != false;
|
|
}
|
|
if (this.settings.icon_prop in metadata.frontmatter) {
|
|
let value = metadata.frontmatter[this.settings.icon_prop];
|
|
if (_is_string(value))
|
|
this.note_list[file_id].icon = value;
|
|
}
|
|
}
|
|
this._apply_highlight(metadata, file_id);
|
|
this._extract_metadata(metadata, file_id);
|
|
}
|
|
_apply_highlight(metadata, file_id) {
|
|
if (this.settings.tag_highlights.length === 0)
|
|
return;
|
|
let tags = (0, import_obsidian2.getAllTags)(metadata);
|
|
if (!tags)
|
|
return;
|
|
for (let hl of this.settings.tag_highlights) {
|
|
if (tags.includes(hl.tag)) {
|
|
this.note_list[file_id].highlight_color = hl.color;
|
|
this.note_list[file_id].highlight_opacity = hl.opacity;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
_extract_metadata(metadata, file_id) {
|
|
if (!this.settings.expose_metadata)
|
|
return;
|
|
if (!(metadata == null ? void 0 : metadata.frontmatter))
|
|
return;
|
|
let result = {};
|
|
for (let key of Object.keys(metadata.frontmatter)) {
|
|
if (key === "position")
|
|
continue;
|
|
let str = _frontmatter_to_string(metadata.frontmatter[key]);
|
|
if (str === null)
|
|
continue;
|
|
result[key.toLowerCase()] = str;
|
|
}
|
|
this.note_list[file_id].metadata = result;
|
|
}
|
|
build_links() {
|
|
for (let file of this.get_filtered_list()) {
|
|
this._build_note_links(file);
|
|
}
|
|
}
|
|
is_orphan(note) {
|
|
return note.is_no_parents() && note.is_no_children();
|
|
}
|
|
is_top(note) {
|
|
return note.is_no_parents() && note.has_children();
|
|
}
|
|
is_orphan_or_top(note) {
|
|
return note.is_no_parents();
|
|
}
|
|
build_top() {
|
|
this.orphans_list = [];
|
|
this.top_list = [];
|
|
for (let i in this.note_list) {
|
|
let note = this.note_list[i];
|
|
if (this.is_orphan(note)) {
|
|
this.orphans_list.push(note.id);
|
|
continue;
|
|
}
|
|
if (this.is_top(note)) {
|
|
this.top_list.push(note.id);
|
|
}
|
|
}
|
|
}
|
|
l_sort(links, parentId) {
|
|
let links_copy = [...links];
|
|
let sortBy = this.plugin.settings.sortTreeBy;
|
|
let sortRev = this.plugin.settings.sortTreeRev;
|
|
if (sortBy == "custom" /* custom */ && parentId) {
|
|
let stored = this.plugin.settings.customOrder[parentId];
|
|
if (stored) {
|
|
let linkSet = new Set(links_copy);
|
|
let ordered = stored.filter((id) => linkSet.has(id));
|
|
let orderedSet = new Set(ordered);
|
|
let remaining = links_copy.filter((id) => !orderedSet.has(id));
|
|
remaining.sort((a, b) => a.split("/").pop().localeCompare(b.split("/").pop()));
|
|
links_copy = ordered.concat(remaining);
|
|
}
|
|
} else if (sortBy == "file_name" /* file_name */ || sortBy == "custom" /* custom */ && !parentId) {
|
|
links_copy.sort((a, b) => a.split("/").pop().localeCompare(b.split("/").pop()));
|
|
} else if (sortBy == "note_title" /* note_title */) {
|
|
links_copy.sort(
|
|
(a, b) => {
|
|
a = this.link_to_title(a);
|
|
b = this.link_to_title(b);
|
|
if (a < b) {
|
|
return -1;
|
|
}
|
|
if (a > b) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
);
|
|
} else if (sortBy == "creation_time" /* creation_time */) {
|
|
links_copy.sort(
|
|
(a, b) => {
|
|
return this.link_to_ctime(a) - this.link_to_ctime(b);
|
|
}
|
|
);
|
|
} else if (sortBy == "modification_time" /* modification_time */) {
|
|
links_copy.sort(
|
|
(a, b) => {
|
|
return this.link_to_mtime(a) - this.link_to_mtime(b);
|
|
}
|
|
);
|
|
}
|
|
if (sortBy != "custom" /* custom */ && sortRev)
|
|
links_copy.reverse();
|
|
let pinned = links_copy.filter((id) => {
|
|
var _a;
|
|
return (_a = this.note_list[id]) == null ? void 0 : _a.is_pinned;
|
|
});
|
|
let normal = links_copy.filter((id) => {
|
|
var _a;
|
|
return !((_a = this.note_list[id]) == null ? void 0 : _a.is_pinned);
|
|
});
|
|
return pinned.concat(normal);
|
|
}
|
|
sort_links() {
|
|
for (let id in this.note_list) {
|
|
let note = this.note_list[id];
|
|
note.children = this.l_sort(note.children, id);
|
|
}
|
|
this.orphans_list = this.l_sort(this.orphans_list, "orphan_dir");
|
|
this.top_list = this.l_sort(this.top_list, "top_dir");
|
|
}
|
|
note_by_id(id) {
|
|
if (id in this.note_list) {
|
|
return this.note_list[id];
|
|
}
|
|
}
|
|
get_all_descendants(id) {
|
|
let descendants = /* @__PURE__ */ new Set();
|
|
let stack = [id];
|
|
while (stack.length > 0) {
|
|
let currentId = stack.pop();
|
|
let current = this.note_by_id(currentId);
|
|
if (!current)
|
|
continue;
|
|
for (let childId of current.children) {
|
|
if (!descendants.has(childId)) {
|
|
descendants.add(childId);
|
|
stack.push(childId);
|
|
}
|
|
}
|
|
}
|
|
return descendants;
|
|
}
|
|
is_same_mtime(file) {
|
|
let id = file.path;
|
|
let note = this.note_by_id(id);
|
|
if (!note)
|
|
return false;
|
|
return note.mtime == file.stat.mtime;
|
|
}
|
|
_count_unique(arr) {
|
|
return new Set(arr).size;
|
|
}
|
|
_is_recursion(arr) {
|
|
return this._count_unique(arr) != arr.length;
|
|
}
|
|
_build_path(note, path, path_list) {
|
|
if (this._is_recursion(path))
|
|
return;
|
|
if (this.is_orphan(note)) {
|
|
let new_path = ["orphan_dir"].concat(path);
|
|
path_list.push(new_path);
|
|
return;
|
|
}
|
|
if (this.is_top(note)) {
|
|
let new_path = ["top_dir"].concat(path);
|
|
path_list.push(new_path);
|
|
return;
|
|
}
|
|
for (let parent of note.parents) {
|
|
let sub_note = this.note_by_id(parent);
|
|
if (!sub_note)
|
|
continue;
|
|
let new_path = [sub_note.id].concat(path);
|
|
this._build_path(sub_note, new_path, path_list);
|
|
}
|
|
}
|
|
build_path_list(id) {
|
|
let note = this.note_by_id(id);
|
|
if (!note)
|
|
return void 0;
|
|
let path_list = [];
|
|
this._build_path(note, [note.id], path_list);
|
|
return path_list;
|
|
}
|
|
_get_min_path(path_list) {
|
|
let min_path = [];
|
|
let min_count = Number.MAX_SAFE_INTEGER;
|
|
for (let path of path_list) {
|
|
let len = path.length;
|
|
if (len < min_count) {
|
|
min_count = len;
|
|
min_path = path;
|
|
}
|
|
}
|
|
return min_path.slice();
|
|
}
|
|
get_shortest_path(id) {
|
|
let path_list = this.build_path_list(id);
|
|
;
|
|
if (!path_list)
|
|
return void 0;
|
|
let path = this._get_min_path(path_list);
|
|
return path;
|
|
}
|
|
_array_index(path_list, old_path) {
|
|
for (let i in path_list) {
|
|
let path = path_list[i];
|
|
if (path.join("/") == old_path.join("/")) {
|
|
return parseInt(i);
|
|
}
|
|
}
|
|
}
|
|
_next_index(path_len, old_index) {
|
|
return path_len > old_index + 1 ? old_index + 1 : 0;
|
|
}
|
|
_split_into_parents(path_list) {
|
|
let parent_list = {};
|
|
for (let path of path_list) {
|
|
let parent = path[path.length - 2];
|
|
if (!(parent in parent_list))
|
|
parent_list[parent] = [];
|
|
parent_list[parent].push(path);
|
|
}
|
|
return parent_list;
|
|
}
|
|
_get_shortest_list(path_list) {
|
|
let parent_list = this._split_into_parents(path_list);
|
|
let shortest_list = [];
|
|
for (let parent in parent_list) {
|
|
let path_parent = parent_list[parent];
|
|
shortest_list.push(this._get_min_path(path_parent));
|
|
}
|
|
return shortest_list;
|
|
}
|
|
get_next_path(id) {
|
|
let path_list = this.build_path_list(id);
|
|
if (!path_list)
|
|
return void 0;
|
|
path_list = this._get_shortest_list(path_list);
|
|
let old_index = this._array_index(path_list, this.last_active);
|
|
let path = void 0;
|
|
if (old_index === void 0) {
|
|
if (this.last_active.length >= 2) {
|
|
let lastParent = this.last_active[this.last_active.length - 2];
|
|
let sameParent = path_list.find((p) => p.length >= 2 && p[p.length - 2] === lastParent);
|
|
if (sameParent)
|
|
path = sameParent;
|
|
}
|
|
if (!path)
|
|
path = this._get_min_path(path_list);
|
|
} else {
|
|
let next_index = this._next_index(path_list.length, old_index);
|
|
path = path_list[next_index];
|
|
}
|
|
this.last_active = path.slice();
|
|
return path;
|
|
}
|
|
// --- incremental updates ---
|
|
is_filtered(file) {
|
|
for (let filter of this.settings.filter) {
|
|
if (file.path.startsWith(filter))
|
|
return true;
|
|
}
|
|
if (this.settings.ignored_tags.length > 0) {
|
|
let cache = this.app.metadataCache.getFileCache(file);
|
|
if (cache) {
|
|
let tags = (0, import_obsidian2.getAllTags)(cache);
|
|
if (tags) {
|
|
for (let tag of tags) {
|
|
if (this.settings.ignored_tags.includes(tag))
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!this._is_included(file))
|
|
return true;
|
|
return false;
|
|
}
|
|
rebuild_top_and_sort() {
|
|
this.build_top();
|
|
this.sort_links();
|
|
}
|
|
_detach_parents(file_id) {
|
|
let note = this.note_by_id(file_id);
|
|
if (!note)
|
|
return;
|
|
for (let parent_id of note.parents) {
|
|
let parent = this.note_by_id(parent_id);
|
|
if (parent) {
|
|
parent.children = parent.children.filter((id) => id !== file_id);
|
|
}
|
|
}
|
|
note.parents = [];
|
|
note.is_pinned = false;
|
|
}
|
|
_detach_children(file_id) {
|
|
let note = this.note_by_id(file_id);
|
|
if (!note)
|
|
return;
|
|
for (let child_id of note.children) {
|
|
let child = this.note_by_id(child_id);
|
|
if (child) {
|
|
child.parents = child.parents.filter((id) => id !== file_id);
|
|
}
|
|
}
|
|
note.children = [];
|
|
}
|
|
add_note(file) {
|
|
if (this.is_filtered(file))
|
|
return;
|
|
let file_id = file.path;
|
|
this.note_list[file_id] = new OneNote(
|
|
file_id,
|
|
file.stat.mtime,
|
|
file.stat.ctime,
|
|
file.basename,
|
|
this.get_note_title(file)
|
|
);
|
|
this._build_note_links(file);
|
|
this.rebuild_top_and_sort();
|
|
}
|
|
remove_note(file_id) {
|
|
let note = this.note_by_id(file_id);
|
|
if (!note)
|
|
return;
|
|
this._detach_parents(file_id);
|
|
this._detach_children(file_id);
|
|
delete this.note_list[file_id];
|
|
this.rebuild_top_and_sort();
|
|
}
|
|
rename_note(file, oldPath) {
|
|
let old_note = this.note_by_id(oldPath);
|
|
if (!old_note) {
|
|
this.add_note(file);
|
|
return;
|
|
}
|
|
let newPath = file.path;
|
|
for (let parent_id of old_note.parents) {
|
|
let parent = this.note_by_id(parent_id);
|
|
if (parent) {
|
|
let idx = parent.children.indexOf(oldPath);
|
|
if (idx !== -1)
|
|
parent.children[idx] = newPath;
|
|
}
|
|
}
|
|
for (let child_id of old_note.children) {
|
|
let child = this.note_by_id(child_id);
|
|
if (child) {
|
|
let idx = child.parents.indexOf(oldPath);
|
|
if (idx !== -1)
|
|
child.parents[idx] = newPath;
|
|
}
|
|
}
|
|
old_note.id = newPath;
|
|
old_note.name = file.basename;
|
|
old_note.title = this.get_note_title(file);
|
|
old_note.mtime = file.stat.mtime;
|
|
delete this.note_list[oldPath];
|
|
this.note_list[newPath] = old_note;
|
|
this.rebuild_top_and_sort();
|
|
}
|
|
_read_expected_parents(file) {
|
|
let parents = [];
|
|
let metadata = this.app.metadataCache.getFileCache(file);
|
|
if (!metadata || !metadata.frontmatterLinks)
|
|
return parents;
|
|
for (let link of metadata.frontmatterLinks) {
|
|
if (!this.test_prop_name(link.key))
|
|
continue;
|
|
let link_file = this.app.metadataCache.getFirstLinkpathDest(link.link, "");
|
|
if (!link_file)
|
|
continue;
|
|
let link_id = link_file.path;
|
|
if (link_id === file.path)
|
|
continue;
|
|
if (!(link_id in this.note_list))
|
|
continue;
|
|
parents.push(link_id);
|
|
}
|
|
return parents;
|
|
}
|
|
_read_expected_pinned(file) {
|
|
let metadata = this.app.metadataCache.getFileCache(file);
|
|
if (!metadata || !metadata.frontmatter)
|
|
return false;
|
|
if (!("vf_pinned" in metadata.frontmatter))
|
|
return false;
|
|
let value = metadata.frontmatter["vf_pinned"];
|
|
return value != "0" && value != "false" && value != false;
|
|
}
|
|
_read_expected_icon(file) {
|
|
let metadata = this.app.metadataCache.getFileCache(file);
|
|
if (!metadata || !metadata.frontmatter)
|
|
return "";
|
|
if (!(this.settings.icon_prop in metadata.frontmatter))
|
|
return "";
|
|
let value = metadata.frontmatter[this.settings.icon_prop];
|
|
return _is_string(value) ? value : "";
|
|
}
|
|
_read_expected_highlight(file) {
|
|
if (this.settings.tag_highlights.length === 0)
|
|
return { color: "", opacity: 0 };
|
|
let metadata = this.app.metadataCache.getFileCache(file);
|
|
if (!metadata)
|
|
return { color: "", opacity: 0 };
|
|
let tags = (0, import_obsidian2.getAllTags)(metadata);
|
|
if (!tags)
|
|
return { color: "", opacity: 0 };
|
|
for (let hl of this.settings.tag_highlights) {
|
|
if (tags.includes(hl.tag))
|
|
return { color: hl.color, opacity: hl.opacity };
|
|
}
|
|
return { color: "", opacity: 0 };
|
|
}
|
|
_read_expected_metadata(file) {
|
|
if (!this.settings.expose_metadata)
|
|
return {};
|
|
let metadata = this.app.metadataCache.getFileCache(file);
|
|
if (!(metadata == null ? void 0 : metadata.frontmatter))
|
|
return {};
|
|
let result = {};
|
|
for (let key of Object.keys(metadata.frontmatter)) {
|
|
if (key === "position")
|
|
continue;
|
|
let str = _frontmatter_to_string(metadata.frontmatter[key]);
|
|
if (str === null)
|
|
continue;
|
|
result[key.toLowerCase()] = str;
|
|
}
|
|
return result;
|
|
}
|
|
_arrays_equal(a, b) {
|
|
if (a.length !== b.length)
|
|
return false;
|
|
for (let i = 0; i < a.length; i++) {
|
|
if (a[i] !== b[i])
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
_records_equal(a, b) {
|
|
let keysA = Object.keys(a);
|
|
let keysB = Object.keys(b);
|
|
if (keysA.length !== keysB.length)
|
|
return false;
|
|
for (let key of keysA) {
|
|
if (a[key] !== b[key])
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
update_note(file) {
|
|
let file_id = file.path;
|
|
let note = this.note_by_id(file_id);
|
|
if (!note) {
|
|
if (!this.is_filtered(file)) {
|
|
this.add_note(file);
|
|
}
|
|
return;
|
|
}
|
|
if (this.is_filtered(file)) {
|
|
this.remove_note(file_id);
|
|
return;
|
|
}
|
|
let expected_parents = this._read_expected_parents(file);
|
|
let expected_pinned = this._read_expected_pinned(file);
|
|
let expected_title = this.get_note_title(file);
|
|
let expected_icon = this._read_expected_icon(file);
|
|
let expected_highlight = this._read_expected_highlight(file);
|
|
let expected_metadata = this._read_expected_metadata(file);
|
|
if (note.mtime == file.stat.mtime && note.title == expected_title && note.is_pinned == expected_pinned && note.icon == expected_icon && note.highlight_color == expected_highlight.color && note.highlight_opacity == expected_highlight.opacity && this._arrays_equal(note.parents, expected_parents) && this._records_equal(note.metadata, expected_metadata)) {
|
|
return;
|
|
}
|
|
let old_utime = note.utime;
|
|
this._detach_parents(file_id);
|
|
note.mtime = file.stat.mtime;
|
|
note.title = expected_title;
|
|
note.is_pinned = expected_pinned;
|
|
note.icon = expected_icon;
|
|
note.highlight_color = expected_highlight.color;
|
|
note.highlight_opacity = expected_highlight.opacity;
|
|
note.metadata = expected_metadata;
|
|
for (let parent_id of expected_parents) {
|
|
note.parents.push(parent_id);
|
|
this.note_list[parent_id].children.push(file_id);
|
|
}
|
|
note.utime = old_utime;
|
|
this.rebuild_top_and_sort();
|
|
}
|
|
};
|
|
|
|
// select_file_modal.ts
|
|
var import_obsidian3 = require("obsidian");
|
|
var VF_SelectFile = class extends import_obsidian3.FuzzySuggestModal {
|
|
constructor(plugin2, onSubmit, excludeIds) {
|
|
super(plugin2.app);
|
|
this.plugin = plugin2;
|
|
this.onSubmit = onSubmit;
|
|
this.excludeIds = excludeIds;
|
|
this.selected = "";
|
|
this.setPlaceholder("Type note's title");
|
|
}
|
|
getItemName(item) {
|
|
if (this.plugin.settings.cmdShowTitle)
|
|
return item.title;
|
|
return item.name;
|
|
}
|
|
getItemText(item) {
|
|
return this.getItemName(item);
|
|
}
|
|
getItems() {
|
|
let notes = [];
|
|
for (let id in this.plugin.base.note_list) {
|
|
if (this.excludeIds && this.excludeIds.has(id))
|
|
continue;
|
|
notes.push(this.plugin.base.note_list[id]);
|
|
}
|
|
notes.sort(function(a, b) {
|
|
return b.utime - a.utime;
|
|
});
|
|
return notes;
|
|
}
|
|
onChooseItem(item, evt) {
|
|
this.onSubmit(item.id);
|
|
}
|
|
_format_parents(parents) {
|
|
let links = [];
|
|
for (let id of parents) {
|
|
let note = this.plugin.base.note_by_id(id);
|
|
if (!note)
|
|
continue;
|
|
links.push(this.getItemName(note));
|
|
}
|
|
return links;
|
|
}
|
|
renderSuggestion(item, el) {
|
|
el.createEl("div", { text: this.getItemName(item.item) });
|
|
let small = el.createEl("small", { cls: "vf_search_parents" });
|
|
for (let parent of item.item.parents) {
|
|
let path = this.plugin.base.get_shortest_path(parent);
|
|
if (!path)
|
|
continue;
|
|
let links = this._format_parents(path);
|
|
let line = small.createEl("div", { cls: "vf_search_div" });
|
|
for (let id of links) {
|
|
line.createEl("span", { text: id, cls: "vf_search_link" });
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// select_prop_modal.ts
|
|
var import_obsidian4 = require("obsidian");
|
|
function get_link_base(link) {
|
|
let regexp_1 = /(?:\[\[(.+?)\||\[\[(.+?)\]\]|\[.+?\]\((.+?)\))/;
|
|
let result = null;
|
|
let match = regexp_1.exec(link);
|
|
if (match) {
|
|
if (match[1])
|
|
result = match[1];
|
|
if (match[2])
|
|
result = match[2];
|
|
if (match[3])
|
|
result = match[3];
|
|
}
|
|
return result;
|
|
}
|
|
var VF_SelectPropModal = class extends import_obsidian4.SuggestModal {
|
|
constructor(plugin2, yamlProp, onSubmit) {
|
|
super(plugin2.app);
|
|
this.plugin = plugin2;
|
|
this.yamlProp = yamlProp;
|
|
this.onSubmit = onSubmit;
|
|
this.app = plugin2.app;
|
|
this.useMarkdownLinks = this.app.vault.getConfig("useMarkdownLinks");
|
|
this.setPlaceholder("Select one to remove");
|
|
}
|
|
open() {
|
|
this.plugin.yaml.get_links(this.yamlProp, (links) => {
|
|
if (links.length == 0) {
|
|
new import_obsidian4.Notice(`${this.yamlProp} is empty`);
|
|
return;
|
|
}
|
|
if (links.length == 1) {
|
|
this.onSubmit(links[0]);
|
|
return;
|
|
}
|
|
super.open();
|
|
});
|
|
}
|
|
async getSuggestions(query) {
|
|
let notes = [];
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (file) {
|
|
await this.app.fileManager.processFrontMatter(file, (fm) => {
|
|
this._get_prop_list(fm, this.yamlProp);
|
|
});
|
|
for (let item of this.prop_list) {
|
|
let name = get_link_base(item);
|
|
if (!name)
|
|
continue;
|
|
notes.push({ name, full: item });
|
|
}
|
|
}
|
|
return notes;
|
|
}
|
|
getItemName(item) {
|
|
if (!this.plugin.settings.cmdShowTitle)
|
|
return item.name;
|
|
return this.plugin.base.link_to_title(item.name);
|
|
}
|
|
renderSuggestion(item, el) {
|
|
el.createEl("div", { text: this.getItemName(item) });
|
|
}
|
|
onChooseSuggestion(item, evt) {
|
|
this.onSubmit(item.full);
|
|
}
|
|
_get_prop_list(front, prop) {
|
|
if (prop in front && front[prop]) {
|
|
this.prop_list = front[prop];
|
|
} else {
|
|
this.prop_list = [];
|
|
}
|
|
}
|
|
};
|
|
|
|
// tree_view.ts
|
|
var import_obsidian7 = require("obsidian");
|
|
|
|
// node_modules/svelte/src/runtime/internal/disclose-version/index.js
|
|
if (typeof window !== "undefined")
|
|
(window.__svelte || (window.__svelte = { v: /* @__PURE__ */ new Set() })).v.add(PUBLIC_VERSION);
|
|
|
|
// node_modules/tslib/tslib.es6.js
|
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
function adopt(value) {
|
|
return value instanceof P ? value : new P(function(resolve) {
|
|
resolve(value);
|
|
});
|
|
}
|
|
return new (P || (P = Promise))(function(resolve, reject) {
|
|
function fulfilled(value) {
|
|
try {
|
|
step(generator.next(value));
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}
|
|
function rejected(value) {
|
|
try {
|
|
step(generator["throw"](value));
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}
|
|
function step(result) {
|
|
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
}
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
}
|
|
|
|
// node_modules/svelte/src/runtime/easing/index.js
|
|
function cubicOut(t) {
|
|
const f = t - 1;
|
|
return f * f * f + 1;
|
|
}
|
|
|
|
// node_modules/svelte/src/runtime/transition/index.js
|
|
function slide(node, { delay = 0, duration = 400, easing = cubicOut, axis = "y" } = {}) {
|
|
const style = getComputedStyle(node);
|
|
const opacity = +style.opacity;
|
|
const primary_property = axis === "y" ? "height" : "width";
|
|
const primary_property_value = parseFloat(style[primary_property]);
|
|
const secondary_properties = axis === "y" ? ["top", "bottom"] : ["left", "right"];
|
|
const capitalized_secondary_properties = secondary_properties.map(
|
|
(e) => `${e[0].toUpperCase()}${e.slice(1)}`
|
|
);
|
|
const padding_start_value = parseFloat(style[`padding${capitalized_secondary_properties[0]}`]);
|
|
const padding_end_value = parseFloat(style[`padding${capitalized_secondary_properties[1]}`]);
|
|
const margin_start_value = parseFloat(style[`margin${capitalized_secondary_properties[0]}`]);
|
|
const margin_end_value = parseFloat(style[`margin${capitalized_secondary_properties[1]}`]);
|
|
const border_width_start_value = parseFloat(
|
|
style[`border${capitalized_secondary_properties[0]}Width`]
|
|
);
|
|
const border_width_end_value = parseFloat(
|
|
style[`border${capitalized_secondary_properties[1]}Width`]
|
|
);
|
|
return {
|
|
delay,
|
|
duration,
|
|
easing,
|
|
css: (t) => `overflow: hidden;opacity: ${Math.min(t * 20, 1) * opacity};${primary_property}: ${t * primary_property_value}px;padding-${secondary_properties[0]}: ${t * padding_start_value}px;padding-${secondary_properties[1]}: ${t * padding_end_value}px;margin-${secondary_properties[0]}: ${t * margin_start_value}px;margin-${secondary_properties[1]}: ${t * margin_end_value}px;border-${secondary_properties[0]}-width: ${t * border_width_start_value}px;border-${secondary_properties[1]}-width: ${t * border_width_end_value}px;`
|
|
};
|
|
}
|
|
|
|
// components/Note.svelte
|
|
var import_obsidian6 = require("obsidian");
|
|
|
|
// icon_picker_modal.ts
|
|
var import_obsidian5 = require("obsidian");
|
|
|
|
// emoji_names.ts
|
|
var EMOJI_NAMES = {
|
|
"\u{1F600}": "grinning face",
|
|
"\u{1F603}": "smiley",
|
|
"\u{1F604}": "smile",
|
|
"\u{1F601}": "grin",
|
|
"\u{1F606}": "laughing",
|
|
"\u{1F605}": "sweat smile",
|
|
"\u{1F923}": "rofl",
|
|
"\u{1F602}": "joy",
|
|
"\u{1F642}": "slightly smiling",
|
|
"\u{1F609}": "wink",
|
|
"\u{1F60A}": "blush",
|
|
"\u{1F607}": "innocent halo",
|
|
"\u{1F970}": "smiling hearts love",
|
|
"\u{1F60D}": "heart eyes",
|
|
"\u{1F929}": "star struck",
|
|
"\u{1F60E}": "sunglasses cool",
|
|
"\u{1F913}": "nerd",
|
|
"\u{1F9D0}": "monocle",
|
|
"\u{1F60F}": "smirk",
|
|
"\u{1F914}": "thinking",
|
|
"\u{1F92B}": "shushing quiet",
|
|
"\u{1F634}": "sleeping zzz",
|
|
"\u{1F92F}": "exploding head mind blown",
|
|
"\u{1F631}": "scream fear",
|
|
"\u{1F973}": "party celebrate",
|
|
"\u{1F608}": "devil",
|
|
"\u{1F47B}": "ghost",
|
|
"\u{1F480}": "skull dead",
|
|
"\u{1F916}": "robot bot",
|
|
"\u{1F47D}": "alien ufo",
|
|
"\u{1F621}": "angry rage",
|
|
"\u{1F624}": "huffing steam",
|
|
"\u{1F62D}": "crying sob",
|
|
"\u{1F622}": "sad tear",
|
|
"\u{1F633}": "flushed embarrassed",
|
|
"\u{1F97A}": "pleading puppy",
|
|
"\u{1F62C}": "grimacing awkward",
|
|
"\u{1F92E}": "vomiting sick",
|
|
"\u{1F927}": "sneezing",
|
|
"\u{1F976}": "cold freezing",
|
|
"\u{1F975}": "hot sweating",
|
|
"\u{1F636}": "no mouth silent",
|
|
"\u{1F610}": "neutral",
|
|
"\u{1F611}": "expressionless",
|
|
"\u{1FAE0}": "melting",
|
|
"\u{1F911}": "money mouth rich",
|
|
"\u{1F917}": "hugging",
|
|
"\u{1F92D}": "giggling hand over mouth",
|
|
"\u{1FAE1}": "salute",
|
|
"\u{1FAE3}": "peeking",
|
|
"\u{1FAE2}": "open eyes hand over mouth",
|
|
"\u{1F62E}": "open mouth surprised",
|
|
"\u{1F62F}": "hushed",
|
|
"\u{1F632}": "astonished",
|
|
"\u{1F635}": "dizzy face",
|
|
"\u{1F974}": "woozy drunk",
|
|
"\u{1F637}": "mask medical",
|
|
"\u{1F912}": "thermometer sick",
|
|
"\u{1F915}": "bandage hurt",
|
|
"\u{1F910}": "zipper mouth secret",
|
|
"\u{1F636}\u200D\u{1F32B}\uFE0F": "face in clouds",
|
|
"\u{1FAE5}": "dotted line invisible",
|
|
"\u{1F925}": "lying pinocchio",
|
|
"\u{1F44D}": "thumbs up like",
|
|
"\u{1F44E}": "thumbs down dislike",
|
|
"\u{1F44B}": "wave hello",
|
|
"\u270B": "raised hand stop",
|
|
"\u{1F44F}": "clap applause",
|
|
"\u{1F91D}": "handshake deal",
|
|
"\u270C\uFE0F": "peace victory",
|
|
"\u{1F91E}": "crossed fingers luck",
|
|
"\u{1F4AA}": "muscle strong",
|
|
"\u270D\uFE0F": "writing hand",
|
|
"\u{1F64F}": "pray please thanks",
|
|
"\u{1F90C}": "pinched fingers italian",
|
|
"\u{1F90F}": "pinching small",
|
|
"\u{1F919}": "call me hang loose",
|
|
"\u{1F596}": "vulcan spock",
|
|
"\u{1FAF6}": "heart hands",
|
|
"\u{1F91F}": "love you gesture",
|
|
"\u{1F918}": "rock on horns",
|
|
"\u{1F44C}": "ok perfect",
|
|
"\u{1FAF0}": "hand with index finger and thumb crossed",
|
|
"\u2764\uFE0F": "red heart love",
|
|
"\u{1F9E1}": "orange heart",
|
|
"\u{1F49B}": "yellow heart",
|
|
"\u{1F49A}": "green heart",
|
|
"\u{1F499}": "blue heart",
|
|
"\u{1F49C}": "purple heart",
|
|
"\u{1F5A4}": "black heart",
|
|
"\u{1F90D}": "white heart",
|
|
"\u{1F494}": "broken heart",
|
|
"\u2764\uFE0F\u200D\u{1F525}": "heart on fire",
|
|
"\u2764\uFE0F\u200D\u{1FA79}": "mending heart",
|
|
"\u{1F4AF}": "hundred perfect score",
|
|
"\u{1F4A5}": "collision boom bang",
|
|
"\u{1F4AB}": "dizzy star",
|
|
"\u{1F4AC}": "speech bubble comment",
|
|
"\u{1F4AD}": "thought bubble think",
|
|
"\u{1F464}": "person silhouette user",
|
|
"\u{1F465}": "people group users",
|
|
"\u{1F476}": "baby child",
|
|
"\u{1F466}": "boy",
|
|
"\u{1F467}": "girl",
|
|
"\u{1F468}": "man",
|
|
"\u{1F469}": "woman",
|
|
"\u{1F474}": "old man elder",
|
|
"\u{1F475}": "old woman elder",
|
|
"\u{1F9D2}": "child",
|
|
"\u{1F9D3}": "older person",
|
|
"\u{1F9D4}": "bearded person",
|
|
"\u{1F9D1}\u200D\u{1F4BB}": "technologist programmer developer",
|
|
"\u{1F9D1}\u200D\u{1F393}": "student graduate",
|
|
"\u{1F9D1}\u200D\u{1F3EB}": "teacher professor",
|
|
"\u{1F9D1}\u200D\u{1F52C}": "scientist researcher",
|
|
"\u{1F9D1}\u200D\u{1F3A8}": "artist painter",
|
|
"\u{1F9D1}\u200D\u{1F680}": "astronaut space",
|
|
"\u{1F9D1}\u200D\u2695\uFE0F": "doctor health",
|
|
"\u{1F9D1}\u200D\u{1F373}": "cook chef",
|
|
"\u{1F9D1}\u200D\u{1F527}": "mechanic",
|
|
"\u{1F9D1}\u200D\u{1F3ED}": "factory worker",
|
|
"\u{1F9D1}\u200D\u{1F4BC}": "office worker",
|
|
"\u{1F9D1}\u200D\u{1F692}": "firefighter",
|
|
"\u{1F436}": "dog puppy",
|
|
"\u{1F431}": "cat kitten",
|
|
"\u{1F42D}": "mouse rat",
|
|
"\u{1F439}": "hamster",
|
|
"\u{1F430}": "rabbit bunny",
|
|
"\u{1F98A}": "fox",
|
|
"\u{1F43B}": "bear",
|
|
"\u{1F43C}": "panda",
|
|
"\u{1F428}": "koala",
|
|
"\u{1F981}": "lion king",
|
|
"\u{1F42F}": "tiger",
|
|
"\u{1F42E}": "cow",
|
|
"\u{1F437}": "pig",
|
|
"\u{1F438}": "frog",
|
|
"\u{1F435}": "monkey",
|
|
"\u{1F414}": "chicken",
|
|
"\u{1F427}": "penguin",
|
|
"\u{1F426}": "bird",
|
|
"\u{1F985}": "eagle",
|
|
"\u{1F989}": "owl wisdom",
|
|
"\u{1F98B}": "butterfly",
|
|
"\u{1F41B}": "bug insect",
|
|
"\u{1F41D}": "bee honeybee",
|
|
"\u{1F41E}": "ladybug",
|
|
"\u{1F422}": "turtle tortoise",
|
|
"\u{1F40D}": "snake",
|
|
"\u{1F98E}": "lizard",
|
|
"\u{1F419}": "octopus",
|
|
"\u{1F988}": "shark",
|
|
"\u{1F433}": "whale ocean",
|
|
"\u{1F42C}": "dolphin",
|
|
"\u{1F984}": "unicorn magic",
|
|
"\u{1F432}": "dragon",
|
|
"\u{1F434}": "horse",
|
|
"\u{1F43A}": "wolf",
|
|
"\u{1F417}": "boar",
|
|
"\u{1F43B}\u200D\u2744\uFE0F": "polar bear",
|
|
"\u{1F99D}": "raccoon",
|
|
"\u{1F9AB}": "beaver",
|
|
"\u{1F9A6}": "otter",
|
|
"\u{1F9A5}": "sloth",
|
|
"\u{1F9A8}": "skunk",
|
|
"\u{1F998}": "kangaroo",
|
|
"\u{1F9A1}": "badger",
|
|
"\u{1F43E}": "paw prints",
|
|
"\u{1F983}": "turkey",
|
|
"\u{1F413}": "rooster",
|
|
"\u{1F986}": "duck",
|
|
"\u{1F9A2}": "swan",
|
|
"\u{1F99C}": "parrot",
|
|
"\u{1FAB6}": "feather",
|
|
"\u{1F9A9}": "flamingo",
|
|
"\u{1F99A}": "peacock",
|
|
"\u{1F40A}": "crocodile",
|
|
"\u{1F409}": "dragon face",
|
|
"\u{1F995}": "sauropod dinosaur",
|
|
"\u{1F996}": "trex dinosaur",
|
|
"\u{1F40B}": "whale",
|
|
"\u{1F9AD}": "seal",
|
|
"\u{1F41F}": "fish",
|
|
"\u{1F420}": "tropical fish",
|
|
"\u{1F421}": "blowfish",
|
|
"\u{1F990}": "shrimp",
|
|
"\u{1F99E}": "lobster",
|
|
"\u{1F980}": "crab",
|
|
"\u{1F991}": "squid",
|
|
"\u{1F40C}": "snail",
|
|
"\u{1F997}": "cricket",
|
|
"\u{1FAB2}": "beetle",
|
|
"\u{1FAB3}": "cockroach",
|
|
"\u{1F577}\uFE0F": "spider",
|
|
"\u{1F578}\uFE0F": "spider web",
|
|
"\u{1F99F}": "mosquito",
|
|
"\u{1FAB0}": "fly",
|
|
"\u{1FAB1}": "worm",
|
|
"\u{1F9A0}": "microbe bacteria virus",
|
|
"\u{1F338}": "cherry blossom flower",
|
|
"\u{1F339}": "rose flower",
|
|
"\u{1F33B}": "sunflower",
|
|
"\u{1F33A}": "hibiscus flower",
|
|
"\u{1F337}": "tulip flower",
|
|
"\u{1F331}": "seedling sprout grow",
|
|
"\u{1F332}": "evergreen tree pine",
|
|
"\u{1F333}": "deciduous tree",
|
|
"\u{1F340}": "four leaf clover luck",
|
|
"\u{1F341}": "maple leaf autumn",
|
|
"\u{1F342}": "fallen leaf autumn",
|
|
"\u{1F33F}": "herb leaf green",
|
|
"\u{1F335}": "cactus desert",
|
|
"\u{1F344}": "mushroom",
|
|
"\u{1FAB4}": "potted plant",
|
|
"\u{1F33E}": "rice sheaf",
|
|
"\u{1FABB}": "hyacinth",
|
|
"\u{1FAB7}": "lotus",
|
|
"\u{1F34E}": "apple red fruit",
|
|
"\u{1F34A}": "orange tangerine fruit",
|
|
"\u{1F34B}": "lemon citrus",
|
|
"\u{1F347}": "grapes fruit",
|
|
"\u{1F353}": "strawberry fruit",
|
|
"\u{1F352}": "cherry fruit",
|
|
"\u{1F351}": "peach fruit",
|
|
"\u{1F34C}": "banana fruit",
|
|
"\u{1F349}": "watermelon fruit",
|
|
"\u{1F355}": "pizza food",
|
|
"\u{1F354}": "hamburger burger food",
|
|
"\u{1F35F}": "fries food",
|
|
"\u{1F32E}": "taco food",
|
|
"\u{1F370}": "cake dessert birthday",
|
|
"\u{1F369}": "donut doughnut dessert",
|
|
"\u{1F36A}": "cookie dessert",
|
|
"\u{1F36B}": "chocolate bar candy",
|
|
"\u{1F951}": "avocado",
|
|
"\u{1F955}": "carrot",
|
|
"\u{1F33D}": "corn",
|
|
"\u{1F966}": "broccoli",
|
|
"\u{1F9C4}": "garlic",
|
|
"\u{1F9C5}": "onion",
|
|
"\u{1F952}": "cucumber",
|
|
"\u{1FAD1}": "bell pepper",
|
|
"\u{1F950}": "croissant",
|
|
"\u{1F956}": "baguette bread",
|
|
"\u{1F968}": "pretzel",
|
|
"\u{1F9C0}": "cheese",
|
|
"\u{1F969}": "meat steak",
|
|
"\u{1F357}": "poultry chicken leg",
|
|
"\u{1F32D}": "hot dog",
|
|
"\u{1F96A}": "sandwich",
|
|
"\u{1F363}": "sushi",
|
|
"\u{1F35C}": "ramen noodles",
|
|
"\u{1F35D}": "pasta spaghetti",
|
|
"\u{1F35B}": "curry rice",
|
|
"\u{1F372}": "pot stew",
|
|
"\u{1F957}": "salad green",
|
|
"\u{1F37F}": "popcorn",
|
|
"\u{1F9C1}": "cupcake",
|
|
"\u{1F366}": "ice cream",
|
|
"\u{1F367}": "shaved ice",
|
|
"\u{1F368}": "ice cream sundae",
|
|
"\u{1F382}": "birthday cake",
|
|
"\u{1F36E}": "custard pudding",
|
|
"\u{1F36F}": "honey pot",
|
|
"\u2615": "coffee hot beverage",
|
|
"\u{1F375}": "tea green",
|
|
"\u{1F37A}": "beer mug drink",
|
|
"\u{1F377}": "wine glass drink",
|
|
"\u{1F964}": "cup straw beverage drink",
|
|
"\u{1F376}": "sake",
|
|
"\u{1F37E}": "champagne bottle",
|
|
"\u{1F942}": "clinking glasses cheers",
|
|
"\u{1F943}": "tumbler whiskey",
|
|
"\u{1FAD7}": "pouring liquid",
|
|
"\u{1F9CB}": "bubble tea boba",
|
|
"\u{1F9C3}": "juice box",
|
|
"\u{1F9CA}": "ice cube",
|
|
"\u{1F3E0}": "house home",
|
|
"\u{1F3E1}": "house garden home",
|
|
"\u{1F3E2}": "office building",
|
|
"\u{1F3EB}": "school building",
|
|
"\u{1F3E5}": "hospital building",
|
|
"\u{1F3F0}": "castle",
|
|
"\u{1F5FC}": "tower",
|
|
"\u{1F5FD}": "statue liberty",
|
|
"\u26EA": "church religion",
|
|
"\u{1F54C}": "mosque religion",
|
|
"\u26E9\uFE0F": "shinto shrine torii",
|
|
"\u{1F30D}": "earth globe world europe africa",
|
|
"\u{1F30E}": "earth globe world americas",
|
|
"\u{1F30F}": "earth globe world asia",
|
|
"\u{1F5FA}\uFE0F": "world map",
|
|
"\u{1F3D4}\uFE0F": "mountain snow",
|
|
"\u26F0\uFE0F": "mountain",
|
|
"\u{1F30B}": "volcano",
|
|
"\u{1F3DD}\uFE0F": "desert island",
|
|
"\u{1F3D6}\uFE0F": "beach umbrella",
|
|
"\u{1F697}": "car automobile",
|
|
"\u{1F695}": "taxi cab",
|
|
"\u{1F68C}": "bus",
|
|
"\u{1F680}": "rocket launch space",
|
|
"\u2708\uFE0F": "airplane plane flight travel",
|
|
"\u{1F681}": "helicopter",
|
|
"\u{1F6A2}": "ship boat",
|
|
"\u{1F682}": "train locomotive",
|
|
"\u{1F6B2}": "bicycle bike",
|
|
"\u26F5": "sailboat",
|
|
"\u{1F6F8}": "flying saucer ufo",
|
|
"\u{1F683}": "railway car",
|
|
"\u{1F684}": "high speed train",
|
|
"\u{1F685}": "bullet train",
|
|
"\u{1F686}": "train",
|
|
"\u{1F687}": "metro subway",
|
|
"\u{1F688}": "light rail",
|
|
"\u{1F689}": "station",
|
|
"\u{1F68A}": "tram",
|
|
"\u{1F69D}": "monorail",
|
|
"\u{1F69E}": "mountain railway",
|
|
"\u{1F68B}": "tram car",
|
|
"\u{1F68D}": "bus front",
|
|
"\u{1F68E}": "trolleybus",
|
|
"\u{1F690}": "minibus",
|
|
"\u{1F691}": "ambulance",
|
|
"\u{1F692}": "fire engine",
|
|
"\u{1F693}": "police car",
|
|
"\u{1F694}": "police car oncoming",
|
|
"\u{1F696}": "taxi oncoming",
|
|
"\u{1F698}": "automobile oncoming",
|
|
"\u{1F699}": "suv sport utility",
|
|
"\u{1F6FB}": "pickup truck",
|
|
"\u{1F69A}": "delivery truck",
|
|
"\u{1F69B}": "articulated lorry",
|
|
"\u{1F69C}": "tractor farm",
|
|
"\u{1F6F5}": "motor scooter",
|
|
"\u{1F3CD}\uFE0F": "motorcycle racing",
|
|
"\u{1F6FA}": "auto rickshaw",
|
|
"\u{1F6A0}": "mountain cableway",
|
|
"\u{1F6A1}": "aerial tramway",
|
|
"\u{1F6F6}": "canoe kayak",
|
|
"\u{1F6A4}": "speedboat",
|
|
"\u{1F6F3}\uFE0F": "passenger ship cruise",
|
|
"\u26F4\uFE0F": "ferry",
|
|
"\u{1F6E5}\uFE0F": "motor boat",
|
|
"\u{1F6E9}\uFE0F": "small airplane",
|
|
"\u{1FA82}": "parachute",
|
|
"\u{1F4BA}": "seat",
|
|
"\u{1F6F0}\uFE0F": "satellite",
|
|
"\u231A": "watch time clock",
|
|
"\u{1F4F1}": "phone mobile smartphone",
|
|
"\u{1F4BB}": "laptop computer",
|
|
"\u{1F5A5}\uFE0F": "desktop computer monitor",
|
|
"\u2328\uFE0F": "keyboard typing",
|
|
"\u{1F5B1}\uFE0F": "mouse computer",
|
|
"\u{1F5A8}\uFE0F": "printer",
|
|
"\u{1F4BE}": "floppy disk save",
|
|
"\u{1F4BF}": "cd optical disk",
|
|
"\u{1F4C0}": "dvd disk",
|
|
"\u{1F3AE}": "gamepad controller game",
|
|
"\u{1F579}\uFE0F": "joystick game",
|
|
"\u{1F50B}": "battery power",
|
|
"\u{1F4A1}": "light bulb idea",
|
|
"\u{1F526}": "flashlight torch",
|
|
"\u{1F4F7}": "camera photo",
|
|
"\u{1F3A5}": "movie camera video film",
|
|
"\u{1F4F9}": "video camera",
|
|
"\u{1F50D}": "magnifying glass search left",
|
|
"\u{1F50E}": "magnifying glass search right",
|
|
"\u{1F52C}": "microscope science research",
|
|
"\u{1F52D}": "telescope astronomy",
|
|
"\u{1F4E1}": "satellite antenna",
|
|
"\u{1F511}": "key password",
|
|
"\u{1F5DD}\uFE0F": "old key vintage",
|
|
"\u{1F512}": "lock locked security",
|
|
"\u{1F513}": "unlock unlocked open",
|
|
"\u{1F527}": "wrench tool fix",
|
|
"\u{1F528}": "hammer tool build",
|
|
"\u2699\uFE0F": "gear settings cog",
|
|
"\u{1F9F2}": "magnet",
|
|
"\u26A1": "lightning bolt zap electricity",
|
|
"\u{1F9EA}": "test tube experiment",
|
|
"\u{1F48A}": "pill medicine",
|
|
"\u{1FA7A}": "stethoscope medical doctor",
|
|
"\u{1F9EC}": "dna genetics",
|
|
"\u{1FA9B}": "screwdriver",
|
|
"\u{1FA9A}": "saw carpentry",
|
|
"\u{1FA9D}": "hook",
|
|
"\u{1F9F0}": "toolbox",
|
|
"\u{1FAA4}": "mousetrap",
|
|
"\u2697\uFE0F": "alembic chemistry",
|
|
"\u{1FA7B}": "x-ray",
|
|
"\u{1FA78}": "drop of blood",
|
|
"\u{1F4DD}": "memo note write pencil",
|
|
"\u{1F4CB}": "clipboard",
|
|
"\u{1F4CC}": "pushpin pin",
|
|
"\u{1F4CE}": "paperclip attach",
|
|
"\u270F\uFE0F": "pencil write edit",
|
|
"\u{1F58A}\uFE0F": "pen write",
|
|
"\u{1F58B}\uFE0F": "fountain pen write",
|
|
"\u{1F4D0}": "triangular ruler",
|
|
"\u{1F4CF}": "straight ruler",
|
|
"\u{1F4D5}": "book red closed",
|
|
"\u{1F4D7}": "book green",
|
|
"\u{1F4D8}": "book blue",
|
|
"\u{1F4D9}": "book orange",
|
|
"\u{1F4DA}": "books stack library",
|
|
"\u{1F4D6}": "open book read",
|
|
"\u{1F4D3}": "notebook",
|
|
"\u{1F4D2}": "ledger notebook",
|
|
"\u{1F4C4}": "page document file",
|
|
"\u{1F4C3}": "page curl document",
|
|
"\u{1F4D1}": "bookmark tabs",
|
|
"\u{1F5C2}\uFE0F": "card index dividers files",
|
|
"\u{1F4C1}": "folder file",
|
|
"\u{1F4C2}": "open folder file",
|
|
"\u{1F5C3}\uFE0F": "card file box archive",
|
|
"\u{1F5C4}\uFE0F": "file cabinet storage",
|
|
"\u{1F5D1}\uFE0F": "wastebasket trash delete",
|
|
"\u{1F4CA}": "bar chart graph statistics",
|
|
"\u{1F4C8}": "chart increasing up trend",
|
|
"\u{1F4C9}": "chart decreasing down trend",
|
|
"\u{1F4C6}": "calendar date",
|
|
"\u{1F4C5}": "calendar",
|
|
"\u{1F5D3}\uFE0F": "calendar spiral date",
|
|
"\u{1F4EC}": "mailbox mail",
|
|
"\u{1F4E7}": "email e-mail",
|
|
"\u{1F4E9}": "envelope arrow email incoming",
|
|
"\u{1F4E4}": "outbox tray upload",
|
|
"\u{1F4E5}": "inbox tray download",
|
|
"\u{1F4E6}": "package box",
|
|
"\u{1F4EA}": "mailbox closed",
|
|
"\u{1F4EB}": "mailbox raised flag",
|
|
"\u{1F4EE}": "postbox",
|
|
"\u{1F3F7}\uFE0F": "label tag price",
|
|
"\u2B50": "star favorite",
|
|
"\u{1F31F}": "glowing star shine",
|
|
"\u2728": "sparkles shine magic",
|
|
"\u{1F525}": "fire hot flame trending",
|
|
"\u{1F4A7}": "water droplet",
|
|
"\u{1F30A}": "wave ocean water",
|
|
"\u2600\uFE0F": "sun sunny bright",
|
|
"\u{1F319}": "moon crescent night",
|
|
"\u{1F308}": "rainbow",
|
|
"\u2601\uFE0F": "cloud",
|
|
"\u2744\uFE0F": "snowflake cold winter",
|
|
"\u{1F32A}\uFE0F": "tornado",
|
|
"\u{1F324}\uFE0F": "sun behind small cloud",
|
|
"\u26C8\uFE0F": "thunder cloud rain",
|
|
"\u{1F327}\uFE0F": "cloud rain",
|
|
"\u{1F328}\uFE0F": "cloud snow",
|
|
"\u2614": "umbrella rain",
|
|
"\u{1F3AF}": "target bullseye goal",
|
|
"\u{1F3C6}": "trophy award winner cup",
|
|
"\u{1F947}": "gold medal first",
|
|
"\u{1F948}": "silver medal second",
|
|
"\u{1F949}": "bronze medal third",
|
|
"\u{1F3C5}": "medal sports",
|
|
"\u{1F3AA}": "circus tent",
|
|
"\u{1F3A8}": "palette art paint color",
|
|
"\u{1F3AD}": "performing arts theater masks",
|
|
"\u{1F3AC}": "clapper board movie film",
|
|
"\u{1F3A4}": "microphone karaoke",
|
|
"\u{1F3A7}": "headphones music audio",
|
|
"\u{1F3B5}": "music note",
|
|
"\u{1F3B6}": "music notes",
|
|
"\u{1F3B9}": "piano musical keyboard",
|
|
"\u{1F3B8}": "guitar music",
|
|
"\u{1F3BA}": "trumpet music",
|
|
"\u{1F941}": "drum music",
|
|
"\u{1F3BB}": "violin",
|
|
"\u{1FA97}": "accordion",
|
|
"\u{1F3B7}": "saxophone",
|
|
"\u{1F3B2}": "dice game random",
|
|
"\u265F\uFE0F": "chess pawn strategy",
|
|
"\u{1F9E9}": "puzzle piece jigsaw",
|
|
"\u{1F381}": "gift present wrapped",
|
|
"\u{1F380}": "ribbon bow",
|
|
"\u{1F388}": "balloon party",
|
|
"\u{1F389}": "party popper celebrate tada",
|
|
"\u{1F38A}": "confetti ball celebrate",
|
|
"\u{1F397}\uFE0F": "reminder ribbon awareness",
|
|
"\u26BD": "soccer football",
|
|
"\u{1F3C0}": "basketball",
|
|
"\u{1F3C8}": "american football",
|
|
"\u26BE": "baseball",
|
|
"\u{1F3BE}": "tennis",
|
|
"\u{1F3D0}": "volleyball",
|
|
"\u{1F3C9}": "rugby",
|
|
"\u{1F3B1}": "billiards pool",
|
|
"\u{1F3D3}": "table tennis ping pong",
|
|
"\u{1F3F8}": "badminton",
|
|
"\u{1F94A}": "boxing glove",
|
|
"\u{1F94B}": "martial arts",
|
|
"\u{1F3CB}\uFE0F": "weight lifting",
|
|
"\u{1F938}": "cartwheeling gymnastics",
|
|
"\u26F7\uFE0F": "skier",
|
|
"\u{1F3C2}": "snowboarder",
|
|
"\u{1F3C4}": "surfer",
|
|
"\u{1F6A3}": "rowing",
|
|
"\u{1F3CA}": "swimming",
|
|
"\u{1F9D7}": "climbing",
|
|
"\u{1F6B4}": "cycling bicyclist",
|
|
"\u{1F9D8}": "yoga meditation",
|
|
"\u{1F3A3}": "fishing",
|
|
"\u{1FA81}": "kite",
|
|
"\u2705": "check mark done complete",
|
|
"\u274C": "cross mark error wrong",
|
|
"\u26A0\uFE0F": "warning alert caution",
|
|
"\u{1F6AB}": "prohibited forbidden no",
|
|
"\u2753": "question mark",
|
|
"\u2757": "exclamation mark important",
|
|
"\u203C\uFE0F": "double exclamation",
|
|
"\u2049\uFE0F": "exclamation question",
|
|
"\u{1F534}": "red circle dot",
|
|
"\u{1F7E0}": "orange circle dot",
|
|
"\u{1F7E1}": "yellow circle dot",
|
|
"\u{1F7E2}": "green circle dot",
|
|
"\u{1F535}": "blue circle dot",
|
|
"\u{1F7E3}": "purple circle dot",
|
|
"\u26AB": "black circle dot",
|
|
"\u26AA": "white circle dot",
|
|
"\u{1F7E4}": "brown circle dot",
|
|
"\u{1F7E5}": "red square",
|
|
"\u{1F7E7}": "orange square",
|
|
"\u{1F7E8}": "yellow square",
|
|
"\u{1F7E9}": "green square",
|
|
"\u{1F7E6}": "blue square",
|
|
"\u{1F7EA}": "purple square",
|
|
"\u2B1B": "black large square",
|
|
"\u2B1C": "white large square",
|
|
"\u{1F7EB}": "brown square",
|
|
"\u2B06\uFE0F": "arrow up",
|
|
"\u2B07\uFE0F": "arrow down",
|
|
"\u2B05\uFE0F": "arrow left",
|
|
"\u27A1\uFE0F": "arrow right",
|
|
"\u21A9\uFE0F": "arrow return back",
|
|
"\u{1F504}": "arrows counterclockwise refresh",
|
|
"\u{1F500}": "shuffle twisted arrows",
|
|
"\u{1F501}": "repeat loop",
|
|
"\u25B6\uFE0F": "play button",
|
|
"\u23F8\uFE0F": "pause button",
|
|
"\u23F9\uFE0F": "stop button",
|
|
"\u23E9": "fast forward",
|
|
"\u23EA": "rewind",
|
|
"\u{1F3F3}\uFE0F": "white flag surrender",
|
|
"\u{1F3F4}": "black flag",
|
|
"\u{1F6A9}": "triangular flag red",
|
|
"\u{1F3C1}": "checkered flag race finish",
|
|
"\u267B\uFE0F": "recycling recycle",
|
|
"\u{1F517}": "link chain",
|
|
"\u{1F4E2}": "loudspeaker announce",
|
|
"\u{1F514}": "bell notification",
|
|
"\u{1F515}": "bell slash no notification mute",
|
|
"\u{1F6E1}\uFE0F": "shield protect security",
|
|
"\u2694\uFE0F": "crossed swords fight",
|
|
"\u{1F3F9}": "bow arrow archery",
|
|
"\u{1F48E}": "gem diamond jewel",
|
|
"\u{1F451}": "crown king queen royal",
|
|
"\u{1F393}": "graduation cap education",
|
|
"\u{1F9E0}": "brain mind think intelligence",
|
|
"\u{1F441}\uFE0F": "eye see look vision",
|
|
"\u{1F440}": "eyes see look",
|
|
"\u{1FAC0}": "anatomical heart organ",
|
|
"\u{1F9B7}": "tooth dental",
|
|
"\u{1F9B4}": "bone skeleton",
|
|
"\u{1F48D}": "ring wedding diamond",
|
|
"\u{1F453}": "glasses eyeglasses",
|
|
"\u{1F576}\uFE0F": "sunglasses dark",
|
|
"\u{1F9F3}": "luggage suitcase travel",
|
|
"\u{1F392}": "backpack school bag",
|
|
"\u{1F6D2}": "shopping cart",
|
|
"\u23F0": "alarm clock time",
|
|
"\u23F3": "hourglass time sand",
|
|
"\u{1F9ED}": "compass navigation direction",
|
|
"\u{1F4CD}": "pin location map",
|
|
"\u{1F510}": "locked key secure",
|
|
"\u{1F56F}\uFE0F": "candle light",
|
|
"\u{1F4B0}": "money bag",
|
|
"\u{1F4B5}": "dollar banknote",
|
|
"\u{1F4B3}": "credit card",
|
|
"\u{1F9FE}": "receipt",
|
|
"\u{1F4B8}": "money with wings flying",
|
|
"\u{1FA99}": "coin",
|
|
"\u{1F3B0}": "slot machine jackpot",
|
|
"\u{1FA84}": "magic wand",
|
|
"\u{1F52E}": "crystal ball fortune",
|
|
"\u{1F9FF}": "nazar amulet evil eye",
|
|
"\u{1FAAC}": "hamsa",
|
|
"\u267E\uFE0F": "infinity",
|
|
"\u{1F3B4}": "flower playing cards",
|
|
"\u{1F004}": "mahjong",
|
|
"\u{1F0CF}": "joker card",
|
|
"\u{1F6C1}": "bathtub",
|
|
"\u{1F6BF}": "shower",
|
|
"\u{1FAA5}": "toothbrush",
|
|
"\u{1F9F4}": "lotion bottle",
|
|
"\u{1F9F7}": "safety pin",
|
|
"\u{1F9F9}": "broom",
|
|
"\u{1FAA3}": "bucket",
|
|
"\u{1F9FA}": "basket",
|
|
"\u{1F9FB}": "toilet paper roll",
|
|
"\u{1F6BD}": "toilet",
|
|
"\u{1FA9E}": "mirror",
|
|
"\u{1FA9F}": "window",
|
|
"\u{1F6CF}\uFE0F": "bed",
|
|
"\u{1F6CB}\uFE0F": "couch lamp",
|
|
"\u{1FA91}": "chair",
|
|
"\u{1F6AA}": "door",
|
|
"\u{1F9EF}": "fire extinguisher",
|
|
"\u{1F488}": "barber pole",
|
|
"\u{1F3FA}": "amphora vase",
|
|
// Additional smileys and faces
|
|
"\u{1F972}": "smiling tear happy sad",
|
|
"\u{1FAE4}": "face diagonal mouth",
|
|
"\u{1FAE8}": "shaking face",
|
|
"\u{1FAE9}": "face with bags under eyes tired",
|
|
"\u{1F60B}": "yum delicious savoring",
|
|
"\u{1F61C}": "winking tongue playful",
|
|
"\u{1F92A}": "zany crazy",
|
|
"\u{1F61D}": "squinting tongue",
|
|
"\u{1F61B}": "tongue out",
|
|
"\u{1F978}": "disguised face",
|
|
"\u{1F612}": "unamused",
|
|
"\u{1F61E}": "disappointed sad",
|
|
"\u{1F614}": "pensive sad",
|
|
"\u{1F61F}": "worried",
|
|
"\u{1F615}": "confused",
|
|
"\u{1F641}": "slightly frowning",
|
|
"\u{1F623}": "persevering",
|
|
"\u{1F616}": "confounded",
|
|
"\u{1F62B}": "tired weary",
|
|
"\u{1F629}": "weary exhausted",
|
|
"\u{1F971}": "yawning bored",
|
|
"\u{1F92C}": "cursing swearing angry",
|
|
"\u{1F620}": "angry",
|
|
"\u{1FAE7}": "bubbles soap",
|
|
"\u{1F4A8}": "dashing away wind fast",
|
|
"\u{1F4A6}": "sweat droplets splashing",
|
|
"\u{1F4A4}": "zzz sleeping",
|
|
"\u{1F573}\uFE0F": "hole",
|
|
"\u{1F4A3}": "bomb explosive",
|
|
"\u{1F5E8}\uFE0F": "left speech bubble",
|
|
"\u{1F5EF}\uFE0F": "right anger bubble",
|
|
"\u{1F4A2}": "anger symbol",
|
|
// More hand gestures
|
|
"\u{1F590}\uFE0F": "hand with fingers splayed",
|
|
"\u{1F91A}": "raised back of hand",
|
|
"\u{1F44A}": "fist bump punch",
|
|
"\u270A": "raised fist power",
|
|
"\u{1FAF3}": "palm down hand",
|
|
"\u{1FAF4}": "palm up hand",
|
|
"\u{1FAF2}": "leftwards hand",
|
|
"\u{1FAF1}": "rightwards hand",
|
|
"\u{1F448}": "pointing left",
|
|
"\u{1F449}": "pointing right",
|
|
"\u{1F446}": "pointing up",
|
|
"\u{1F447}": "pointing down",
|
|
"\u261D\uFE0F": "index pointing up",
|
|
"\u{1F595}": "middle finger",
|
|
"\u{1FAF5}": "index pointing at viewer",
|
|
"\u{1F932}": "palms up together",
|
|
"\u{1F64C}": "raising hands hooray",
|
|
"\u{1F933}": "selfie",
|
|
// Body and people
|
|
"\u{1F9B6}": "foot",
|
|
"\u{1F9B5}": "leg",
|
|
"\u{1FAC1}": "lungs breathing",
|
|
"\u{1F9BB}": "ear hearing",
|
|
"\u{1F442}": "ear",
|
|
"\u{1F443}": "nose smell",
|
|
"\u{1F9BF}": "mechanical leg prosthetic",
|
|
"\u{1F9BE}": "mechanical arm prosthetic",
|
|
"\u{1F485}": "nail polish",
|
|
"\u{1F937}": "shrug",
|
|
"\u{1F926}": "facepalm",
|
|
"\u{1F646}": "ok gesture person",
|
|
"\u{1F645}": "no good person",
|
|
"\u{1F487}": "haircut",
|
|
"\u{1F486}": "massage",
|
|
"\u{1F9D6}": "person in steamy room sauna",
|
|
"\u{1F6C0}": "person taking bath",
|
|
"\u{1F9D1}\u200D\u{1F9AF}": "person with white cane blind",
|
|
"\u{1F9D1}\u200D\u{1F9BC}": "person in motorized wheelchair",
|
|
"\u{1F9D1}\u200D\u{1F9BD}": "person in manual wheelchair",
|
|
"\u{1F9D9}": "mage wizard",
|
|
"\u{1F9DA}": "fairy",
|
|
"\u{1F9DB}": "vampire",
|
|
"\u{1F9DC}": "merperson",
|
|
"\u{1F9DD}": "elf",
|
|
"\u{1F9DE}": "genie",
|
|
"\u{1F9DF}": "zombie",
|
|
"\u{1F9D1}\u200D\u{1F91D}\u200D\u{1F9D1}": "people holding hands",
|
|
"\u{1F46B}": "man woman holding hands couple",
|
|
"\u{1F46C}": "men holding hands",
|
|
"\u{1F46D}": "women holding hands",
|
|
"\u{1F48F}": "kiss couple",
|
|
"\u{1F491}": "couple with heart love",
|
|
"\u{1F46A}": "family",
|
|
"\u{1F9D1}\u200D\u{1F9D1}\u200D\u{1F9D2}": "family parents child",
|
|
"\u{1FAC2}": "people hugging embrace",
|
|
// More animals
|
|
"\u{1F400}": "rat",
|
|
"\u{1F401}": "mouse small",
|
|
"\u{1F402}": "ox",
|
|
"\u{1F403}": "water buffalo",
|
|
"\u{1F404}": "cow dairy",
|
|
"\u{1F405}": "tiger full",
|
|
"\u{1F406}": "leopard",
|
|
"\u{1F407}": "rabbit full",
|
|
"\u{1F408}": "cat full",
|
|
"\u{1F408}\u200D\u2B1B": "black cat",
|
|
"\u{1F429}": "poodle dog",
|
|
"\u{1F9AE}": "guide dog",
|
|
"\u{1F415}\u200D\u{1F9BA}": "service dog",
|
|
"\u{1F415}": "dog full",
|
|
"\u{1F40E}": "horse racing",
|
|
"\u{1FACE}": "moose elk",
|
|
"\u{1FACF}": "donkey",
|
|
"\u{1F98C}": "deer",
|
|
"\u{1F9AC}": "bison buffalo",
|
|
"\u{1F9A3}": "mammoth woolly",
|
|
"\u{1F98F}": "rhinoceros",
|
|
"\u{1F99B}": "hippopotamus hippo",
|
|
"\u{1F42A}": "camel one hump",
|
|
"\u{1F42B}": "two hump camel",
|
|
"\u{1F992}": "giraffe",
|
|
"\u{1F418}": "elephant",
|
|
"\u{1F40F}": "ram sheep",
|
|
"\u{1F411}": "ewe sheep",
|
|
"\u{1F410}": "goat",
|
|
"\u{1F999}": "llama alpaca",
|
|
"\u{1F994}": "hedgehog",
|
|
"\u{1F43F}\uFE0F": "chipmunk",
|
|
"\u{1F426}\u200D\u2B1B": "black bird crow raven",
|
|
"\u{1F9A4}": "dodo extinct",
|
|
"\u{1FABF}": "goose",
|
|
"\u{1F9A7}": "orangutan",
|
|
"\u{1F412}": "monkey full",
|
|
"\u{1F98D}": "gorilla ape",
|
|
"\u{1F416}": "pig full",
|
|
"\u{1FAB8}": "coral reef",
|
|
"\u{1FABC}": "jellyfish",
|
|
"\u{1F41A}": "shell seashell",
|
|
"\u{1F41C}": "ant",
|
|
"\u{1F982}": "scorpion",
|
|
// More plants and nature
|
|
"\u{1F33C}": "blossom flower",
|
|
"\u{1F490}": "bouquet flowers",
|
|
"\u{1F330}": "chestnut nut",
|
|
"\u{1FAD8}": "beans",
|
|
"\u{1FAB9}": "empty nest",
|
|
"\u{1FABA}": "nest with eggs",
|
|
"\u{1F311}": "new moon dark",
|
|
"\u{1F312}": "waxing crescent moon",
|
|
"\u{1F313}": "first quarter moon",
|
|
"\u{1F314}": "waxing gibbous moon",
|
|
"\u{1F315}": "full moon",
|
|
"\u{1F316}": "waning gibbous moon",
|
|
"\u{1F317}": "last quarter moon",
|
|
"\u{1F318}": "waning crescent moon",
|
|
"\u{1F31A}": "new moon face",
|
|
"\u{1F31B}": "first quarter moon face",
|
|
"\u{1F31C}": "last quarter moon face",
|
|
"\u{1F31D}": "full moon face",
|
|
"\u{1F31E}": "sun with face",
|
|
"\u{1FA90}": "ringed planet saturn",
|
|
"\u{1F320}": "shooting star",
|
|
"\u{1F30C}": "milky way galaxy night sky",
|
|
"\u{1F32B}\uFE0F": "fog",
|
|
"\u{1F32C}\uFE0F": "wind face blowing",
|
|
"\u{1F300}": "cyclone hurricane typhoon spiral",
|
|
"\u{1F301}": "foggy",
|
|
// More food and drink
|
|
"\u{1F360}": "sweet potato roasted",
|
|
"\u{1F954}": "potato",
|
|
"\u{1F95A}": "egg",
|
|
"\u{1F373}": "cooking egg fried",
|
|
"\u{1F953}": "bacon",
|
|
"\u{1F95E}": "pancakes",
|
|
"\u{1F9C7}": "waffle",
|
|
"\u{1F96F}": "bagel",
|
|
"\u{1FAD3}": "flatbread",
|
|
"\u{1FAD4}": "tamale",
|
|
"\u{1F959}": "stuffed flatbread pita",
|
|
"\u{1F9C6}": "falafel",
|
|
"\u{1F958}": "shallow pan paella",
|
|
"\u{1FAD5}": "fondue",
|
|
"\u{1F96B}": "canned food",
|
|
"\u{1F371}": "bento box japanese lunch",
|
|
"\u{1F358}": "rice cracker",
|
|
"\u{1F359}": "rice ball onigiri",
|
|
"\u{1F35A}": "cooked rice",
|
|
"\u{1F362}": "oden skewer",
|
|
"\u{1F361}": "dango",
|
|
"\u{1F95F}": "dumpling",
|
|
"\u{1F960}": "fortune cookie",
|
|
"\u{1F961}": "takeout box",
|
|
"\u{1F967}": "pie",
|
|
"\u{1F36C}": "candy sweet",
|
|
"\u{1F36D}": "lollipop candy",
|
|
"\u{1FAD6}": "teapot",
|
|
"\u{1F37C}": "baby bottle milk",
|
|
"\u{1F95B}": "glass of milk",
|
|
"\u{1FAD9}": "jar container",
|
|
"\u{1F37D}\uFE0F": "plate cutlery fork knife",
|
|
"\u{1F962}": "chopsticks",
|
|
"\u{1F944}": "spoon",
|
|
"\u{1F52A}": "kitchen knife hocho",
|
|
// More buildings and places
|
|
"\u{1F3D7}\uFE0F": "construction building crane",
|
|
"\u{1F3D8}\uFE0F": "houses neighborhood",
|
|
"\u{1F3DA}\uFE0F": "derelict house abandoned",
|
|
"\u{1F3DB}\uFE0F": "classical building columns",
|
|
"\u{1F3D9}\uFE0F": "cityscape skyline",
|
|
"\u{1F303}": "night with stars city",
|
|
"\u{1F306}": "cityscape at dusk sunset",
|
|
"\u{1F307}": "sunset city",
|
|
"\u{1F305}": "sunrise morning",
|
|
"\u{1F304}": "sunrise over mountains",
|
|
"\u{1F3DC}\uFE0F": "desert",
|
|
"\u{1F3DE}\uFE0F": "national park nature",
|
|
"\u{1F3A0}": "carousel horse merry go round",
|
|
"\u{1F3A1}": "ferris wheel",
|
|
"\u{1F3A2}": "roller coaster",
|
|
"\u{1F3DF}\uFE0F": "stadium",
|
|
"\u{1F54D}": "synagogue jewish",
|
|
"\u{1F6D5}": "hindu temple",
|
|
"\u{1F54B}": "kaaba mecca",
|
|
"\u26F2": "fountain water",
|
|
"\u26FA": "tent camping",
|
|
"\u{1F3D5}\uFE0F": "camping tent nature",
|
|
// More objects
|
|
"\u{1FA94}": "diya lamp oil",
|
|
"\u{1F4FA}": "television tv monitor",
|
|
"\u{1F4FB}": "radio",
|
|
"\u{1F4E0}": "fax machine",
|
|
"\u{1F50A}": "speaker loud volume high",
|
|
"\u{1F509}": "speaker medium volume",
|
|
"\u{1F508}": "speaker low volume",
|
|
"\u{1F507}": "muted speaker volume off",
|
|
"\u{1F4E3}": "megaphone cheering",
|
|
"\u{1F399}\uFE0F": "studio microphone podcast",
|
|
"\u{1F39A}\uFE0F": "level slider",
|
|
"\u{1F39B}\uFE0F": "control knobs",
|
|
"\u{1F9EE}": "abacus math calculate",
|
|
"\u{1F5A9}": "calculator",
|
|
"\u{1F4F8}": "camera flash photo",
|
|
"\u{1F4FD}\uFE0F": "film projector",
|
|
"\u{1F39E}\uFE0F": "film frames",
|
|
"\u{1F4FC}": "videocassette vhs tape",
|
|
"\u{1F50C}": "electric plug power",
|
|
"\u{1FAAB}": "low battery",
|
|
"\u{1F4B6}": "euro banknote",
|
|
"\u{1F4B7}": "pound banknote",
|
|
"\u{1F4B4}": "yen banknote",
|
|
"\u{1FAAA}": "identification card id",
|
|
"\u{1F9EB}": "petri dish biology",
|
|
"\u{1F6D7}": "elevator lift",
|
|
"\u{1FA9C}": "ladder steps",
|
|
"\u2696\uFE0F": "balance scale justice",
|
|
"\u26D3\uFE0F": "chains linked",
|
|
"\u2693": "anchor nautical ship",
|
|
"\u{1F5FF}": "moai easter island statue",
|
|
// Zodiac and symbols
|
|
"\u2648": "aries zodiac",
|
|
"\u2649": "taurus zodiac",
|
|
"\u264A": "gemini zodiac",
|
|
"\u264B": "cancer zodiac",
|
|
"\u264C": "leo zodiac",
|
|
"\u264D": "virgo zodiac",
|
|
"\u264E": "libra zodiac",
|
|
"\u264F": "scorpio zodiac",
|
|
"\u2650": "sagittarius zodiac",
|
|
"\u2651": "capricorn zodiac",
|
|
"\u2652": "aquarius zodiac",
|
|
"\u2653": "pisces zodiac",
|
|
"\u26CE": "ophiuchus zodiac",
|
|
// Country flags
|
|
"\u{1F1FA}\u{1F1F8}": "flag usa america united states",
|
|
"\u{1F1EC}\u{1F1E7}": "flag uk britain england",
|
|
"\u{1F1EB}\u{1F1F7}": "flag france french",
|
|
"\u{1F1E9}\u{1F1EA}": "flag germany german",
|
|
"\u{1F1EE}\u{1F1F9}": "flag italy italian",
|
|
"\u{1F1EA}\u{1F1F8}": "flag spain spanish",
|
|
"\u{1F1F7}\u{1F1FA}": "flag russia russian",
|
|
"\u{1F1E8}\u{1F1F3}": "flag china chinese",
|
|
"\u{1F1EF}\u{1F1F5}": "flag japan japanese",
|
|
"\u{1F1F0}\u{1F1F7}": "flag korea south korean",
|
|
"\u{1F1E7}\u{1F1F7}": "flag brazil brazilian",
|
|
"\u{1F1EE}\u{1F1F3}": "flag india indian",
|
|
"\u{1F1E8}\u{1F1E6}": "flag canada canadian",
|
|
"\u{1F1E6}\u{1F1FA}": "flag australia australian",
|
|
"\u{1F1F2}\u{1F1FD}": "flag mexico mexican",
|
|
"\u{1F1E6}\u{1F1F7}": "flag argentina",
|
|
"\u{1F1F9}\u{1F1F7}": "flag turkey turkish",
|
|
"\u{1F1F8}\u{1F1E6}": "flag saudi arabia",
|
|
"\u{1F1F3}\u{1F1F1}": "flag netherlands dutch",
|
|
"\u{1F1F8}\u{1F1EA}": "flag sweden swedish",
|
|
"\u{1F1F3}\u{1F1F4}": "flag norway norwegian",
|
|
"\u{1F1E9}\u{1F1F0}": "flag denmark danish",
|
|
"\u{1F1EB}\u{1F1EE}": "flag finland finnish",
|
|
"\u{1F1F5}\u{1F1F1}": "flag poland polish",
|
|
"\u{1F1FA}\u{1F1E6}": "flag ukraine ukrainian",
|
|
"\u{1F1E8}\u{1F1ED}": "flag switzerland swiss",
|
|
"\u{1F1E6}\u{1F1F9}": "flag austria",
|
|
"\u{1F1E7}\u{1F1EA}": "flag belgium",
|
|
"\u{1F1F5}\u{1F1F9}": "flag portugal portuguese",
|
|
"\u{1F1EC}\u{1F1F7}": "flag greece greek",
|
|
"\u{1F1EE}\u{1F1EA}": "flag ireland irish",
|
|
"\u{1F1EE}\u{1F1F1}": "flag israel",
|
|
"\u{1F1EA}\u{1F1EC}": "flag egypt",
|
|
"\u{1F1FF}\u{1F1E6}": "flag south africa",
|
|
"\u{1F1F9}\u{1F1ED}": "flag thailand thai",
|
|
"\u{1F1FB}\u{1F1F3}": "flag vietnam vietnamese",
|
|
"\u{1F1EE}\u{1F1E9}": "flag indonesia",
|
|
"\u{1F1F5}\u{1F1ED}": "flag philippines",
|
|
"\u{1F1F3}\u{1F1FF}": "flag new zealand",
|
|
"\u{1F1F8}\u{1F1EC}": "flag singapore",
|
|
"\u{1F1F2}\u{1F1FE}": "flag malaysia",
|
|
"\u{1F1E8}\u{1F1F4}": "flag colombia",
|
|
"\u{1F1E8}\u{1F1F1}": "flag chile",
|
|
"\u{1F1F5}\u{1F1EA}": "flag peru",
|
|
"\u{1F1F0}\u{1F1FF}": "flag kazakhstan",
|
|
"\u{1F1EC}\u{1F1EA}": "flag georgia",
|
|
"\u{1F3F4}\u200D\u2620\uFE0F": "pirate flag jolly roger",
|
|
"\u{1F3F3}\uFE0F\u200D\u{1F308}": "rainbow flag pride lgbtq",
|
|
"\u{1F3F3}\uFE0F\u200D\u26A7\uFE0F": "transgender flag",
|
|
// More misc symbols
|
|
"\u262E\uFE0F": "peace symbol",
|
|
"\u271D\uFE0F": "latin cross christian",
|
|
"\u262A\uFE0F": "star and crescent islam",
|
|
"\u{1F549}\uFE0F": "om hindu buddhist",
|
|
"\u262F\uFE0F": "yin yang balance",
|
|
"\u2721\uFE0F": "star of david jewish",
|
|
"\u{1F52F}": "six pointed star",
|
|
"\u2638\uFE0F": "wheel of dharma buddhism",
|
|
"\u{1F6D0}": "place of worship",
|
|
"\u269B\uFE0F": "atom symbol science",
|
|
"\u2622\uFE0F": "radioactive nuclear",
|
|
"\u2623\uFE0F": "biohazard",
|
|
"\u{1F194}": "id identity",
|
|
"\u2695\uFE0F": "medical symbol caduceus",
|
|
"\u24C2\uFE0F": "circled m metro",
|
|
"\u{1F170}\uFE0F": "a button blood type",
|
|
"\u{1F171}\uFE0F": "b button blood type",
|
|
"\u{1F18E}": "ab button blood type",
|
|
"\u{1F17E}\uFE0F": "o button blood type",
|
|
"\u{1F198}": "sos emergency help",
|
|
"\u{1F19A}": "vs versus",
|
|
"\u{1F197}": "ok button",
|
|
"\u{1F195}": "new button",
|
|
"\u{1F193}": "free button",
|
|
"\u{1F201}": "japanese here",
|
|
"\u{1F202}\uFE0F": "japanese service charge",
|
|
"\u{1F530}": "japanese symbol beginner",
|
|
"\u2640\uFE0F": "female sign woman",
|
|
"\u2642\uFE0F": "male sign man",
|
|
"\u26A7\uFE0F": "transgender symbol",
|
|
"\u2716\uFE0F": "multiply cross",
|
|
"\u2795": "plus add",
|
|
"\u2796": "minus subtract",
|
|
"\u2797": "divide",
|
|
"\u{1F7F0}": "equals sign",
|
|
"#\uFE0F\u20E3": "hash number sign",
|
|
"*\uFE0F\u20E3": "asterisk keycap",
|
|
"0\uFE0F\u20E3": "zero keycap",
|
|
"1\uFE0F\u20E3": "one keycap",
|
|
"2\uFE0F\u20E3": "two keycap",
|
|
"3\uFE0F\u20E3": "three keycap",
|
|
"4\uFE0F\u20E3": "four keycap",
|
|
"5\uFE0F\u20E3": "five keycap",
|
|
"6\uFE0F\u20E3": "six keycap",
|
|
"7\uFE0F\u20E3": "seven keycap",
|
|
"8\uFE0F\u20E3": "eight keycap",
|
|
"9\uFE0F\u20E3": "nine keycap",
|
|
"\u{1F51F}": "ten keycap",
|
|
"\u{1F17F}\uFE0F": "parking button",
|
|
"\u{1F233}": "japanese vacancy",
|
|
"\u{1F234}": "japanese passing grade",
|
|
"\u{1F235}": "japanese no vacancy",
|
|
"\u{1F239}": "japanese discount",
|
|
"\u{1F232}": "japanese prohibited",
|
|
"\u{1F250}": "japanese bargain",
|
|
"\u{1F236}": "japanese not free of charge",
|
|
"\u{1F21A}": "japanese free of charge",
|
|
"\u{1F51D}": "top arrow",
|
|
"\u{1F519}": "back arrow",
|
|
"\u{1F51B}": "on arrow",
|
|
"\u{1F51C}": "soon arrow",
|
|
"\u{1F51A}": "end arrow",
|
|
"\u2195\uFE0F": "up down arrow",
|
|
"\u2194\uFE0F": "left right arrow",
|
|
"\u2197\uFE0F": "northeast arrow",
|
|
"\u2198\uFE0F": "southeast arrow",
|
|
"\u2199\uFE0F": "southwest arrow",
|
|
"\u2196\uFE0F": "northwest arrow",
|
|
"\u2934\uFE0F": "right arrow curving up",
|
|
"\u2935\uFE0F": "right arrow curving down",
|
|
"\u{1F502}": "repeat single loop one",
|
|
"\u{1F503}": "clockwise arrows",
|
|
"\u25C0\uFE0F": "reverse button rewind",
|
|
"\u23ED\uFE0F": "next track",
|
|
"\u23EE\uFE0F": "previous track",
|
|
"\u23EF\uFE0F": "play pause toggle",
|
|
"\u{1F505}": "dim button brightness low",
|
|
"\u{1F506}": "bright button brightness high",
|
|
"\u{1F4F6}": "signal bars antenna",
|
|
"\u{1F4F3}": "vibration mode",
|
|
"\u{1F4F4}": "mobile phone off",
|
|
"\u{1F518}": "radio button",
|
|
"\u{1F532}": "black square button",
|
|
"\u{1F533}": "white square button",
|
|
"\u{1F53A}": "red triangle up",
|
|
"\u{1F53B}": "red triangle down",
|
|
"\u{1F538}": "small orange diamond",
|
|
"\u{1F539}": "small blue diamond",
|
|
"\u{1F536}": "large orange diamond",
|
|
"\u{1F537}": "large blue diamond",
|
|
"\u25FB\uFE0F": "white medium square",
|
|
"\u25FC\uFE0F": "black medium square",
|
|
"\u25FD": "white medium small square",
|
|
"\u25FE": "black medium small square",
|
|
"\u25AA\uFE0F": "black small square",
|
|
"\u25AB\uFE0F": "white small square",
|
|
"\u{1F4A0}": "diamond shape with dot inside blue",
|
|
"\xA9\uFE0F": "copyright",
|
|
"\xAE\uFE0F": "registered trademark",
|
|
"\u2122\uFE0F": "trademark"
|
|
};
|
|
|
|
// icon_picker_modal.ts
|
|
var GROUPS = [
|
|
{
|
|
label: "Smileys",
|
|
icon: "\u{1F600}",
|
|
emojis: [
|
|
"\u{1F600}",
|
|
"\u{1F603}",
|
|
"\u{1F604}",
|
|
"\u{1F601}",
|
|
"\u{1F606}",
|
|
"\u{1F605}",
|
|
"\u{1F923}",
|
|
"\u{1F602}",
|
|
"\u{1F642}",
|
|
"\u{1F643}",
|
|
"\u{1FAE0}",
|
|
"\u{1F609}",
|
|
"\u{1F60A}",
|
|
"\u{1F607}",
|
|
"\u{1F970}",
|
|
"\u{1F60D}",
|
|
"\u{1F929}",
|
|
"\u{1F618}",
|
|
"\u{1F617}",
|
|
"\u263A\uFE0F",
|
|
"\u{1F61A}",
|
|
"\u{1F619}",
|
|
"\u{1F972}",
|
|
"\u{1F60B}",
|
|
"\u{1F61B}",
|
|
"\u{1F61C}",
|
|
"\u{1F92A}",
|
|
"\u{1F61D}",
|
|
"\u{1F911}",
|
|
"\u{1F917}",
|
|
"\u{1F92D}",
|
|
"\u{1FAE2}",
|
|
"\u{1FAE3}",
|
|
"\u{1F92B}",
|
|
"\u{1F914}",
|
|
"\u{1FAE1}",
|
|
"\u{1F910}",
|
|
"\u{1F928}",
|
|
"\u{1F610}",
|
|
"\u{1F611}",
|
|
"\u{1F636}",
|
|
"\u{1FAE5}",
|
|
"\u{1F636}\u200D\u{1F32B}\uFE0F",
|
|
"\u{1F60F}",
|
|
"\u{1F612}",
|
|
"\u{1F644}",
|
|
"\u{1F62C}",
|
|
"\u{1F62E}\u200D\u{1F4A8}",
|
|
"\u{1F925}",
|
|
"\u{1FAE8}",
|
|
"\u{1F60C}",
|
|
"\u{1F614}",
|
|
"\u{1F62A}",
|
|
"\u{1F924}",
|
|
"\u{1F634}",
|
|
"\u{1FAE9}",
|
|
"\u{1F637}",
|
|
"\u{1F912}",
|
|
"\u{1F915}",
|
|
"\u{1F922}",
|
|
"\u{1F92E}",
|
|
"\u{1F927}",
|
|
"\u{1F975}",
|
|
"\u{1F976}",
|
|
"\u{1F974}",
|
|
"\u{1F635}",
|
|
"\u{1F635}\u200D\u{1F4AB}",
|
|
"\u{1F92F}",
|
|
"\u{1F920}",
|
|
"\u{1F973}",
|
|
"\u{1F978}",
|
|
"\u{1F60E}",
|
|
"\u{1F913}",
|
|
"\u{1F9D0}",
|
|
"\u{1F615}",
|
|
"\u{1FAE4}",
|
|
"\u{1F61F}",
|
|
"\u{1F641}",
|
|
"\u2639\uFE0F",
|
|
"\u{1F62E}",
|
|
"\u{1F62F}",
|
|
"\u{1F632}",
|
|
"\u{1F633}",
|
|
"\u{1F97A}",
|
|
"\u{1F979}",
|
|
"\u{1F626}",
|
|
"\u{1F627}",
|
|
"\u{1F628}",
|
|
"\u{1F630}",
|
|
"\u{1F625}",
|
|
"\u{1F622}",
|
|
"\u{1F62D}",
|
|
"\u{1F631}",
|
|
"\u{1F616}",
|
|
"\u{1F623}",
|
|
"\u{1F61E}",
|
|
"\u{1F613}",
|
|
"\u{1F629}",
|
|
"\u{1F62B}",
|
|
"\u{1F971}",
|
|
"\u{1F624}",
|
|
"\u{1F621}",
|
|
"\u{1F620}",
|
|
"\u{1F92C}",
|
|
"\u{1F608}",
|
|
"\u{1F47F}",
|
|
"\u{1F480}",
|
|
"\u2620\uFE0F",
|
|
"\u{1F4A9}",
|
|
"\u{1F921}",
|
|
"\u{1F479}",
|
|
"\u{1F47A}",
|
|
"\u{1F47B}",
|
|
"\u{1F47D}",
|
|
"\u{1F47E}",
|
|
"\u{1F916}",
|
|
"\u{1F63A}",
|
|
"\u{1F638}",
|
|
"\u{1F639}",
|
|
"\u{1F63B}",
|
|
"\u{1F63C}",
|
|
"\u{1F63D}",
|
|
"\u{1F640}",
|
|
"\u{1F63F}",
|
|
"\u{1F63E}",
|
|
"\u{1F648}",
|
|
"\u{1F649}",
|
|
"\u{1F64A}",
|
|
"\u{1F48C}",
|
|
"\u{1F498}",
|
|
"\u{1F49D}",
|
|
"\u{1F496}",
|
|
"\u{1F497}",
|
|
"\u{1F493}",
|
|
"\u{1F49E}",
|
|
"\u{1F495}",
|
|
"\u{1F49F}",
|
|
"\u2763\uFE0F",
|
|
"\u{1F494}",
|
|
"\u2764\uFE0F\u200D\u{1F525}",
|
|
"\u2764\uFE0F\u200D\u{1FA79}",
|
|
"\u2764\uFE0F",
|
|
"\u{1FA77}",
|
|
"\u{1F9E1}",
|
|
"\u{1F49B}",
|
|
"\u{1F49A}",
|
|
"\u{1F499}",
|
|
"\u{1FA75}",
|
|
"\u{1F49C}",
|
|
"\u{1F90E}",
|
|
"\u{1F5A4}",
|
|
"\u{1FA76}",
|
|
"\u{1F90D}",
|
|
"\u{1F48B}",
|
|
"\u{1F4AF}",
|
|
"\u{1F4A2}",
|
|
"\u{1F4A5}",
|
|
"\u{1F4AB}",
|
|
"\u{1F4A6}",
|
|
"\u{1F4A8}",
|
|
"\u{1F573}\uFE0F",
|
|
"\u{1F4AC}",
|
|
"\u{1F441}\uFE0F\u200D\u{1F5E8}\uFE0F",
|
|
"\u{1F5E8}\uFE0F",
|
|
"\u{1F5EF}\uFE0F",
|
|
"\u{1F4AD}",
|
|
"\u{1F4A4}"
|
|
]
|
|
},
|
|
{
|
|
label: "People",
|
|
icon: "\u{1F44B}",
|
|
emojis: [
|
|
"\u{1F44B}",
|
|
"\u{1F91A}",
|
|
"\u{1F590}\uFE0F",
|
|
"\u270B",
|
|
"\u{1F596}",
|
|
"\u{1FAF1}",
|
|
"\u{1FAF2}",
|
|
"\u{1FAF3}",
|
|
"\u{1FAF4}",
|
|
"\u{1FAF7}",
|
|
"\u{1FAF8}",
|
|
"\u{1F44C}",
|
|
"\u{1F90C}",
|
|
"\u{1F90F}",
|
|
"\u270C\uFE0F",
|
|
"\u{1F91E}",
|
|
"\u{1FAF0}",
|
|
"\u{1F91F}",
|
|
"\u{1F918}",
|
|
"\u{1F919}",
|
|
"\u{1F448}",
|
|
"\u{1F449}",
|
|
"\u{1F446}",
|
|
"\u{1F595}",
|
|
"\u{1F447}",
|
|
"\u261D\uFE0F",
|
|
"\u{1FAF5}",
|
|
"\u{1F44D}",
|
|
"\u{1F44E}",
|
|
"\u270A",
|
|
"\u{1F44A}",
|
|
"\u{1F91B}",
|
|
"\u{1F91C}",
|
|
"\u{1F44F}",
|
|
"\u{1F64C}",
|
|
"\u{1FAF6}",
|
|
"\u{1F450}",
|
|
"\u{1F932}",
|
|
"\u{1F91D}",
|
|
"\u{1F64F}",
|
|
"\u270D\uFE0F",
|
|
"\u{1F485}",
|
|
"\u{1F933}",
|
|
"\u{1F4AA}",
|
|
"\u{1F9BE}",
|
|
"\u{1F9BF}",
|
|
"\u{1F9B5}",
|
|
"\u{1F9B6}",
|
|
"\u{1F442}",
|
|
"\u{1F9BB}",
|
|
"\u{1F443}",
|
|
"\u{1F9E0}",
|
|
"\u{1FAC0}",
|
|
"\u{1FAC1}",
|
|
"\u{1F9B7}",
|
|
"\u{1F9B4}",
|
|
"\u{1F440}",
|
|
"\u{1F441}\uFE0F",
|
|
"\u{1F445}",
|
|
"\u{1F444}",
|
|
"\u{1FAE6}",
|
|
"\u{1F476}",
|
|
"\u{1F9D2}",
|
|
"\u{1F466}",
|
|
"\u{1F467}",
|
|
"\u{1F9D1}",
|
|
"\u{1F471}",
|
|
"\u{1F468}",
|
|
"\u{1F469}",
|
|
"\u{1F9D3}",
|
|
"\u{1F474}",
|
|
"\u{1F475}",
|
|
"\u{1F645}",
|
|
"\u{1F646}",
|
|
"\u{1F481}",
|
|
"\u{1F64B}",
|
|
"\u{1F9CF}",
|
|
"\u{1F647}",
|
|
"\u{1F926}",
|
|
"\u{1F937}",
|
|
"\u{1F9D1}\u200D\u2695\uFE0F",
|
|
"\u{1F9D1}\u200D\u{1F393}",
|
|
"\u{1F9D1}\u200D\u{1F3EB}",
|
|
"\u{1F9D1}\u200D\u2696\uFE0F",
|
|
"\u{1F9D1}\u200D\u{1F33E}",
|
|
"\u{1F9D1}\u200D\u{1F373}",
|
|
"\u{1F9D1}\u200D\u{1F527}",
|
|
"\u{1F9D1}\u200D\u{1F3ED}",
|
|
"\u{1F9D1}\u200D\u{1F4BC}",
|
|
"\u{1F9D1}\u200D\u{1F52C}",
|
|
"\u{1F9D1}\u200D\u{1F4BB}",
|
|
"\u{1F9D1}\u200D\u{1F3A4}",
|
|
"\u{1F9D1}\u200D\u{1F3A8}",
|
|
"\u{1F9D1}\u200D\u2708\uFE0F",
|
|
"\u{1F9D1}\u200D\u{1F680}",
|
|
"\u{1F9D1}\u200D\u{1F692}",
|
|
"\u{1F46E}",
|
|
"\u{1F575}\uFE0F",
|
|
"\u{1F482}",
|
|
"\u{1F977}",
|
|
"\u{1F477}",
|
|
"\u{1FAC5}",
|
|
"\u{1F934}",
|
|
"\u{1F478}",
|
|
"\u{1F473}",
|
|
"\u{1F472}",
|
|
"\u{1F9D5}",
|
|
"\u{1F935}",
|
|
"\u{1F470}",
|
|
"\u{1F930}",
|
|
"\u{1F931}",
|
|
"\u{1F47C}",
|
|
"\u{1F385}",
|
|
"\u{1F936}",
|
|
"\u{1F9D1}\u200D\u{1F384}",
|
|
"\u{1F9B8}",
|
|
"\u{1F9B9}",
|
|
"\u{1F9D9}",
|
|
"\u{1F9DA}",
|
|
"\u{1F9DB}",
|
|
"\u{1F9DC}",
|
|
"\u{1F9DD}",
|
|
"\u{1F9DE}",
|
|
"\u{1F9DF}",
|
|
"\u{1F9CC}",
|
|
"\u{1F486}",
|
|
"\u{1F487}",
|
|
"\u{1F6B6}",
|
|
"\u{1F9CD}",
|
|
"\u{1F9CE}",
|
|
"\u{1F9D1}\u200D\u{1F9AF}",
|
|
"\u{1F9D1}\u200D\u{1F9BC}",
|
|
"\u{1F9D1}\u200D\u{1F9BD}",
|
|
"\u{1F3C3}",
|
|
"\u{1F483}",
|
|
"\u{1F57A}",
|
|
"\u{1F574}\uFE0F",
|
|
"\u{1F46F}",
|
|
"\u{1F9D6}",
|
|
"\u{1F9D7}",
|
|
"\u{1F93A}",
|
|
"\u{1F3C7}",
|
|
"\u26F7\uFE0F",
|
|
"\u{1F3C2}",
|
|
"\u{1F3CC}\uFE0F",
|
|
"\u{1F3C4}",
|
|
"\u{1F6A3}",
|
|
"\u{1F3CA}",
|
|
"\u26F9\uFE0F",
|
|
"\u{1F3CB}\uFE0F",
|
|
"\u{1F6B4}",
|
|
"\u{1F6B5}",
|
|
"\u{1F938}",
|
|
"\u{1F93C}",
|
|
"\u{1F93D}",
|
|
"\u{1F93E}",
|
|
"\u{1F939}",
|
|
"\u{1F9D8}",
|
|
"\u{1F6C0}",
|
|
"\u{1F6CC}",
|
|
"\u{1F9D1}\u200D\u{1F91D}\u200D\u{1F9D1}",
|
|
"\u{1F46D}",
|
|
"\u{1F46B}",
|
|
"\u{1F46C}",
|
|
"\u{1F48F}",
|
|
"\u{1F491}",
|
|
"\u{1F46A}",
|
|
"\u{1F5E3}\uFE0F",
|
|
"\u{1F464}",
|
|
"\u{1F465}",
|
|
"\u{1FAC2}",
|
|
"\u{1F463}"
|
|
]
|
|
},
|
|
{
|
|
label: "Animals",
|
|
icon: "\u{1F436}",
|
|
emojis: [
|
|
"\u{1F435}",
|
|
"\u{1F412}",
|
|
"\u{1F98D}",
|
|
"\u{1F9A7}",
|
|
"\u{1F436}",
|
|
"\u{1F415}",
|
|
"\u{1F9AE}",
|
|
"\u{1F415}\u200D\u{1F9BA}",
|
|
"\u{1F429}",
|
|
"\u{1F43A}",
|
|
"\u{1F98A}",
|
|
"\u{1F99D}",
|
|
"\u{1F431}",
|
|
"\u{1F408}",
|
|
"\u{1F408}\u200D\u2B1B",
|
|
"\u{1F981}",
|
|
"\u{1F42F}",
|
|
"\u{1F405}",
|
|
"\u{1F406}",
|
|
"\u{1F434}",
|
|
"\u{1FACE}",
|
|
"\u{1FACF}",
|
|
"\u{1F40E}",
|
|
"\u{1F984}",
|
|
"\u{1F993}",
|
|
"\u{1F98C}",
|
|
"\u{1F9AC}",
|
|
"\u{1F42E}",
|
|
"\u{1F402}",
|
|
"\u{1F403}",
|
|
"\u{1F404}",
|
|
"\u{1F437}",
|
|
"\u{1F416}",
|
|
"\u{1F417}",
|
|
"\u{1F43D}",
|
|
"\u{1F40F}",
|
|
"\u{1F411}",
|
|
"\u{1F410}",
|
|
"\u{1F42A}",
|
|
"\u{1F42B}",
|
|
"\u{1F999}",
|
|
"\u{1F992}",
|
|
"\u{1F418}",
|
|
"\u{1F9A3}",
|
|
"\u{1F98F}",
|
|
"\u{1F99B}",
|
|
"\u{1F42D}",
|
|
"\u{1F401}",
|
|
"\u{1F400}",
|
|
"\u{1F439}",
|
|
"\u{1F430}",
|
|
"\u{1F407}",
|
|
"\u{1F43F}\uFE0F",
|
|
"\u{1F9AB}",
|
|
"\u{1F994}",
|
|
"\u{1F987}",
|
|
"\u{1F43B}",
|
|
"\u{1F43B}\u200D\u2744\uFE0F",
|
|
"\u{1F428}",
|
|
"\u{1F43C}",
|
|
"\u{1F9A5}",
|
|
"\u{1F9A6}",
|
|
"\u{1F9A8}",
|
|
"\u{1F998}",
|
|
"\u{1F9A1}",
|
|
"\u{1F43E}",
|
|
"\u{1F983}",
|
|
"\u{1F414}",
|
|
"\u{1F413}",
|
|
"\u{1F423}",
|
|
"\u{1F424}",
|
|
"\u{1F425}",
|
|
"\u{1F426}",
|
|
"\u{1F427}",
|
|
"\u{1F54A}\uFE0F",
|
|
"\u{1F985}",
|
|
"\u{1F986}",
|
|
"\u{1F9A2}",
|
|
"\u{1F989}",
|
|
"\u{1F9A4}",
|
|
"\u{1FAB6}",
|
|
"\u{1F9A9}",
|
|
"\u{1F99A}",
|
|
"\u{1F99C}",
|
|
"\u{1FABD}",
|
|
"\u{1F426}\u200D\u2B1B",
|
|
"\u{1FABF}",
|
|
"\u{1F426}\u200D\u{1F525}",
|
|
"\u{1F438}",
|
|
"\u{1F40A}",
|
|
"\u{1F422}",
|
|
"\u{1F98E}",
|
|
"\u{1F40D}",
|
|
"\u{1F432}",
|
|
"\u{1F409}",
|
|
"\u{1F995}",
|
|
"\u{1F996}",
|
|
"\u{1F433}",
|
|
"\u{1F40B}",
|
|
"\u{1F42C}",
|
|
"\u{1F9AD}",
|
|
"\u{1F41F}",
|
|
"\u{1F420}",
|
|
"\u{1F421}",
|
|
"\u{1F988}",
|
|
"\u{1F419}",
|
|
"\u{1F41A}",
|
|
"\u{1FAB8}",
|
|
"\u{1FABC}",
|
|
"\u{1F980}",
|
|
"\u{1F99E}",
|
|
"\u{1F990}",
|
|
"\u{1F991}",
|
|
"\u{1F9AA}",
|
|
"\u{1F40C}",
|
|
"\u{1F98B}",
|
|
"\u{1F41B}",
|
|
"\u{1F41C}",
|
|
"\u{1F41D}",
|
|
"\u{1FAB2}",
|
|
"\u{1F41E}",
|
|
"\u{1F997}",
|
|
"\u{1FAB3}",
|
|
"\u{1F577}\uFE0F",
|
|
"\u{1F578}\uFE0F",
|
|
"\u{1F982}",
|
|
"\u{1F99F}",
|
|
"\u{1FAB0}",
|
|
"\u{1FAB1}",
|
|
"\u{1F9A0}",
|
|
"\u{1F490}",
|
|
"\u{1F338}",
|
|
"\u{1F4AE}",
|
|
"\u{1FAB7}",
|
|
"\u{1F3F5}\uFE0F",
|
|
"\u{1F339}",
|
|
"\u{1F940}",
|
|
"\u{1F33A}",
|
|
"\u{1F33B}",
|
|
"\u{1F33C}",
|
|
"\u{1F337}",
|
|
"\u{1FABB}",
|
|
"\u{1F331}",
|
|
"\u{1FAB4}",
|
|
"\u{1F332}",
|
|
"\u{1F333}",
|
|
"\u{1F334}",
|
|
"\u{1F335}",
|
|
"\u{1F33E}",
|
|
"\u{1F33F}",
|
|
"\u2618\uFE0F",
|
|
"\u{1F340}",
|
|
"\u{1F341}",
|
|
"\u{1F342}",
|
|
"\u{1F343}",
|
|
"\u{1FAB9}",
|
|
"\u{1FABA}",
|
|
"\u{1F344}"
|
|
]
|
|
},
|
|
{
|
|
label: "Food",
|
|
icon: "\u{1F354}",
|
|
emojis: [
|
|
"\u{1F347}",
|
|
"\u{1F348}",
|
|
"\u{1F349}",
|
|
"\u{1F34A}",
|
|
"\u{1F34B}",
|
|
"\u{1F34B}\u200D\u{1F7E9}",
|
|
"\u{1F34C}",
|
|
"\u{1F34D}",
|
|
"\u{1F96D}",
|
|
"\u{1F34E}",
|
|
"\u{1F34F}",
|
|
"\u{1F350}",
|
|
"\u{1F351}",
|
|
"\u{1F352}",
|
|
"\u{1F353}",
|
|
"\u{1FAD0}",
|
|
"\u{1F95D}",
|
|
"\u{1F345}",
|
|
"\u{1FAD2}",
|
|
"\u{1F965}",
|
|
"\u{1F951}",
|
|
"\u{1F346}",
|
|
"\u{1F954}",
|
|
"\u{1F955}",
|
|
"\u{1F33D}",
|
|
"\u{1F336}\uFE0F",
|
|
"\u{1FAD1}",
|
|
"\u{1F952}",
|
|
"\u{1F96C}",
|
|
"\u{1F966}",
|
|
"\u{1F9C4}",
|
|
"\u{1F9C5}",
|
|
"\u{1F95C}",
|
|
"\u{1FAD8}",
|
|
"\u{1F330}",
|
|
"\u{1FADA}",
|
|
"\u{1FADB}",
|
|
"\u{1F35E}",
|
|
"\u{1F950}",
|
|
"\u{1F956}",
|
|
"\u{1FAD3}",
|
|
"\u{1F968}",
|
|
"\u{1F96F}",
|
|
"\u{1F95E}",
|
|
"\u{1F9C7}",
|
|
"\u{1F9C0}",
|
|
"\u{1F356}",
|
|
"\u{1F357}",
|
|
"\u{1F969}",
|
|
"\u{1F953}",
|
|
"\u{1F354}",
|
|
"\u{1F35F}",
|
|
"\u{1F355}",
|
|
"\u{1F32D}",
|
|
"\u{1F96A}",
|
|
"\u{1F32E}",
|
|
"\u{1F32F}",
|
|
"\u{1FAD4}",
|
|
"\u{1F959}",
|
|
"\u{1F9C6}",
|
|
"\u{1F95A}",
|
|
"\u{1F373}",
|
|
"\u{1F958}",
|
|
"\u{1F372}",
|
|
"\u{1FAD5}",
|
|
"\u{1F963}",
|
|
"\u{1F957}",
|
|
"\u{1F37F}",
|
|
"\u{1F9C8}",
|
|
"\u{1F9C2}",
|
|
"\u{1F96B}",
|
|
"\u{1F371}",
|
|
"\u{1F358}",
|
|
"\u{1F359}",
|
|
"\u{1F35A}",
|
|
"\u{1F35B}",
|
|
"\u{1F35C}",
|
|
"\u{1F35D}",
|
|
"\u{1F360}",
|
|
"\u{1F362}",
|
|
"\u{1F363}",
|
|
"\u{1F364}",
|
|
"\u{1F365}",
|
|
"\u{1F96E}",
|
|
"\u{1F361}",
|
|
"\u{1F95F}",
|
|
"\u{1F960}",
|
|
"\u{1F961}",
|
|
"\u{1F366}",
|
|
"\u{1F367}",
|
|
"\u{1F368}",
|
|
"\u{1F369}",
|
|
"\u{1F36A}",
|
|
"\u{1F382}",
|
|
"\u{1F370}",
|
|
"\u{1F9C1}",
|
|
"\u{1F967}",
|
|
"\u{1F36B}",
|
|
"\u{1F36C}",
|
|
"\u{1F36D}",
|
|
"\u{1F36E}",
|
|
"\u{1F36F}",
|
|
"\u{1F37C}",
|
|
"\u{1F95B}",
|
|
"\u2615",
|
|
"\u{1FAD6}",
|
|
"\u{1F375}",
|
|
"\u{1F376}",
|
|
"\u{1F37E}",
|
|
"\u{1F377}",
|
|
"\u{1F378}",
|
|
"\u{1F379}",
|
|
"\u{1F37A}",
|
|
"\u{1F37B}",
|
|
"\u{1F942}",
|
|
"\u{1F943}",
|
|
"\u{1FAD7}",
|
|
"\u{1F964}",
|
|
"\u{1F9CB}",
|
|
"\u{1F9C3}",
|
|
"\u{1F9C9}",
|
|
"\u{1F9CA}",
|
|
"\u{1F962}",
|
|
"\u{1F37D}\uFE0F",
|
|
"\u{1F374}",
|
|
"\u{1F944}",
|
|
"\u{1F52A}",
|
|
"\u{1FAD9}",
|
|
"\u{1F3FA}"
|
|
]
|
|
},
|
|
{
|
|
label: "Travel",
|
|
icon: "\u{1F697}",
|
|
emojis: [
|
|
"\u{1F30D}",
|
|
"\u{1F30E}",
|
|
"\u{1F30F}",
|
|
"\u{1F310}",
|
|
"\u{1F5FA}\uFE0F",
|
|
"\u{1F5FE}",
|
|
"\u{1F9ED}",
|
|
"\u{1F3D4}\uFE0F",
|
|
"\u26F0\uFE0F",
|
|
"\u{1F30B}",
|
|
"\u{1F5FB}",
|
|
"\u{1F3D5}\uFE0F",
|
|
"\u{1F3D6}\uFE0F",
|
|
"\u{1F3DC}\uFE0F",
|
|
"\u{1F3DD}\uFE0F",
|
|
"\u{1F3DE}\uFE0F",
|
|
"\u{1F3DF}\uFE0F",
|
|
"\u{1F3DB}\uFE0F",
|
|
"\u{1F3D7}\uFE0F",
|
|
"\u{1F9F1}",
|
|
"\u{1FAA8}",
|
|
"\u{1FAB5}",
|
|
"\u{1F6D6}",
|
|
"\u{1F3D8}\uFE0F",
|
|
"\u{1F3DA}\uFE0F",
|
|
"\u{1F3E0}",
|
|
"\u{1F3E1}",
|
|
"\u{1F3E2}",
|
|
"\u{1F3E3}",
|
|
"\u{1F3E4}",
|
|
"\u{1F3E5}",
|
|
"\u{1F3E6}",
|
|
"\u{1F3E8}",
|
|
"\u{1F3E9}",
|
|
"\u{1F3EA}",
|
|
"\u{1F3EB}",
|
|
"\u{1F3EC}",
|
|
"\u{1F3ED}",
|
|
"\u{1F3EF}",
|
|
"\u{1F3F0}",
|
|
"\u{1F492}",
|
|
"\u{1F5FC}",
|
|
"\u{1F5FD}",
|
|
"\u26EA",
|
|
"\u{1F54C}",
|
|
"\u{1F6D5}",
|
|
"\u{1F54D}",
|
|
"\u26E9\uFE0F",
|
|
"\u{1F54B}",
|
|
"\u26F2",
|
|
"\u26FA",
|
|
"\u{1F301}",
|
|
"\u{1F303}",
|
|
"\u{1F3D9}\uFE0F",
|
|
"\u{1F304}",
|
|
"\u{1F305}",
|
|
"\u{1F306}",
|
|
"\u{1F307}",
|
|
"\u{1F309}",
|
|
"\u2668\uFE0F",
|
|
"\u{1F3A0}",
|
|
"\u{1F6DD}",
|
|
"\u{1F3A1}",
|
|
"\u{1F3A2}",
|
|
"\u{1F488}",
|
|
"\u{1F3AA}",
|
|
"\u{1F682}",
|
|
"\u{1F683}",
|
|
"\u{1F684}",
|
|
"\u{1F685}",
|
|
"\u{1F686}",
|
|
"\u{1F687}",
|
|
"\u{1F688}",
|
|
"\u{1F689}",
|
|
"\u{1F68A}",
|
|
"\u{1F69D}",
|
|
"\u{1F69E}",
|
|
"\u{1F68B}",
|
|
"\u{1F68C}",
|
|
"\u{1F68D}",
|
|
"\u{1F68E}",
|
|
"\u{1F690}",
|
|
"\u{1F691}",
|
|
"\u{1F692}",
|
|
"\u{1F693}",
|
|
"\u{1F694}",
|
|
"\u{1F695}",
|
|
"\u{1F696}",
|
|
"\u{1F697}",
|
|
"\u{1F698}",
|
|
"\u{1F699}",
|
|
"\u{1F6FB}",
|
|
"\u{1F69A}",
|
|
"\u{1F69B}",
|
|
"\u{1F69C}",
|
|
"\u{1F3CE}\uFE0F",
|
|
"\u{1F3CD}\uFE0F",
|
|
"\u{1F6F5}",
|
|
"\u{1F9BD}",
|
|
"\u{1F9BC}",
|
|
"\u{1F6FA}",
|
|
"\u{1F6B2}",
|
|
"\u{1F6F4}",
|
|
"\u{1F6F9}",
|
|
"\u{1F6FC}",
|
|
"\u{1F68F}",
|
|
"\u{1F6E3}\uFE0F",
|
|
"\u{1F6E4}\uFE0F",
|
|
"\u{1F6E2}\uFE0F",
|
|
"\u26FD",
|
|
"\u{1F6DE}",
|
|
"\u{1F6A8}",
|
|
"\u{1F6A5}",
|
|
"\u{1F6A6}",
|
|
"\u{1F6D1}",
|
|
"\u{1F6A7}",
|
|
"\u2693",
|
|
"\u{1F6DF}",
|
|
"\u26F5",
|
|
"\u{1F6F6}",
|
|
"\u{1F6A4}",
|
|
"\u{1F6F3}\uFE0F",
|
|
"\u26F4\uFE0F",
|
|
"\u{1F6E5}\uFE0F",
|
|
"\u{1F6A2}",
|
|
"\u2708\uFE0F",
|
|
"\u{1F6E9}\uFE0F",
|
|
"\u{1F6EB}",
|
|
"\u{1F6EC}",
|
|
"\u{1FA82}",
|
|
"\u{1F4BA}",
|
|
"\u{1F681}",
|
|
"\u{1F69F}",
|
|
"\u{1F6A0}",
|
|
"\u{1F6A1}",
|
|
"\u{1F6F0}\uFE0F",
|
|
"\u{1F680}",
|
|
"\u{1F6F8}",
|
|
"\u{1F6CE}\uFE0F",
|
|
"\u{1F9F3}",
|
|
"\u231B",
|
|
"\u23F3",
|
|
"\u231A",
|
|
"\u23F0",
|
|
"\u23F1\uFE0F",
|
|
"\u23F2\uFE0F",
|
|
"\u{1F570}\uFE0F",
|
|
"\u{1F311}",
|
|
"\u{1F312}",
|
|
"\u{1F313}",
|
|
"\u{1F314}",
|
|
"\u{1F315}",
|
|
"\u{1F316}",
|
|
"\u{1F317}",
|
|
"\u{1F318}",
|
|
"\u{1F319}",
|
|
"\u{1F31A}",
|
|
"\u{1F31B}",
|
|
"\u{1F31C}",
|
|
"\u{1F321}\uFE0F",
|
|
"\u2600\uFE0F",
|
|
"\u{1F31D}",
|
|
"\u{1F31E}",
|
|
"\u{1FA90}",
|
|
"\u2B50",
|
|
"\u{1F31F}",
|
|
"\u{1F320}",
|
|
"\u{1F30C}",
|
|
"\u2601\uFE0F",
|
|
"\u26C5",
|
|
"\u26C8\uFE0F",
|
|
"\u{1F324}\uFE0F",
|
|
"\u{1F325}\uFE0F",
|
|
"\u{1F326}\uFE0F",
|
|
"\u{1F327}\uFE0F",
|
|
"\u{1F328}\uFE0F",
|
|
"\u{1F329}\uFE0F",
|
|
"\u{1F32A}\uFE0F",
|
|
"\u{1F32B}\uFE0F",
|
|
"\u{1F32C}\uFE0F",
|
|
"\u{1F300}",
|
|
"\u{1F308}",
|
|
"\u{1F302}",
|
|
"\u2602\uFE0F",
|
|
"\u2614",
|
|
"\u26F1\uFE0F",
|
|
"\u26A1",
|
|
"\u2744\uFE0F",
|
|
"\u2603\uFE0F",
|
|
"\u26C4",
|
|
"\u2604\uFE0F",
|
|
"\u{1F525}",
|
|
"\u{1F4A7}",
|
|
"\u{1F30A}"
|
|
]
|
|
},
|
|
{
|
|
label: "Activities",
|
|
icon: "\u{1F3AF}",
|
|
emojis: [
|
|
"\u{1F383}",
|
|
"\u{1F384}",
|
|
"\u{1F386}",
|
|
"\u{1F387}",
|
|
"\u{1F9E8}",
|
|
"\u2728",
|
|
"\u{1F388}",
|
|
"\u{1F389}",
|
|
"\u{1F38A}",
|
|
"\u{1F38B}",
|
|
"\u{1F38D}",
|
|
"\u{1F38E}",
|
|
"\u{1F38F}",
|
|
"\u{1F390}",
|
|
"\u{1F391}",
|
|
"\u{1F9E7}",
|
|
"\u{1F380}",
|
|
"\u{1F381}",
|
|
"\u{1F397}\uFE0F",
|
|
"\u{1F39F}\uFE0F",
|
|
"\u{1F3AB}",
|
|
"\u{1F396}\uFE0F",
|
|
"\u{1F3C6}",
|
|
"\u{1F3C5}",
|
|
"\u{1F947}",
|
|
"\u{1F948}",
|
|
"\u{1F949}",
|
|
"\u26BD",
|
|
"\u26BE",
|
|
"\u{1F94E}",
|
|
"\u{1F3C0}",
|
|
"\u{1F3D0}",
|
|
"\u{1F3C8}",
|
|
"\u{1F3C9}",
|
|
"\u{1F3BE}",
|
|
"\u{1F94F}",
|
|
"\u{1F3B3}",
|
|
"\u{1F3CF}",
|
|
"\u{1F3D1}",
|
|
"\u{1F3D2}",
|
|
"\u{1F94D}",
|
|
"\u{1F3D3}",
|
|
"\u{1F3F8}",
|
|
"\u{1F94A}",
|
|
"\u{1F94B}",
|
|
"\u{1F945}",
|
|
"\u26F3",
|
|
"\u26F8\uFE0F",
|
|
"\u{1F3A3}",
|
|
"\u{1F93F}",
|
|
"\u{1F3BD}",
|
|
"\u{1F3BF}",
|
|
"\u{1F6F7}",
|
|
"\u{1F94C}",
|
|
"\u{1F3AF}",
|
|
"\u{1FA80}",
|
|
"\u{1FA81}",
|
|
"\u{1F52B}",
|
|
"\u{1F3B1}",
|
|
"\u{1F52E}",
|
|
"\u{1FA84}",
|
|
"\u{1F3AE}",
|
|
"\u{1F579}\uFE0F",
|
|
"\u{1F3B0}",
|
|
"\u{1F3B2}",
|
|
"\u{1F9E9}",
|
|
"\u{1F9F8}",
|
|
"\u{1FA85}",
|
|
"\u{1FAA9}",
|
|
"\u{1FA86}",
|
|
"\u2660\uFE0F",
|
|
"\u2665\uFE0F",
|
|
"\u2666\uFE0F",
|
|
"\u2663\uFE0F",
|
|
"\u265F\uFE0F",
|
|
"\u{1F0CF}",
|
|
"\u{1F004}",
|
|
"\u{1F3B4}",
|
|
"\u{1F3AD}",
|
|
"\u{1F5BC}\uFE0F",
|
|
"\u{1F3A8}",
|
|
"\u{1F9F5}",
|
|
"\u{1FAA1}",
|
|
"\u{1F9F6}",
|
|
"\u{1FAA2}"
|
|
]
|
|
},
|
|
{
|
|
label: "Objects",
|
|
icon: "\u{1F4A1}",
|
|
emojis: [
|
|
"\u{1F453}",
|
|
"\u{1F576}\uFE0F",
|
|
"\u{1F97D}",
|
|
"\u{1F97C}",
|
|
"\u{1F9BA}",
|
|
"\u{1F454}",
|
|
"\u{1F455}",
|
|
"\u{1F456}",
|
|
"\u{1F9E3}",
|
|
"\u{1F9E4}",
|
|
"\u{1F9E5}",
|
|
"\u{1F9E6}",
|
|
"\u{1F457}",
|
|
"\u{1F458}",
|
|
"\u{1F97B}",
|
|
"\u{1FA71}",
|
|
"\u{1FA72}",
|
|
"\u{1FA73}",
|
|
"\u{1F459}",
|
|
"\u{1F45A}",
|
|
"\u{1FAAD}",
|
|
"\u{1F45B}",
|
|
"\u{1F45C}",
|
|
"\u{1F45D}",
|
|
"\u{1F6CD}\uFE0F",
|
|
"\u{1F392}",
|
|
"\u{1FA74}",
|
|
"\u{1F45E}",
|
|
"\u{1F45F}",
|
|
"\u{1F97E}",
|
|
"\u{1F97F}",
|
|
"\u{1F460}",
|
|
"\u{1F461}",
|
|
"\u{1FA70}",
|
|
"\u{1F462}",
|
|
"\u{1FAAE}",
|
|
"\u{1F451}",
|
|
"\u{1F452}",
|
|
"\u{1F3A9}",
|
|
"\u{1F393}",
|
|
"\u{1F9E2}",
|
|
"\u{1FA96}",
|
|
"\u26D1\uFE0F",
|
|
"\u{1F4FF}",
|
|
"\u{1F484}",
|
|
"\u{1F48D}",
|
|
"\u{1F48E}",
|
|
"\u{1F507}",
|
|
"\u{1F508}",
|
|
"\u{1F509}",
|
|
"\u{1F50A}",
|
|
"\u{1F4E2}",
|
|
"\u{1F4E3}",
|
|
"\u{1F4EF}",
|
|
"\u{1F514}",
|
|
"\u{1F515}",
|
|
"\u{1F3BC}",
|
|
"\u{1F3B5}",
|
|
"\u{1F3B6}",
|
|
"\u{1F399}\uFE0F",
|
|
"\u{1F39A}\uFE0F",
|
|
"\u{1F39B}\uFE0F",
|
|
"\u{1F3A4}",
|
|
"\u{1F3A7}",
|
|
"\u{1F4FB}",
|
|
"\u{1F3B7}",
|
|
"\u{1FA97}",
|
|
"\u{1F3B8}",
|
|
"\u{1F3B9}",
|
|
"\u{1F3BA}",
|
|
"\u{1F3BB}",
|
|
"\u{1FA95}",
|
|
"\u{1F941}",
|
|
"\u{1FA98}",
|
|
"\u{1FA87}",
|
|
"\u{1FA88}",
|
|
"\u{1FA89}",
|
|
"\u{1F4F1}",
|
|
"\u{1F4F2}",
|
|
"\u260E\uFE0F",
|
|
"\u{1F4DE}",
|
|
"\u{1F4DF}",
|
|
"\u{1F4E0}",
|
|
"\u{1F50B}",
|
|
"\u{1FAAB}",
|
|
"\u{1F50C}",
|
|
"\u{1F4BB}",
|
|
"\u{1F5A5}\uFE0F",
|
|
"\u{1F5A8}\uFE0F",
|
|
"\u2328\uFE0F",
|
|
"\u{1F5B1}\uFE0F",
|
|
"\u{1F5B2}\uFE0F",
|
|
"\u{1F4BD}",
|
|
"\u{1F4BE}",
|
|
"\u{1F4BF}",
|
|
"\u{1F4C0}",
|
|
"\u{1F9EE}",
|
|
"\u{1F3A5}",
|
|
"\u{1F39E}\uFE0F",
|
|
"\u{1F4FD}\uFE0F",
|
|
"\u{1F3AC}",
|
|
"\u{1F4FA}",
|
|
"\u{1F4F7}",
|
|
"\u{1F4F8}",
|
|
"\u{1F4F9}",
|
|
"\u{1F4FC}",
|
|
"\u{1F50D}",
|
|
"\u{1F50E}",
|
|
"\u{1F56F}\uFE0F",
|
|
"\u{1F4A1}",
|
|
"\u{1F526}",
|
|
"\u{1F3EE}",
|
|
"\u{1FA94}",
|
|
"\u{1F4D4}",
|
|
"\u{1F4D5}",
|
|
"\u{1F4D6}",
|
|
"\u{1F4D7}",
|
|
"\u{1F4D8}",
|
|
"\u{1F4D9}",
|
|
"\u{1F4DA}",
|
|
"\u{1F4D3}",
|
|
"\u{1F4D2}",
|
|
"\u{1F4C3}",
|
|
"\u{1F4DC}",
|
|
"\u{1F4C4}",
|
|
"\u{1F4F0}",
|
|
"\u{1F5DE}\uFE0F",
|
|
"\u{1F4D1}",
|
|
"\u{1F516}",
|
|
"\u{1F3F7}\uFE0F",
|
|
"\u{1F4B0}",
|
|
"\u{1FA99}",
|
|
"\u{1F4B4}",
|
|
"\u{1F4B5}",
|
|
"\u{1F4B6}",
|
|
"\u{1F4B7}",
|
|
"\u{1F4B8}",
|
|
"\u{1F4B3}",
|
|
"\u{1F9FE}",
|
|
"\u{1F4B9}",
|
|
"\u2709\uFE0F",
|
|
"\u{1F4E7}",
|
|
"\u{1F4E8}",
|
|
"\u{1F4E9}",
|
|
"\u{1F4E4}",
|
|
"\u{1F4E5}",
|
|
"\u{1F4E6}",
|
|
"\u{1F4EB}",
|
|
"\u{1F4EA}",
|
|
"\u{1F4EC}",
|
|
"\u{1F4ED}",
|
|
"\u{1F4EE}",
|
|
"\u{1F5F3}\uFE0F",
|
|
"\u270F\uFE0F",
|
|
"\u2712\uFE0F",
|
|
"\u{1F58B}\uFE0F",
|
|
"\u{1F58A}\uFE0F",
|
|
"\u{1F58C}\uFE0F",
|
|
"\u{1F58D}\uFE0F",
|
|
"\u{1F4DD}",
|
|
"\u{1F4BC}",
|
|
"\u{1F4C1}",
|
|
"\u{1F4C2}",
|
|
"\u{1F5C2}\uFE0F",
|
|
"\u{1F4C5}",
|
|
"\u{1F4C6}",
|
|
"\u{1F5D2}\uFE0F",
|
|
"\u{1F5D3}\uFE0F",
|
|
"\u{1F4C7}",
|
|
"\u{1F4C8}",
|
|
"\u{1F4C9}",
|
|
"\u{1F4CA}",
|
|
"\u{1F4CB}",
|
|
"\u{1F4CC}",
|
|
"\u{1F4CD}",
|
|
"\u{1F4CE}",
|
|
"\u{1F587}\uFE0F",
|
|
"\u{1F4CF}",
|
|
"\u{1F4D0}",
|
|
"\u2702\uFE0F",
|
|
"\u{1F5C3}\uFE0F",
|
|
"\u{1F5C4}\uFE0F",
|
|
"\u{1F5D1}\uFE0F",
|
|
"\u{1F512}",
|
|
"\u{1F513}",
|
|
"\u{1F50F}",
|
|
"\u{1F510}",
|
|
"\u{1F511}",
|
|
"\u{1F5DD}\uFE0F",
|
|
"\u{1F528}",
|
|
"\u{1FA93}",
|
|
"\u26CF\uFE0F",
|
|
"\u2692\uFE0F",
|
|
"\u{1F6E0}\uFE0F",
|
|
"\u{1F5E1}\uFE0F",
|
|
"\u2694\uFE0F",
|
|
"\u{1F4A3}",
|
|
"\u{1FA83}",
|
|
"\u{1F3F9}",
|
|
"\u{1F6E1}\uFE0F",
|
|
"\u{1FA9A}",
|
|
"\u{1F527}",
|
|
"\u{1FA9B}",
|
|
"\u{1F529}",
|
|
"\u2699\uFE0F",
|
|
"\u{1F5DC}\uFE0F",
|
|
"\u2696\uFE0F",
|
|
"\u{1F9AF}",
|
|
"\u{1F517}",
|
|
"\u26D3\uFE0F",
|
|
"\u{1FA9D}",
|
|
"\u{1F9F0}",
|
|
"\u{1F9F2}",
|
|
"\u{1FA9C}",
|
|
"\u2697\uFE0F",
|
|
"\u{1F9EA}",
|
|
"\u{1F9EB}",
|
|
"\u{1F9EC}",
|
|
"\u{1F52C}",
|
|
"\u{1F52D}",
|
|
"\u{1F4E1}",
|
|
"\u{1F489}",
|
|
"\u{1FA78}",
|
|
"\u{1F48A}",
|
|
"\u{1FA79}",
|
|
"\u{1FA7C}",
|
|
"\u{1FA7A}",
|
|
"\u{1FA7B}",
|
|
"\u{1F6AA}",
|
|
"\u{1F6D7}",
|
|
"\u{1FA9E}",
|
|
"\u{1FA9F}",
|
|
"\u{1F6CF}\uFE0F",
|
|
"\u{1F6CB}\uFE0F",
|
|
"\u{1FA91}",
|
|
"\u{1F6BD}",
|
|
"\u{1FAA0}",
|
|
"\u{1F6BF}",
|
|
"\u{1F6C1}",
|
|
"\u{1FAA4}",
|
|
"\u{1FA92}",
|
|
"\u{1F9F4}",
|
|
"\u{1F9F7}",
|
|
"\u{1F9F9}",
|
|
"\u{1F9FA}",
|
|
"\u{1F9FB}",
|
|
"\u{1FAA3}",
|
|
"\u{1F9FC}",
|
|
"\u{1FAE7}",
|
|
"\u{1FAA5}",
|
|
"\u{1F9FD}",
|
|
"\u{1F9EF}",
|
|
"\u{1F6D2}",
|
|
"\u{1F6AC}",
|
|
"\u26B0\uFE0F",
|
|
"\u{1FAA6}",
|
|
"\u26B1\uFE0F",
|
|
"\u{1F9FF}",
|
|
"\u{1FAAC}",
|
|
"\u{1F5FF}",
|
|
"\u{1FAA7}",
|
|
"\u{1FAAA}"
|
|
]
|
|
},
|
|
{
|
|
label: "Symbols",
|
|
icon: "\u{1F523}",
|
|
emojis: [
|
|
"\u{1F3E7}",
|
|
"\u{1F6AE}",
|
|
"\u{1F6B0}",
|
|
"\u267F",
|
|
"\u{1F6B9}",
|
|
"\u{1F6BA}",
|
|
"\u{1F6BB}",
|
|
"\u{1F6BC}",
|
|
"\u{1F6BE}",
|
|
"\u{1F6C2}",
|
|
"\u{1F6C3}",
|
|
"\u{1F6C4}",
|
|
"\u{1F6C5}",
|
|
"\u26A0\uFE0F",
|
|
"\u{1F6B8}",
|
|
"\u26D4",
|
|
"\u{1F6AB}",
|
|
"\u{1F6B3}",
|
|
"\u{1F6AD}",
|
|
"\u{1F6AF}",
|
|
"\u{1F6B1}",
|
|
"\u{1F6B7}",
|
|
"\u{1F4F5}",
|
|
"\u{1F51E}",
|
|
"\u2622\uFE0F",
|
|
"\u2623\uFE0F",
|
|
"\u2B06\uFE0F",
|
|
"\u2197\uFE0F",
|
|
"\u27A1\uFE0F",
|
|
"\u2198\uFE0F",
|
|
"\u2B07\uFE0F",
|
|
"\u2199\uFE0F",
|
|
"\u2B05\uFE0F",
|
|
"\u2196\uFE0F",
|
|
"\u2195\uFE0F",
|
|
"\u2194\uFE0F",
|
|
"\u21A9\uFE0F",
|
|
"\u21AA\uFE0F",
|
|
"\u2934\uFE0F",
|
|
"\u2935\uFE0F",
|
|
"\u{1F503}",
|
|
"\u{1F504}",
|
|
"\u{1F519}",
|
|
"\u{1F51A}",
|
|
"\u{1F51B}",
|
|
"\u{1F51C}",
|
|
"\u{1F51D}",
|
|
"\u{1F6D0}",
|
|
"\u269B\uFE0F",
|
|
"\u{1F549}\uFE0F",
|
|
"\u2721\uFE0F",
|
|
"\u2638\uFE0F",
|
|
"\u262F\uFE0F",
|
|
"\u271D\uFE0F",
|
|
"\u2626\uFE0F",
|
|
"\u262A\uFE0F",
|
|
"\u262E\uFE0F",
|
|
"\u{1F54E}",
|
|
"\u{1F52F}",
|
|
"\u{1FAAF}",
|
|
"\u2648",
|
|
"\u2649",
|
|
"\u264A",
|
|
"\u264B",
|
|
"\u264C",
|
|
"\u264D",
|
|
"\u264E",
|
|
"\u264F",
|
|
"\u2650",
|
|
"\u2651",
|
|
"\u2652",
|
|
"\u2653",
|
|
"\u26CE",
|
|
"\u{1F500}",
|
|
"\u{1F501}",
|
|
"\u{1F502}",
|
|
"\u25B6\uFE0F",
|
|
"\u23E9",
|
|
"\u23ED\uFE0F",
|
|
"\u23EF\uFE0F",
|
|
"\u25C0\uFE0F",
|
|
"\u23EA",
|
|
"\u23EE\uFE0F",
|
|
"\u{1F53C}",
|
|
"\u23EB",
|
|
"\u{1F53D}",
|
|
"\u23EC",
|
|
"\u23F8\uFE0F",
|
|
"\u23F9\uFE0F",
|
|
"\u23FA\uFE0F",
|
|
"\u23CF\uFE0F",
|
|
"\u{1F3A6}",
|
|
"\u{1F505}",
|
|
"\u{1F506}",
|
|
"\u{1F4F6}",
|
|
"\u{1F6DC}",
|
|
"\u{1F4F3}",
|
|
"\u{1F4F4}",
|
|
"\u2640\uFE0F",
|
|
"\u2642\uFE0F",
|
|
"\u26A7\uFE0F",
|
|
"\u2716\uFE0F",
|
|
"\u2795",
|
|
"\u2796",
|
|
"\u2797",
|
|
"\u{1F7F0}",
|
|
"\u267E\uFE0F",
|
|
"\u203C\uFE0F",
|
|
"\u2049\uFE0F",
|
|
"\u2753",
|
|
"\u2754",
|
|
"\u2755",
|
|
"\u2757",
|
|
"\u3030\uFE0F",
|
|
"\u{1F4B1}",
|
|
"\u{1F4B2}",
|
|
"\u2695\uFE0F",
|
|
"\u267B\uFE0F",
|
|
"\u269C\uFE0F",
|
|
"\u{1F531}",
|
|
"\u{1F4DB}",
|
|
"\u{1F530}",
|
|
"\u2B55",
|
|
"\u2705",
|
|
"\u2611\uFE0F",
|
|
"\u2714\uFE0F",
|
|
"\u274C",
|
|
"\u274E",
|
|
"\u27B0",
|
|
"\u27BF",
|
|
"\u303D\uFE0F",
|
|
"\u2733\uFE0F",
|
|
"\u2734\uFE0F",
|
|
"\u2747\uFE0F",
|
|
"\xA9\uFE0F",
|
|
"\xAE\uFE0F",
|
|
"\u2122\uFE0F",
|
|
"#\uFE0F\u20E3",
|
|
"*\uFE0F\u20E3",
|
|
"0\uFE0F\u20E3",
|
|
"1\uFE0F\u20E3",
|
|
"2\uFE0F\u20E3",
|
|
"3\uFE0F\u20E3",
|
|
"4\uFE0F\u20E3",
|
|
"5\uFE0F\u20E3",
|
|
"6\uFE0F\u20E3",
|
|
"7\uFE0F\u20E3",
|
|
"8\uFE0F\u20E3",
|
|
"9\uFE0F\u20E3",
|
|
"\u{1F51F}",
|
|
"\u{1F520}",
|
|
"\u{1F521}",
|
|
"\u{1F522}",
|
|
"\u{1F523}",
|
|
"\u{1F524}",
|
|
"\u{1F170}\uFE0F",
|
|
"\u{1F18E}",
|
|
"\u{1F171}\uFE0F",
|
|
"\u{1F191}",
|
|
"\u{1F192}",
|
|
"\u{1F193}",
|
|
"\u2139\uFE0F",
|
|
"\u{1F194}",
|
|
"\u24C2\uFE0F",
|
|
"\u{1F195}",
|
|
"\u{1F196}",
|
|
"\u{1F17E}\uFE0F",
|
|
"\u{1F197}",
|
|
"\u{1F17F}\uFE0F",
|
|
"\u{1F198}",
|
|
"\u{1F199}",
|
|
"\u{1F19A}",
|
|
"\u{1F201}",
|
|
"\u{1F202}\uFE0F",
|
|
"\u{1F237}\uFE0F",
|
|
"\u{1F236}",
|
|
"\u{1F22F}",
|
|
"\u{1F250}",
|
|
"\u{1F239}",
|
|
"\u{1F21A}",
|
|
"\u{1F232}",
|
|
"\u{1F251}",
|
|
"\u{1F238}",
|
|
"\u{1F234}",
|
|
"\u{1F233}",
|
|
"\u3297\uFE0F",
|
|
"\u3299\uFE0F",
|
|
"\u{1F23A}",
|
|
"\u{1F235}",
|
|
"\u{1F534}",
|
|
"\u{1F7E0}",
|
|
"\u{1F7E1}",
|
|
"\u{1F7E2}",
|
|
"\u{1F535}",
|
|
"\u{1F7E3}",
|
|
"\u{1F7E4}",
|
|
"\u26AB",
|
|
"\u26AA",
|
|
"\u{1F7E5}",
|
|
"\u{1F7E7}",
|
|
"\u{1F7E8}",
|
|
"\u{1F7E9}",
|
|
"\u{1F7E6}",
|
|
"\u{1F7EA}",
|
|
"\u{1F7EB}",
|
|
"\u2B1B",
|
|
"\u2B1C",
|
|
"\u25FC\uFE0F",
|
|
"\u25FB\uFE0F",
|
|
"\u25FE",
|
|
"\u25FD",
|
|
"\u25AA\uFE0F",
|
|
"\u25AB\uFE0F",
|
|
"\u{1F536}",
|
|
"\u{1F537}",
|
|
"\u{1F538}",
|
|
"\u{1F539}",
|
|
"\u{1F53A}",
|
|
"\u{1F53B}",
|
|
"\u{1F4A0}",
|
|
"\u{1F518}",
|
|
"\u{1F533}",
|
|
"\u{1F532}"
|
|
]
|
|
}
|
|
];
|
|
function getAllItems() {
|
|
let items = [];
|
|
for (let g of GROUPS)
|
|
for (let e of g.emojis)
|
|
items.push({ emoji: e, name: EMOJI_NAMES[e] || "" });
|
|
return items;
|
|
}
|
|
var VF_IconPickerModal = class extends import_obsidian5.Modal {
|
|
constructor(plugin2, onSubmit) {
|
|
super(plugin2.app);
|
|
this.plugin = plugin2;
|
|
this.onSubmit = onSubmit;
|
|
this.query = "";
|
|
this.activeGroup = 0;
|
|
}
|
|
onOpen() {
|
|
this.titleEl.setText("Manage icon");
|
|
this.modalEl.addClass("vf-icon-modal");
|
|
let searchInput = this.contentEl.createEl("input", {
|
|
type: "text",
|
|
placeholder: "Search...",
|
|
cls: "vf-icon-search"
|
|
});
|
|
let searchTimer = 0;
|
|
searchInput.addEventListener("input", () => {
|
|
if (searchTimer)
|
|
clearTimeout(searchTimer);
|
|
searchTimer = window.setTimeout(() => {
|
|
this.query = searchInput.value.toLowerCase();
|
|
this.renderGrid();
|
|
}, 120);
|
|
});
|
|
this.tabsEl = this.contentEl.createDiv({ cls: "vf-icon-tabs" });
|
|
this.gridEl = this.contentEl.createDiv({ cls: "vf-icon-grid" });
|
|
this.gridEl.addEventListener("click", (e) => {
|
|
let target = e.target.closest(".vf-icon-cell");
|
|
if (!target || !target.dataset.emoji)
|
|
return;
|
|
this.close();
|
|
this.onSubmit(target.dataset.emoji);
|
|
});
|
|
this.buildTabs();
|
|
this.renderGrid();
|
|
let removeBtn = this.contentEl.createEl("button", {
|
|
text: "Remove icon",
|
|
cls: "vf-icon-remove-btn"
|
|
});
|
|
removeBtn.addEventListener("click", () => {
|
|
this.close();
|
|
this.onSubmit("");
|
|
});
|
|
searchInput.focus();
|
|
}
|
|
buildTabs() {
|
|
for (let i = 0; i < GROUPS.length; i++) {
|
|
let tab = this.tabsEl.createDiv({ cls: "vf-icon-tab" });
|
|
tab.textContent = GROUPS[i].icon;
|
|
tab.title = GROUPS[i].label;
|
|
tab.addEventListener("click", () => {
|
|
this.activeGroup = i;
|
|
this.query = "";
|
|
let input = this.contentEl.querySelector(".vf-icon-search");
|
|
if (input)
|
|
input.value = "";
|
|
this.updateTabHighlight();
|
|
this.renderGrid();
|
|
});
|
|
}
|
|
this.updateTabHighlight();
|
|
}
|
|
updateTabHighlight() {
|
|
let tabs = this.tabsEl.children;
|
|
for (let i = 0; i < tabs.length; i++)
|
|
tabs[i].toggleClass("is-active", !this.query && i === this.activeGroup);
|
|
}
|
|
renderGrid() {
|
|
this.gridEl.empty();
|
|
this.updateTabHighlight();
|
|
let items;
|
|
if (this.query) {
|
|
let terms = this.query.split(/\s+/);
|
|
items = getAllItems().filter((item) => {
|
|
let text2 = (item.name + " " + item.emoji).toLowerCase();
|
|
return terms.every((t) => text2.includes(t));
|
|
});
|
|
} else {
|
|
let group = GROUPS[this.activeGroup];
|
|
items = group.emojis.map((e) => ({ emoji: e, name: EMOJI_NAMES[e] || "" }));
|
|
}
|
|
if (items.length === 0) {
|
|
this.gridEl.createDiv({ cls: "vf-icon-empty", text: "Nothing found" });
|
|
return;
|
|
}
|
|
let fragment = document.createDocumentFragment();
|
|
for (let item of items) {
|
|
let cell = document.createElement("div");
|
|
cell.className = "vf-icon-cell";
|
|
cell.textContent = item.emoji;
|
|
cell.dataset.emoji = item.emoji;
|
|
if (item.name)
|
|
cell.title = item.name;
|
|
fragment.appendChild(cell);
|
|
}
|
|
this.gridEl.appendChild(fragment);
|
|
}
|
|
};
|
|
|
|
// components/Note.svelte
|
|
function get_each_context(ctx, list, i) {
|
|
const child_ctx = ctx.slice();
|
|
child_ctx[43] = list[i];
|
|
child_ctx[44] = list;
|
|
child_ctx[45] = i;
|
|
return child_ctx;
|
|
}
|
|
function create_if_block_4(ctx) {
|
|
let div;
|
|
let collapsedIcon_action;
|
|
let mounted;
|
|
let dispose;
|
|
return {
|
|
c() {
|
|
div = element("div");
|
|
attr(div, "class", "tree-item-icon collapse-icon");
|
|
toggle_class(
|
|
div,
|
|
"is-collapsed",
|
|
/*isCollapsed*/
|
|
ctx[6]
|
|
);
|
|
},
|
|
m(target, anchor) {
|
|
insert(target, div, anchor);
|
|
if (!mounted) {
|
|
dispose = [
|
|
listen(div, "click", stop_propagation(
|
|
/*click_handler*/
|
|
ctx[34]
|
|
)),
|
|
action_destroyer(collapsedIcon_action = /*collapsedIcon*/
|
|
ctx[17].call(null, div))
|
|
];
|
|
mounted = true;
|
|
}
|
|
},
|
|
p(ctx2, dirty) {
|
|
if (dirty[0] & /*isCollapsed*/
|
|
64) {
|
|
toggle_class(
|
|
div,
|
|
"is-collapsed",
|
|
/*isCollapsed*/
|
|
ctx2[6]
|
|
);
|
|
}
|
|
},
|
|
d(detaching) {
|
|
if (detaching) {
|
|
detach(div);
|
|
}
|
|
mounted = false;
|
|
run_all(dispose);
|
|
}
|
|
};
|
|
}
|
|
function create_if_block_3(ctx) {
|
|
let span;
|
|
let t;
|
|
return {
|
|
c() {
|
|
span = element("span");
|
|
t = text(
|
|
/*noteIcon*/
|
|
ctx[4]
|
|
);
|
|
attr(span, "class", "vf-note-icon");
|
|
},
|
|
m(target, anchor) {
|
|
insert(target, span, anchor);
|
|
append(span, t);
|
|
},
|
|
p(ctx2, dirty) {
|
|
if (dirty[0] & /*noteIcon*/
|
|
16)
|
|
set_data(
|
|
t,
|
|
/*noteIcon*/
|
|
ctx2[4]
|
|
);
|
|
},
|
|
d(detaching) {
|
|
if (detaching) {
|
|
detach(span);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
function create_if_block_2(ctx) {
|
|
let span;
|
|
return {
|
|
c() {
|
|
span = element("span");
|
|
span.textContent = "\u{1F4CC}";
|
|
attr(span, "class", "vf-pin-icon");
|
|
},
|
|
m(target, anchor) {
|
|
insert(target, span, anchor);
|
|
},
|
|
d(detaching) {
|
|
if (detaching) {
|
|
detach(span);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
function create_if_block_1(ctx) {
|
|
let span;
|
|
let t;
|
|
return {
|
|
c() {
|
|
span = element("span");
|
|
t = text(
|
|
/*childCounter*/
|
|
ctx[8]
|
|
);
|
|
attr(span, "class", "vf-counter");
|
|
},
|
|
m(target, anchor) {
|
|
insert(target, span, anchor);
|
|
append(span, t);
|
|
},
|
|
p(ctx2, dirty) {
|
|
if (dirty[0] & /*childCounter*/
|
|
256)
|
|
set_data(
|
|
t,
|
|
/*childCounter*/
|
|
ctx2[8]
|
|
);
|
|
},
|
|
d(detaching) {
|
|
if (detaching) {
|
|
detach(span);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
function create_if_block(ctx) {
|
|
let div;
|
|
let each_blocks = [];
|
|
let each_1_lookup = /* @__PURE__ */ new Map();
|
|
let div_transition;
|
|
let current;
|
|
let mounted;
|
|
let dispose;
|
|
let each_value = ensure_array_like(
|
|
/*childList*/
|
|
ctx[9]
|
|
);
|
|
const get_key = (ctx2) => (
|
|
/*child*/
|
|
ctx2[43]
|
|
);
|
|
for (let i = 0; i < each_value.length; i += 1) {
|
|
let child_ctx = get_each_context(ctx, each_value, i);
|
|
let key = get_key(child_ctx);
|
|
each_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx));
|
|
}
|
|
return {
|
|
c() {
|
|
div = element("div");
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].c();
|
|
}
|
|
attr(div, "class", "tree-item-children");
|
|
},
|
|
m(target, anchor) {
|
|
insert(target, div, anchor);
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
if (each_blocks[i]) {
|
|
each_blocks[i].m(div, null);
|
|
}
|
|
}
|
|
current = true;
|
|
if (!mounted) {
|
|
dispose = [
|
|
listen(
|
|
div,
|
|
"introstart",
|
|
/*expandTransitionStart*/
|
|
ctx[18]
|
|
),
|
|
listen(
|
|
div,
|
|
"introend",
|
|
/*introend_handler*/
|
|
ctx[37]
|
|
)
|
|
];
|
|
mounted = true;
|
|
}
|
|
},
|
|
p(ctx2, dirty) {
|
|
if (dirty[0] & /*childList, build_path, children*/
|
|
526848) {
|
|
each_value = ensure_array_like(
|
|
/*childList*/
|
|
ctx2[9]
|
|
);
|
|
group_outros();
|
|
each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx2, each_value, each_1_lookup, div, outro_and_destroy_block, create_each_block, null, get_each_context);
|
|
check_outros();
|
|
}
|
|
},
|
|
i(local) {
|
|
if (current)
|
|
return;
|
|
for (let i = 0; i < each_value.length; i += 1) {
|
|
transition_in(each_blocks[i]);
|
|
}
|
|
if (local) {
|
|
add_render_callback(() => {
|
|
if (!current)
|
|
return;
|
|
if (!div_transition)
|
|
div_transition = create_bidirectional_transition(div, slide, { duration: 100 }, true);
|
|
div_transition.run(1);
|
|
});
|
|
}
|
|
current = true;
|
|
},
|
|
o(local) {
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
transition_out(each_blocks[i]);
|
|
}
|
|
if (local) {
|
|
if (!div_transition)
|
|
div_transition = create_bidirectional_transition(div, slide, { duration: 100 }, false);
|
|
div_transition.run(0);
|
|
}
|
|
current = false;
|
|
},
|
|
d(detaching) {
|
|
if (detaching) {
|
|
detach(div);
|
|
}
|
|
for (let i = 0; i < each_blocks.length; i += 1) {
|
|
each_blocks[i].d();
|
|
}
|
|
if (detaching && div_transition)
|
|
div_transition.end();
|
|
mounted = false;
|
|
run_all(dispose);
|
|
}
|
|
};
|
|
}
|
|
function create_each_block(key_1, ctx) {
|
|
let first;
|
|
let note_1;
|
|
let child = (
|
|
/*child*/
|
|
ctx[43]
|
|
);
|
|
let current;
|
|
const assign_note_1 = () => (
|
|
/*note_1_binding*/
|
|
ctx[36](note_1, child)
|
|
);
|
|
const unassign_note_1 = () => (
|
|
/*note_1_binding*/
|
|
ctx[36](null, child)
|
|
);
|
|
let note_1_props = {
|
|
id: (
|
|
/*child*/
|
|
ctx[43]
|
|
),
|
|
node_path: (
|
|
/*build_path*/
|
|
ctx[19](
|
|
/*child*/
|
|
ctx[43]
|
|
)
|
|
)
|
|
};
|
|
note_1 = new Note({ props: note_1_props });
|
|
assign_note_1();
|
|
return {
|
|
key: key_1,
|
|
first: null,
|
|
c() {
|
|
first = empty();
|
|
create_component(note_1.$$.fragment);
|
|
this.first = first;
|
|
},
|
|
m(target, anchor) {
|
|
insert(target, first, anchor);
|
|
mount_component(note_1, target, anchor);
|
|
current = true;
|
|
},
|
|
p(new_ctx, dirty) {
|
|
ctx = new_ctx;
|
|
if (child !== /*child*/
|
|
ctx[43]) {
|
|
unassign_note_1();
|
|
child = /*child*/
|
|
ctx[43];
|
|
assign_note_1();
|
|
}
|
|
const note_1_changes = {};
|
|
if (dirty[0] & /*childList*/
|
|
512)
|
|
note_1_changes.id = /*child*/
|
|
ctx[43];
|
|
if (dirty[0] & /*childList*/
|
|
512)
|
|
note_1_changes.node_path = /*build_path*/
|
|
ctx[19](
|
|
/*child*/
|
|
ctx[43]
|
|
);
|
|
note_1.$set(note_1_changes);
|
|
},
|
|
i(local) {
|
|
if (current)
|
|
return;
|
|
transition_in(note_1.$$.fragment, local);
|
|
current = true;
|
|
},
|
|
o(local) {
|
|
transition_out(note_1.$$.fragment, local);
|
|
current = false;
|
|
},
|
|
d(detaching) {
|
|
if (detaching) {
|
|
detach(first);
|
|
}
|
|
unassign_note_1();
|
|
destroy_component(note_1, detaching);
|
|
}
|
|
};
|
|
}
|
|
function create_fragment(ctx) {
|
|
let div2;
|
|
let div1;
|
|
let t0;
|
|
let div0;
|
|
let t1;
|
|
let t2;
|
|
let t3;
|
|
let t4;
|
|
let div1_class_value;
|
|
let div1_draggable_value;
|
|
let applyDataAttrs_action;
|
|
let t5;
|
|
let current;
|
|
let mounted;
|
|
let dispose;
|
|
let if_block0 = (
|
|
/*childCounter*/
|
|
ctx[8] > 0 && create_if_block_4(ctx)
|
|
);
|
|
let if_block1 = (
|
|
/*noteIcon*/
|
|
ctx[4] && create_if_block_3(ctx)
|
|
);
|
|
let if_block2 = (
|
|
/*isPinned*/
|
|
ctx[5] && create_if_block_2(ctx)
|
|
);
|
|
let if_block3 = (
|
|
/*childCounter*/
|
|
ctx[8] > 0 && create_if_block_1(ctx)
|
|
);
|
|
let if_block4 = (
|
|
/*childCounter*/
|
|
ctx[8] > 0 && !/*isCollapsed*/
|
|
ctx[6] && create_if_block(ctx)
|
|
);
|
|
return {
|
|
c() {
|
|
div2 = element("div");
|
|
div1 = element("div");
|
|
if (if_block0)
|
|
if_block0.c();
|
|
t0 = space();
|
|
div0 = element("div");
|
|
if (if_block1)
|
|
if_block1.c();
|
|
t1 = space();
|
|
t2 = text(
|
|
/*title*/
|
|
ctx[3]
|
|
);
|
|
t3 = space();
|
|
if (if_block2)
|
|
if_block2.c();
|
|
t4 = space();
|
|
if (if_block3)
|
|
if_block3.c();
|
|
t5 = space();
|
|
if (if_block4)
|
|
if_block4.c();
|
|
attr(div0, "class", "tree-item-inner");
|
|
attr(div1, "class", div1_class_value = "tree-item-self is-clickable mod-collapsible " + /*IsOpened*/
|
|
(ctx[2] ? "vf-current-note" : ""));
|
|
attr(
|
|
div1,
|
|
"style",
|
|
/*tagHighlightStyle*/
|
|
ctx[14]
|
|
);
|
|
attr(div1, "draggable", div1_draggable_value = /*type*/
|
|
ctx[1] === "sub_note");
|
|
toggle_class(
|
|
div1,
|
|
"vf-tag-highlight",
|
|
/*tagHighlightStyle*/
|
|
ctx[14] !== ""
|
|
);
|
|
toggle_class(
|
|
div1,
|
|
"vf-drop-target",
|
|
/*dropMode*/
|
|
ctx[13] === "target"
|
|
);
|
|
toggle_class(
|
|
div1,
|
|
"vf-drop-before",
|
|
/*dropMode*/
|
|
ctx[13] === "before"
|
|
);
|
|
toggle_class(
|
|
div1,
|
|
"vf-drop-after",
|
|
/*dropMode*/
|
|
ctx[13] === "after"
|
|
);
|
|
attr(div2, "class", "tree-item is-clickable");
|
|
},
|
|
m(target, anchor) {
|
|
insert(target, div2, anchor);
|
|
append(div2, div1);
|
|
if (if_block0)
|
|
if_block0.m(div1, null);
|
|
append(div1, t0);
|
|
append(div1, div0);
|
|
if (if_block1)
|
|
if_block1.m(div0, null);
|
|
append(div0, t1);
|
|
append(div0, t2);
|
|
append(div0, t3);
|
|
if (if_block2)
|
|
if_block2.m(div0, null);
|
|
append(div1, t4);
|
|
if (if_block3)
|
|
if_block3.m(div1, null);
|
|
append(div2, t5);
|
|
if (if_block4)
|
|
if_block4.m(div2, null);
|
|
ctx[38](div2);
|
|
current = true;
|
|
if (!mounted) {
|
|
dispose = [
|
|
action_destroyer(applyDataAttrs_action = /*applyDataAttrs*/
|
|
ctx[16].call(
|
|
null,
|
|
div1,
|
|
/*dataAttrs*/
|
|
ctx[7]
|
|
)),
|
|
listen(
|
|
div1,
|
|
"dragstart",
|
|
/*handleDragStart*/
|
|
ctx[21]
|
|
),
|
|
listen(div1, "dragover", prevent_default(
|
|
/*handleDragOver*/
|
|
ctx[22]
|
|
)),
|
|
listen(
|
|
div1,
|
|
"dragleave",
|
|
/*handleDragLeave*/
|
|
ctx[23]
|
|
),
|
|
listen(
|
|
div1,
|
|
"drop",
|
|
/*handleDrop*/
|
|
ctx[24]
|
|
),
|
|
listen(
|
|
div1,
|
|
"contextmenu",
|
|
/*handleContextMenu*/
|
|
ctx[25]
|
|
),
|
|
listen(
|
|
div1,
|
|
"click",
|
|
/*click_handler_1*/
|
|
ctx[35]
|
|
)
|
|
];
|
|
mounted = true;
|
|
}
|
|
},
|
|
p(ctx2, dirty) {
|
|
if (
|
|
/*childCounter*/
|
|
ctx2[8] > 0
|
|
) {
|
|
if (if_block0) {
|
|
if_block0.p(ctx2, dirty);
|
|
} else {
|
|
if_block0 = create_if_block_4(ctx2);
|
|
if_block0.c();
|
|
if_block0.m(div1, t0);
|
|
}
|
|
} else if (if_block0) {
|
|
if_block0.d(1);
|
|
if_block0 = null;
|
|
}
|
|
if (
|
|
/*noteIcon*/
|
|
ctx2[4]
|
|
) {
|
|
if (if_block1) {
|
|
if_block1.p(ctx2, dirty);
|
|
} else {
|
|
if_block1 = create_if_block_3(ctx2);
|
|
if_block1.c();
|
|
if_block1.m(div0, t1);
|
|
}
|
|
} else if (if_block1) {
|
|
if_block1.d(1);
|
|
if_block1 = null;
|
|
}
|
|
if (!current || dirty[0] & /*title*/
|
|
8)
|
|
set_data(
|
|
t2,
|
|
/*title*/
|
|
ctx2[3]
|
|
);
|
|
if (
|
|
/*isPinned*/
|
|
ctx2[5]
|
|
) {
|
|
if (if_block2) {
|
|
} else {
|
|
if_block2 = create_if_block_2(ctx2);
|
|
if_block2.c();
|
|
if_block2.m(div0, null);
|
|
}
|
|
} else if (if_block2) {
|
|
if_block2.d(1);
|
|
if_block2 = null;
|
|
}
|
|
if (
|
|
/*childCounter*/
|
|
ctx2[8] > 0
|
|
) {
|
|
if (if_block3) {
|
|
if_block3.p(ctx2, dirty);
|
|
} else {
|
|
if_block3 = create_if_block_1(ctx2);
|
|
if_block3.c();
|
|
if_block3.m(div1, null);
|
|
}
|
|
} else if (if_block3) {
|
|
if_block3.d(1);
|
|
if_block3 = null;
|
|
}
|
|
if (!current || dirty[0] & /*IsOpened*/
|
|
4 && div1_class_value !== (div1_class_value = "tree-item-self is-clickable mod-collapsible " + /*IsOpened*/
|
|
(ctx2[2] ? "vf-current-note" : ""))) {
|
|
attr(div1, "class", div1_class_value);
|
|
}
|
|
if (!current || dirty[0] & /*tagHighlightStyle*/
|
|
16384) {
|
|
attr(
|
|
div1,
|
|
"style",
|
|
/*tagHighlightStyle*/
|
|
ctx2[14]
|
|
);
|
|
}
|
|
if (!current || dirty[0] & /*type*/
|
|
2 && div1_draggable_value !== (div1_draggable_value = /*type*/
|
|
ctx2[1] === "sub_note")) {
|
|
attr(div1, "draggable", div1_draggable_value);
|
|
}
|
|
if (applyDataAttrs_action && is_function(applyDataAttrs_action.update) && dirty[0] & /*dataAttrs*/
|
|
128)
|
|
applyDataAttrs_action.update.call(
|
|
null,
|
|
/*dataAttrs*/
|
|
ctx2[7]
|
|
);
|
|
if (!current || dirty[0] & /*IsOpened, tagHighlightStyle*/
|
|
16388) {
|
|
toggle_class(
|
|
div1,
|
|
"vf-tag-highlight",
|
|
/*tagHighlightStyle*/
|
|
ctx2[14] !== ""
|
|
);
|
|
}
|
|
if (!current || dirty[0] & /*IsOpened, dropMode*/
|
|
8196) {
|
|
toggle_class(
|
|
div1,
|
|
"vf-drop-target",
|
|
/*dropMode*/
|
|
ctx2[13] === "target"
|
|
);
|
|
}
|
|
if (!current || dirty[0] & /*IsOpened, dropMode*/
|
|
8196) {
|
|
toggle_class(
|
|
div1,
|
|
"vf-drop-before",
|
|
/*dropMode*/
|
|
ctx2[13] === "before"
|
|
);
|
|
}
|
|
if (!current || dirty[0] & /*IsOpened, dropMode*/
|
|
8196) {
|
|
toggle_class(
|
|
div1,
|
|
"vf-drop-after",
|
|
/*dropMode*/
|
|
ctx2[13] === "after"
|
|
);
|
|
}
|
|
if (
|
|
/*childCounter*/
|
|
ctx2[8] > 0 && !/*isCollapsed*/
|
|
ctx2[6]
|
|
) {
|
|
if (if_block4) {
|
|
if_block4.p(ctx2, dirty);
|
|
if (dirty[0] & /*childCounter, isCollapsed*/
|
|
320) {
|
|
transition_in(if_block4, 1);
|
|
}
|
|
} else {
|
|
if_block4 = create_if_block(ctx2);
|
|
if_block4.c();
|
|
transition_in(if_block4, 1);
|
|
if_block4.m(div2, null);
|
|
}
|
|
} else if (if_block4) {
|
|
group_outros();
|
|
transition_out(if_block4, 1, 1, () => {
|
|
if_block4 = null;
|
|
});
|
|
check_outros();
|
|
}
|
|
},
|
|
i(local) {
|
|
if (current)
|
|
return;
|
|
transition_in(if_block4);
|
|
current = true;
|
|
},
|
|
o(local) {
|
|
transition_out(if_block4);
|
|
current = false;
|
|
},
|
|
d(detaching) {
|
|
if (detaching) {
|
|
detach(div2);
|
|
}
|
|
if (if_block0)
|
|
if_block0.d();
|
|
if (if_block1)
|
|
if_block1.d();
|
|
if (if_block2)
|
|
if_block2.d();
|
|
if (if_block3)
|
|
if_block3.d();
|
|
if (if_block4)
|
|
if_block4.d();
|
|
ctx[38](null);
|
|
mounted = false;
|
|
run_all(dispose);
|
|
}
|
|
};
|
|
}
|
|
function instance($$self, $$props, $$invalidate) {
|
|
let tagHighlightStyle;
|
|
let $data;
|
|
let $active_id;
|
|
component_subscribe($$self, data, ($$value) => $$invalidate(32, $data = $$value));
|
|
component_subscribe($$self, active_id, ($$value) => $$invalidate(33, $active_id = $$value));
|
|
let { id = "unknown-link-id" } = $$props;
|
|
let { type = "sub_note" } = $$props;
|
|
let { node_path = [] } = $$props;
|
|
let plugin2 = getPlugin();
|
|
let note;
|
|
let title = id;
|
|
let noteIcon = "";
|
|
let isPinned = false;
|
|
let isCollapsed = true;
|
|
let IsOpened = false;
|
|
let highlightColor = "";
|
|
let highlightOpacity = 0;
|
|
let dataAttrs = {};
|
|
let childCounter = 0;
|
|
let childList = [];
|
|
let myElement;
|
|
const children2 = {};
|
|
const applyDataAttrs = function(node, attrs) {
|
|
let prev = [];
|
|
function update2(newAttrs) {
|
|
for (let key of prev)
|
|
node.removeAttribute(key);
|
|
prev = Object.keys(newAttrs);
|
|
for (let key of prev)
|
|
node.setAttribute(key, newAttrs[key]);
|
|
}
|
|
update2(attrs);
|
|
return { update: update2 };
|
|
};
|
|
const collapsedIcon = function(node) {
|
|
node.appendChild((0, import_obsidian6.getIcon)("right-triangle"));
|
|
};
|
|
let expandTransitionWaiter = Promise.resolve();
|
|
let expandTransitionEnd;
|
|
function expandTransitionStart() {
|
|
expandTransitionWaiter = new Promise((resolve) => {
|
|
$$invalidate(12, expandTransitionEnd = resolve);
|
|
});
|
|
}
|
|
function build_path(id2) {
|
|
return node_path.concat([id2]);
|
|
}
|
|
function openNote(id2, new_tab = false) {
|
|
if (type == "top_dir" || type == "orphan_dir") {
|
|
return;
|
|
}
|
|
plugin2.app.workspace.openLinkText(id2, id2, new_tab);
|
|
}
|
|
function scrollIntoMiddle() {
|
|
let scrollable = myElement.closest(".view-content");
|
|
if (!scrollable)
|
|
return;
|
|
let elementRect = myElement.getBoundingClientRect();
|
|
let containerRect = scrollable.getBoundingClientRect();
|
|
let elementTopRelative = elementRect.top - containerRect.top + scrollable.scrollTop;
|
|
let elementHeight = elementRect.height;
|
|
let containerHeight = containerRect.height;
|
|
if (elementHeight <= containerHeight) {
|
|
let targetTop = elementTopRelative - containerHeight / 2 + elementHeight / 2;
|
|
scrollable.scrollTop = targetTop;
|
|
} else {
|
|
scrollable.scrollTop = elementTopRelative;
|
|
}
|
|
}
|
|
let dropMode = "none";
|
|
function getDragParentId() {
|
|
let parentId = node_path[node_path.length - 2];
|
|
if (parentId === "top_dir" || parentId === "orphan_dir")
|
|
return null;
|
|
return parentId;
|
|
}
|
|
function getRawParentId() {
|
|
return node_path.length >= 2 ? node_path[node_path.length - 2] : null;
|
|
}
|
|
function handleDragStart(event) {
|
|
if (type !== "sub_note" || !event.dataTransfer)
|
|
return;
|
|
event.dataTransfer.setData("text/plain", JSON.stringify({
|
|
id,
|
|
parentId: getDragParentId(),
|
|
rawParentId: getRawParentId()
|
|
}));
|
|
event.dataTransfer.effectAllowed = "move";
|
|
}
|
|
function handleDragOver(event) {
|
|
event.preventDefault();
|
|
if (event.dataTransfer)
|
|
event.dataTransfer.dropEffect = "move";
|
|
if (plugin2.settings.sortTreeBy === "custom" /* custom */ && type === "sub_note") {
|
|
let rect = event.currentTarget.getBoundingClientRect();
|
|
$$invalidate(13, dropMode = event.clientY < rect.top + rect.height / 2 ? "before" : "after");
|
|
} else {
|
|
$$invalidate(13, dropMode = "target");
|
|
}
|
|
}
|
|
function handleDragLeave() {
|
|
$$invalidate(13, dropMode = "none");
|
|
}
|
|
function handleDrop(event) {
|
|
event.preventDefault();
|
|
$$invalidate(13, dropMode = "none");
|
|
if (!event.dataTransfer)
|
|
return;
|
|
let dragData;
|
|
try {
|
|
dragData = JSON.parse(event.dataTransfer.getData("text/plain"));
|
|
} catch (_a) {
|
|
return;
|
|
}
|
|
let draggedId = dragData.id;
|
|
let oldParentId = dragData.parentId;
|
|
let draggedRawParent = dragData.rawParentId;
|
|
if (draggedId === id || node_path.includes(draggedId)) {
|
|
new import_obsidian6.Notice("Can't move a folder into itself");
|
|
return;
|
|
}
|
|
let myRawParent = getRawParentId();
|
|
if (draggedRawParent && draggedRawParent === myRawParent && plugin2.settings.sortTreeBy === "custom" /* custom */ && type === "sub_note") {
|
|
let rect = event.currentTarget.getBoundingClientRect();
|
|
let insertBefore = event.clientY < rect.top + rect.height / 2;
|
|
plugin2.reorderNote(draggedId, id, draggedRawParent, insertBefore);
|
|
return;
|
|
}
|
|
let newParentId = null;
|
|
if (type === "sub_note")
|
|
newParentId = id;
|
|
if (oldParentId === newParentId)
|
|
return;
|
|
plugin2.moveNoteToFolder(draggedId, oldParentId, newParentId);
|
|
}
|
|
function handleContextMenu(event) {
|
|
var _a, _b;
|
|
if (type !== "sub_note" && type !== "top_dir")
|
|
return;
|
|
event.preventDefault();
|
|
const menu = new import_obsidian6.Menu();
|
|
let folderId = type === "top_dir" ? null : id;
|
|
menu.addItem((item) => {
|
|
item.setTitle("Create note").setIcon("plus").onClick(() => {
|
|
plugin2.createNoteInFolder(folderId);
|
|
});
|
|
});
|
|
if ((_b = (_a = plugin2.app.internalPlugins) === null || _a === void 0 ? void 0 : _a.getPluginById("zk-prefixer")) === null || _b === void 0 ? void 0 : _b.enabled) {
|
|
menu.addItem((item) => {
|
|
item.setTitle("Create unique note").setIcon("fingerprint").onClick(() => {
|
|
plugin2.createNoteInFolder(folderId, true);
|
|
});
|
|
});
|
|
}
|
|
if (type === "sub_note") {
|
|
let file = plugin2.app.vault.getFileByPath(id);
|
|
if (file) {
|
|
menu.addItem((item) => {
|
|
item.setTitle("Manage icon").setIcon("image").onClick(() => {
|
|
new VF_IconPickerModal(
|
|
plugin2,
|
|
(icon) => {
|
|
let f = plugin2.app.vault.getFileByPath(id);
|
|
if (!f)
|
|
return;
|
|
plugin2.yaml.set_icon(f, icon);
|
|
plugin2.update_data();
|
|
}
|
|
).open();
|
|
});
|
|
});
|
|
let isPinned2 = note ? note.is_pinned : false;
|
|
menu.addItem((item) => {
|
|
item.setTitle(isPinned2 ? "Unpin note" : "Pin note").setIcon("pin").onClick(() => {
|
|
let f = plugin2.app.vault.getFileByPath(id);
|
|
if (!f)
|
|
return;
|
|
plugin2.yaml.toggle_pin(f, !isPinned2);
|
|
plugin2.update_data();
|
|
});
|
|
});
|
|
}
|
|
menu.addSeparator();
|
|
menu.addItem((item) => {
|
|
item.setTitle("Delete note").setIcon("trash-2").onClick(() => {
|
|
plugin2.deleteNote(id);
|
|
});
|
|
});
|
|
if (note && note.has_children()) {
|
|
menu.addItem((item) => {
|
|
item.setTitle("Delete with children").setIcon("trash-2").onClick(() => {
|
|
plugin2.deleteNoteRecursive(id);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
menu.showAtMouseEvent(event);
|
|
}
|
|
const collapse = () => {
|
|
$$invalidate(6, isCollapsed = true);
|
|
};
|
|
const focusNotes = (pathNotes) => __awaiter(void 0, void 0, void 0, function* () {
|
|
$$invalidate(6, isCollapsed = false);
|
|
yield tick();
|
|
let next = pathNotes.shift();
|
|
if (next && plugin2.settings.autoCollapse) {
|
|
for (let key in children2) {
|
|
if (key !== next)
|
|
children2[key].collapse();
|
|
}
|
|
}
|
|
if (pathNotes.length === 0)
|
|
yield expandTransitionWaiter;
|
|
if (!next) {
|
|
if (myElement) {
|
|
scrollIntoMiddle();
|
|
}
|
|
return;
|
|
}
|
|
if (next in children2) {
|
|
children2[next].focusNotes(pathNotes);
|
|
}
|
|
});
|
|
const click_handler = () => {
|
|
$$invalidate(6, isCollapsed = !isCollapsed);
|
|
};
|
|
const click_handler_1 = (event) => {
|
|
if (event.shiftKey) {
|
|
openNote(id, false);
|
|
return;
|
|
}
|
|
if (event.ctrlKey) {
|
|
openNote(id, true);
|
|
return;
|
|
}
|
|
if (plugin2.settings.expandOnClick)
|
|
$$invalidate(6, isCollapsed = !isCollapsed);
|
|
openNote(id);
|
|
};
|
|
function note_1_binding($$value, child) {
|
|
binding_callbacks[$$value ? "unshift" : "push"](() => {
|
|
children2[child] = $$value;
|
|
$$invalidate(11, children2);
|
|
});
|
|
}
|
|
const introend_handler = () => {
|
|
expandTransitionEnd();
|
|
};
|
|
function div2_binding($$value) {
|
|
binding_callbacks[$$value ? "unshift" : "push"](() => {
|
|
myElement = $$value;
|
|
$$invalidate(10, myElement);
|
|
});
|
|
}
|
|
$$self.$$set = ($$props2) => {
|
|
if ("id" in $$props2)
|
|
$$invalidate(0, id = $$props2.id);
|
|
if ("type" in $$props2)
|
|
$$invalidate(1, type = $$props2.type);
|
|
if ("node_path" in $$props2)
|
|
$$invalidate(26, node_path = $$props2.node_path);
|
|
};
|
|
$$self.$$.update = () => {
|
|
if ($$self.$$.dirty[0] & /*id, type, note*/
|
|
536870915 | $$self.$$.dirty[1] & /*$active_id, $data*/
|
|
6) {
|
|
$: {
|
|
$$invalidate(2, IsOpened = id == $active_id);
|
|
if (type == "top_dir") {
|
|
$$invalidate(3, title = "ROOT");
|
|
$$invalidate(8, childCounter = $data.top_list.length);
|
|
$$invalidate(9, childList = $data.top_list);
|
|
$$invalidate(7, dataAttrs = {});
|
|
}
|
|
if (type == "orphan_dir") {
|
|
$$invalidate(3, title = "Orphans");
|
|
$$invalidate(8, childCounter = $data.orphans_list.length);
|
|
$$invalidate(9, childList = $data.orphans_list);
|
|
$$invalidate(7, dataAttrs = {});
|
|
}
|
|
if (type == "sub_note") {
|
|
$$invalidate(29, note = $data.note_list[id]);
|
|
if (note) {
|
|
$$invalidate(3, title = note.title);
|
|
$$invalidate(4, noteIcon = note.icon || "");
|
|
$$invalidate(5, isPinned = note.is_pinned);
|
|
$$invalidate(30, highlightColor = note.highlight_color || "");
|
|
$$invalidate(31, highlightOpacity = note.highlight_opacity || 0);
|
|
$$invalidate(8, childCounter = note.count_children());
|
|
$$invalidate(9, childList = note.children);
|
|
let attrs = {};
|
|
for (let key in note.metadata) {
|
|
attrs["data-" + key] = note.metadata[key];
|
|
}
|
|
$$invalidate(7, dataAttrs = attrs);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($$self.$$.dirty[0] & /*highlightColor, IsOpened*/
|
|
1073741828 | $$self.$$.dirty[1] & /*highlightOpacity*/
|
|
1) {
|
|
$:
|
|
$$invalidate(14, tagHighlightStyle = highlightColor && highlightOpacity > 0 && !IsOpened ? `background-color: color-mix(in srgb, ${highlightColor} ${highlightOpacity * 100}%, transparent)` : "");
|
|
}
|
|
};
|
|
return [
|
|
id,
|
|
type,
|
|
IsOpened,
|
|
title,
|
|
noteIcon,
|
|
isPinned,
|
|
isCollapsed,
|
|
dataAttrs,
|
|
childCounter,
|
|
childList,
|
|
myElement,
|
|
children2,
|
|
expandTransitionEnd,
|
|
dropMode,
|
|
tagHighlightStyle,
|
|
plugin2,
|
|
applyDataAttrs,
|
|
collapsedIcon,
|
|
expandTransitionStart,
|
|
build_path,
|
|
openNote,
|
|
handleDragStart,
|
|
handleDragOver,
|
|
handleDragLeave,
|
|
handleDrop,
|
|
handleContextMenu,
|
|
node_path,
|
|
collapse,
|
|
focusNotes,
|
|
note,
|
|
highlightColor,
|
|
highlightOpacity,
|
|
$data,
|
|
$active_id,
|
|
click_handler,
|
|
click_handler_1,
|
|
note_1_binding,
|
|
introend_handler,
|
|
div2_binding
|
|
];
|
|
}
|
|
var Note = class extends SvelteComponent {
|
|
constructor(options) {
|
|
super();
|
|
init(
|
|
this,
|
|
options,
|
|
instance,
|
|
create_fragment,
|
|
safe_not_equal,
|
|
{
|
|
id: 0,
|
|
type: 1,
|
|
node_path: 26,
|
|
collapse: 27,
|
|
focusNotes: 28
|
|
},
|
|
null,
|
|
[-1, -1]
|
|
);
|
|
}
|
|
get collapse() {
|
|
return this.$$.ctx[27];
|
|
}
|
|
get focusNotes() {
|
|
return this.$$.ctx[28];
|
|
}
|
|
};
|
|
var Note_default = Note;
|
|
|
|
// components/Component.svelte
|
|
function create_if_block2(ctx) {
|
|
let note;
|
|
let t;
|
|
let if_block_anchor;
|
|
let current;
|
|
let note_props = { type: "top_dir", node_path: ["top_dir"] };
|
|
note = new Note_default({ props: note_props });
|
|
ctx[3](note);
|
|
let if_block = (
|
|
/*$data*/
|
|
ctx[1].orphans_list.length && !/*$data*/
|
|
ctx[1].settings.hide_orphans && create_if_block_12(ctx)
|
|
);
|
|
return {
|
|
c() {
|
|
create_component(note.$$.fragment);
|
|
t = space();
|
|
if (if_block)
|
|
if_block.c();
|
|
if_block_anchor = empty();
|
|
},
|
|
m(target, anchor) {
|
|
mount_component(note, target, anchor);
|
|
insert(target, t, anchor);
|
|
if (if_block)
|
|
if_block.m(target, anchor);
|
|
insert(target, if_block_anchor, anchor);
|
|
current = true;
|
|
},
|
|
p(ctx2, dirty) {
|
|
const note_changes = {};
|
|
note.$set(note_changes);
|
|
if (
|
|
/*$data*/
|
|
ctx2[1].orphans_list.length && !/*$data*/
|
|
ctx2[1].settings.hide_orphans
|
|
) {
|
|
if (if_block) {
|
|
if_block.p(ctx2, dirty);
|
|
if (dirty & /*$data*/
|
|
2) {
|
|
transition_in(if_block, 1);
|
|
}
|
|
} else {
|
|
if_block = create_if_block_12(ctx2);
|
|
if_block.c();
|
|
transition_in(if_block, 1);
|
|
if_block.m(if_block_anchor.parentNode, if_block_anchor);
|
|
}
|
|
} else if (if_block) {
|
|
group_outros();
|
|
transition_out(if_block, 1, 1, () => {
|
|
if_block = null;
|
|
});
|
|
check_outros();
|
|
}
|
|
},
|
|
i(local) {
|
|
if (current)
|
|
return;
|
|
transition_in(note.$$.fragment, local);
|
|
transition_in(if_block);
|
|
current = true;
|
|
},
|
|
o(local) {
|
|
transition_out(note.$$.fragment, local);
|
|
transition_out(if_block);
|
|
current = false;
|
|
},
|
|
d(detaching) {
|
|
if (detaching) {
|
|
detach(t);
|
|
detach(if_block_anchor);
|
|
}
|
|
ctx[3](null);
|
|
destroy_component(note, detaching);
|
|
if (if_block)
|
|
if_block.d(detaching);
|
|
}
|
|
};
|
|
}
|
|
function create_if_block_12(ctx) {
|
|
let note;
|
|
let current;
|
|
let note_props = {
|
|
type: "orphan_dir",
|
|
node_path: ["orphan_dir"]
|
|
};
|
|
note = new Note_default({ props: note_props });
|
|
ctx[4](note);
|
|
return {
|
|
c() {
|
|
create_component(note.$$.fragment);
|
|
},
|
|
m(target, anchor) {
|
|
mount_component(note, target, anchor);
|
|
current = true;
|
|
},
|
|
p(ctx2, dirty) {
|
|
const note_changes = {};
|
|
note.$set(note_changes);
|
|
},
|
|
i(local) {
|
|
if (current)
|
|
return;
|
|
transition_in(note.$$.fragment, local);
|
|
current = true;
|
|
},
|
|
o(local) {
|
|
transition_out(note.$$.fragment, local);
|
|
current = false;
|
|
},
|
|
d(detaching) {
|
|
ctx[4](null);
|
|
destroy_component(note, detaching);
|
|
}
|
|
};
|
|
}
|
|
function create_fragment2(ctx) {
|
|
let if_block_anchor;
|
|
let current;
|
|
let if_block = (
|
|
/*$data*/
|
|
ctx[1] !== void 0 && create_if_block2(ctx)
|
|
);
|
|
return {
|
|
c() {
|
|
if (if_block)
|
|
if_block.c();
|
|
if_block_anchor = empty();
|
|
},
|
|
m(target, anchor) {
|
|
if (if_block)
|
|
if_block.m(target, anchor);
|
|
insert(target, if_block_anchor, anchor);
|
|
current = true;
|
|
},
|
|
p(ctx2, [dirty]) {
|
|
if (
|
|
/*$data*/
|
|
ctx2[1] !== void 0
|
|
) {
|
|
if (if_block) {
|
|
if_block.p(ctx2, dirty);
|
|
if (dirty & /*$data*/
|
|
2) {
|
|
transition_in(if_block, 1);
|
|
}
|
|
} else {
|
|
if_block = create_if_block2(ctx2);
|
|
if_block.c();
|
|
transition_in(if_block, 1);
|
|
if_block.m(if_block_anchor.parentNode, if_block_anchor);
|
|
}
|
|
} else if (if_block) {
|
|
group_outros();
|
|
transition_out(if_block, 1, 1, () => {
|
|
if_block = null;
|
|
});
|
|
check_outros();
|
|
}
|
|
},
|
|
i(local) {
|
|
if (current)
|
|
return;
|
|
transition_in(if_block);
|
|
current = true;
|
|
},
|
|
o(local) {
|
|
transition_out(if_block);
|
|
current = false;
|
|
},
|
|
d(detaching) {
|
|
if (detaching) {
|
|
detach(if_block_anchor);
|
|
}
|
|
if (if_block)
|
|
if_block.d(detaching);
|
|
}
|
|
};
|
|
}
|
|
function instance2($$self, $$props, $$invalidate) {
|
|
let $data;
|
|
component_subscribe($$self, data, ($$value) => $$invalidate(1, $data = $$value));
|
|
const children2 = {};
|
|
function focusTo(pathNotes) {
|
|
let first = pathNotes.shift();
|
|
if (!first || !(first in children2))
|
|
return;
|
|
children2[first].focusNotes(pathNotes);
|
|
}
|
|
function note_binding($$value) {
|
|
binding_callbacks[$$value ? "unshift" : "push"](() => {
|
|
children2["top_dir"] = $$value;
|
|
$$invalidate(0, children2);
|
|
});
|
|
}
|
|
function note_binding_1($$value) {
|
|
binding_callbacks[$$value ? "unshift" : "push"](() => {
|
|
children2["orphan_dir"] = $$value;
|
|
$$invalidate(0, children2);
|
|
});
|
|
}
|
|
return [children2, $data, focusTo, note_binding, note_binding_1];
|
|
}
|
|
var Component = class extends SvelteComponent {
|
|
constructor(options) {
|
|
super();
|
|
init(this, options, instance2, create_fragment2, safe_not_equal, { focusTo: 2 });
|
|
}
|
|
get focusTo() {
|
|
return this.$$.ctx[2];
|
|
}
|
|
};
|
|
var Component_default = Component;
|
|
|
|
// tree_view.ts
|
|
var TREE_ICON = "folder-tree";
|
|
var VIEW_TYPE_VF = "virt-folder-view";
|
|
var VirtFolderView = class extends import_obsidian7.ItemView {
|
|
constructor(leaf, plugin2) {
|
|
super(leaf);
|
|
this.plugin = plugin2;
|
|
this.icon = TREE_ICON;
|
|
}
|
|
getViewType() {
|
|
return VIEW_TYPE_VF;
|
|
}
|
|
getDisplayText() {
|
|
return "VirtFolder";
|
|
}
|
|
async onOpen() {
|
|
plugin.set(this.plugin);
|
|
this.component = new Component_default({
|
|
target: this.contentEl
|
|
});
|
|
}
|
|
async onClose() {
|
|
this.component.$destroy();
|
|
}
|
|
getComponent() {
|
|
return this.component;
|
|
}
|
|
};
|
|
|
|
// yaml_parser.ts
|
|
var import_obsidian8 = require("obsidian");
|
|
var YamlParser = class {
|
|
constructor(app, plugin2) {
|
|
this.app = app;
|
|
this.plugin = plugin2;
|
|
}
|
|
showMessage(msg) {
|
|
new import_obsidian8.Notice(msg);
|
|
}
|
|
_ensure_array(front, prop) {
|
|
if (prop in front && front[prop] && !Array.isArray(front[prop])) {
|
|
front[prop] = [front[prop]];
|
|
}
|
|
}
|
|
_normalize_prop(front, prop) {
|
|
if (!this.plugin.settings.folderAsString)
|
|
return;
|
|
if (!(prop in front) || !front[prop])
|
|
return;
|
|
if (Array.isArray(front[prop]) && front[prop].length === 1) {
|
|
front[prop] = front[prop][0];
|
|
}
|
|
}
|
|
_fm_add_link(front, selected, prop) {
|
|
let file = this.app.vault.getFileByPath(selected);
|
|
if (!file)
|
|
return;
|
|
let link = this.app.metadataCache.fileToLinktext(file, "");
|
|
let formated_link = `[[${link}]]`;
|
|
if (!this.plugin.settings.UseWikiLinks) {
|
|
formated_link = `[${link}](${link})`;
|
|
}
|
|
this._ensure_array(front, prop);
|
|
if (prop in front && front[prop]) {
|
|
if (front[prop].contains(formated_link)) {
|
|
this.showMessage(`${prop}'s link already exist`);
|
|
return;
|
|
}
|
|
} else {
|
|
front[prop] = [];
|
|
}
|
|
front[prop].push(formated_link);
|
|
this._normalize_prop(front, prop);
|
|
this.showMessage(`Set ${prop}: ${link}`);
|
|
}
|
|
add_link(yamlProp, file_id) {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
this.app.fileManager.processFrontMatter(file, (fm) => {
|
|
this._fm_add_link(fm, file_id, yamlProp);
|
|
});
|
|
}
|
|
add_link_to_file(file, yamlProp, file_id) {
|
|
this.app.fileManager.processFrontMatter(file, (fm) => {
|
|
this._fm_add_link(fm, file_id, yamlProp);
|
|
});
|
|
}
|
|
_fm_replace_link(front, selected, prop, old_link) {
|
|
let file = this.app.vault.getFileByPath(selected);
|
|
if (!file)
|
|
return;
|
|
let link = this.app.metadataCache.fileToLinktext(file, "");
|
|
let formated_link = `[[${link}]]`;
|
|
if (!this.plugin.settings.UseWikiLinks) {
|
|
formated_link = `[${link}](${link})`;
|
|
}
|
|
this._ensure_array(front, prop);
|
|
if (prop in front && front[prop]) {
|
|
if (front[prop].contains(formated_link)) {
|
|
this.showMessage(`${prop}'s link already exist`);
|
|
return;
|
|
}
|
|
if (!front[prop].contains(old_link)) {
|
|
this.showMessage(`Can't find ${old_link} in ${prop}`);
|
|
return;
|
|
}
|
|
let i = front[prop].indexOf(old_link);
|
|
front[prop][i] = formated_link;
|
|
this._normalize_prop(front, prop);
|
|
this.showMessage(`Set ${prop}: ${link}`);
|
|
} else {
|
|
front[prop] = [formated_link];
|
|
this._normalize_prop(front, prop);
|
|
this.showMessage(`Set ${prop}: ${link}`);
|
|
}
|
|
}
|
|
replace_link(yamlProp, old_link, file_id) {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
this.app.fileManager.processFrontMatter(file, (fm) => {
|
|
this._fm_replace_link(fm, file_id, yamlProp, old_link);
|
|
});
|
|
}
|
|
_fm_get_links(front, prop) {
|
|
if (prop in front && front[prop]) {
|
|
if (Array.isArray(front[prop]))
|
|
return front[prop];
|
|
return [front[prop]];
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
get_links(yamlProp, callback) {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
this.app.fileManager.processFrontMatter(file, (fm) => {
|
|
callback(this._fm_get_links(fm, yamlProp));
|
|
});
|
|
}
|
|
_fm_remove_link(front, prop, old_link) {
|
|
this._ensure_array(front, prop);
|
|
if (prop in front && front[prop]) {
|
|
if (front[prop].contains(old_link)) {
|
|
front[prop].remove(old_link);
|
|
this._normalize_prop(front, prop);
|
|
this.showMessage(`${prop}'s link removed`);
|
|
} else {
|
|
this.showMessage(`${prop}'s link not exist`);
|
|
}
|
|
}
|
|
}
|
|
remove_link(yamlProp, old_link) {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
this.app.fileManager.processFrontMatter(file, (fm) => {
|
|
this._fm_remove_link(fm, yamlProp, old_link);
|
|
});
|
|
}
|
|
_extract_link_base(link) {
|
|
let regexp = /(?:\[\[(.+?)\||\[\[(.+?)\]\]|\[.+?\]\((.+?)\))/;
|
|
let match = regexp.exec(link);
|
|
if (!match)
|
|
return null;
|
|
return match[1] || match[2] || match[3] || null;
|
|
}
|
|
_find_link_for_path(front, prop, targetPath) {
|
|
if (!(prop in front) || !front[prop])
|
|
return null;
|
|
let links = Array.isArray(front[prop]) ? front[prop] : [front[prop]];
|
|
for (let rawLink of links) {
|
|
let linkBase = this._extract_link_base(rawLink);
|
|
if (!linkBase)
|
|
continue;
|
|
let resolved = this.app.metadataCache.getFirstLinkpathDest(linkBase, "");
|
|
if (resolved && resolved.path === targetPath)
|
|
return rawLink;
|
|
}
|
|
return null;
|
|
}
|
|
set_icon(file, icon) {
|
|
this.app.fileManager.processFrontMatter(file, (fm) => {
|
|
if (icon) {
|
|
fm[this.plugin.settings.iconProp] = icon;
|
|
this.showMessage(`Icon set: ${icon}`);
|
|
} else {
|
|
delete fm[this.plugin.settings.iconProp];
|
|
this.showMessage("Icon removed");
|
|
}
|
|
});
|
|
}
|
|
toggle_pin(file, pin) {
|
|
this.app.fileManager.processFrontMatter(file, (fm) => {
|
|
if (pin) {
|
|
fm["vf_pinned"] = true;
|
|
this.showMessage("Note pinned");
|
|
} else {
|
|
delete fm["vf_pinned"];
|
|
this.showMessage("Note unpinned");
|
|
}
|
|
});
|
|
}
|
|
move_to_folder(noteFile, yamlProp, oldParentPath, newParentPath) {
|
|
this.app.fileManager.processFrontMatter(noteFile, (fm) => {
|
|
this._ensure_array(fm, yamlProp);
|
|
if (oldParentPath) {
|
|
let rawLink = this._find_link_for_path(fm, yamlProp, oldParentPath);
|
|
if (rawLink) {
|
|
fm[yamlProp].remove(rawLink);
|
|
}
|
|
}
|
|
if (newParentPath) {
|
|
this._fm_add_link(fm, newParentPath, yamlProp);
|
|
} else if (oldParentPath) {
|
|
this._normalize_prop(fm, yamlProp);
|
|
this.showMessage(`${yamlProp}'s link removed`);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
// main.ts
|
|
var VirtFolderPlugin = class extends import_obsidian9.Plugin {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.isFirstRun = false;
|
|
this.onOpenFile = (file) => {
|
|
this.setActiveFile(file);
|
|
if (this.settings.autoReveal && file) {
|
|
let path = this.base.get_next_path(file.path);
|
|
if (path)
|
|
this.revealFile(path);
|
|
}
|
|
};
|
|
this.onCreateFile = (file) => {
|
|
if (file instanceof import_obsidian9.TFile && file.extension === "md") {
|
|
this.data.onCreate(file);
|
|
this.update_data();
|
|
}
|
|
};
|
|
this.onDeleteFile = (file) => {
|
|
if (file instanceof import_obsidian9.TFile && file.extension === "md") {
|
|
this.data.onDelete(file);
|
|
this.update_data();
|
|
}
|
|
};
|
|
this.onRenameFile = (file, oldPath) => {
|
|
if (file instanceof import_obsidian9.TFile && file.extension === "md") {
|
|
for (let key in this.settings.customOrder) {
|
|
let order = this.settings.customOrder[key];
|
|
let idx = order.indexOf(oldPath);
|
|
if (idx !== -1)
|
|
order[idx] = file.path;
|
|
}
|
|
if (oldPath in this.settings.customOrder) {
|
|
this.settings.customOrder[file.path] = this.settings.customOrder[oldPath];
|
|
delete this.settings.customOrder[oldPath];
|
|
}
|
|
this.saveSettings();
|
|
this.data.onRename(file, oldPath);
|
|
this.update_data();
|
|
}
|
|
};
|
|
this.onResolveMetadata = (file) => {
|
|
let activeFile = this.app.workspace.getActiveFile();
|
|
let isActive = !!activeFile && activeFile.path === file.path;
|
|
let oldPath = isActive ? this.base.get_shortest_path(file.path) : void 0;
|
|
this.data.onChange(file);
|
|
this.update_data();
|
|
if (isActive) {
|
|
let newPath = this.base.get_shortest_path(file.path);
|
|
let relocated = (oldPath ? oldPath.join("/") : "") !== (newPath ? newPath.join("/") : "");
|
|
if (relocated && newPath) {
|
|
let path = this.base.get_next_path(file.path);
|
|
if (path)
|
|
this.revealFile(path);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
async onload() {
|
|
await this.loadSettings();
|
|
this.base = new BaseScanner(this.app, this);
|
|
this.data = new NoteData(this.base);
|
|
this.yaml = new YamlParser(this.app, this);
|
|
this.addSettingTab(new VirtFolderSettingTab(this.app, this));
|
|
this.registerView(
|
|
VIEW_TYPE_VF,
|
|
(leaf) => new VirtFolderView(leaf, this)
|
|
);
|
|
this.addCommand({
|
|
id: "open_tree_view",
|
|
name: "Show tree",
|
|
icon: "folder-tree",
|
|
callback: () => {
|
|
this.VF_OpenTreeView();
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "add_folder",
|
|
name: "Add folder",
|
|
icon: "folder-plus",
|
|
callback: () => {
|
|
this.VF_AddFolder();
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "replace_folder",
|
|
name: "Move folder",
|
|
icon: "folder-output",
|
|
callback: () => {
|
|
this.VF_MoveFolder();
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "remove_folder",
|
|
name: "Delete folder",
|
|
icon: "folder-minus",
|
|
callback: () => {
|
|
this.VF_RemoveFolder();
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "reveal_active_file",
|
|
name: "Reveal file",
|
|
icon: "folder-search-2",
|
|
callback: () => {
|
|
this.VF_RevealActiveFile();
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "add_selected_to_folder",
|
|
name: "Add selected files to virtual folder",
|
|
icon: "folder-plus",
|
|
callback: () => {
|
|
var _a;
|
|
let files = [];
|
|
let leaves = this.app.workspace.getLeavesOfType("file-explorer");
|
|
if (leaves.length > 0) {
|
|
let view = leaves[0].view;
|
|
if ((_a = view.tree) == null ? void 0 : _a.selectedDoms) {
|
|
for (let dom of view.tree.selectedDoms.values()) {
|
|
if (dom.file instanceof import_obsidian9.TFile)
|
|
files.push(dom.file);
|
|
}
|
|
}
|
|
}
|
|
if (files.length === 0) {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (file)
|
|
files.push(file);
|
|
}
|
|
if (files.length === 0)
|
|
return;
|
|
this.VF_AddFilesToFolder(files);
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "manage_icon",
|
|
name: "Manage icon",
|
|
icon: "image",
|
|
callback: () => {
|
|
this.VF_SetIcon();
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "pin_note",
|
|
name: "Pin note",
|
|
icon: "pin",
|
|
callback: () => {
|
|
this.VF_TogglePin();
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "navigate_parent",
|
|
name: "Navigate to parent folder",
|
|
icon: "arrow-up",
|
|
callback: () => {
|
|
this.VF_NavigateToParent();
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "navigate_next",
|
|
name: "Navigate to next sibling",
|
|
icon: "arrow-down",
|
|
callback: () => {
|
|
this.VF_NavigateToSibling(1);
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "navigate_prev",
|
|
name: "Navigate to previous sibling",
|
|
icon: "arrow-up",
|
|
callback: () => {
|
|
this.VF_NavigateToSibling(-1);
|
|
}
|
|
});
|
|
this.addCommand({
|
|
id: "navigate_child",
|
|
name: "Navigate to first child",
|
|
icon: "arrow-down",
|
|
callback: () => {
|
|
this.VF_NavigateToChild();
|
|
}
|
|
});
|
|
this.registerView(VIEW_TYPE_VF_WHATSNEW, (leaf) => new VF_WhatsNewView(leaf, this.manifest.version));
|
|
this.addCommand({
|
|
id: "whatsnew",
|
|
name: "What's new",
|
|
icon: "info",
|
|
callback: () => {
|
|
this.app.workspace.getLeaf("tab").setViewState({
|
|
type: VIEW_TYPE_VF_WHATSNEW,
|
|
active: true
|
|
});
|
|
}
|
|
});
|
|
this.app.workspace.onLayoutReady(async () => {
|
|
this.data.onStartApp();
|
|
this.update_data();
|
|
let activeFile = this.app.workspace.getActiveFile();
|
|
if (activeFile) {
|
|
this.setActiveFile(activeFile);
|
|
let path = this.base.get_next_path(activeFile.path);
|
|
if (path)
|
|
this.revealFile(path);
|
|
}
|
|
if (this.isFirstRun) {
|
|
const leaves = this.app.workspace.getLeavesOfType(VIEW_TYPE_VF);
|
|
if (leaves.length === 0)
|
|
this.activateView();
|
|
}
|
|
this.registerEvent(this.app.metadataCache.on("resolve", this.onResolveMetadata));
|
|
this.registerEvent(this.app.workspace.on("file-open", this.onOpenFile, this));
|
|
this.registerEvent(this.app.vault.on("create", this.onCreateFile));
|
|
this.registerEvent(this.app.vault.on("delete", this.onDeleteFile));
|
|
this.registerEvent(this.app.vault.on("rename", this.onRenameFile));
|
|
this.registerEvent(this.app.workspace.on("file-menu", (menu, file, source) => {
|
|
if (!(file instanceof import_obsidian9.TFile))
|
|
return;
|
|
menu.addItem((item) => {
|
|
item.setTitle("Add to virtual folder").setIcon("folder-plus").onClick(() => {
|
|
this.VF_AddFilesToFolder([file]);
|
|
});
|
|
});
|
|
menu.addItem((item) => {
|
|
item.setTitle("Manage icon").setIcon("image").onClick(() => {
|
|
new VF_IconPickerModal(this, (icon) => {
|
|
this.yaml.set_icon(file, icon);
|
|
this.update_data();
|
|
}).open();
|
|
});
|
|
});
|
|
let note = this.base.note_by_id(file.path);
|
|
let isPinned = note ? note.is_pinned : false;
|
|
menu.addItem((item) => {
|
|
item.setTitle(isPinned ? "Unpin note" : "Pin note").setIcon("pin").onClick(() => {
|
|
this.yaml.toggle_pin(file, !isPinned);
|
|
this.update_data();
|
|
});
|
|
});
|
|
}));
|
|
this.registerEvent(this.app.workspace.on("files-menu", (menu, files, source) => {
|
|
let tfiles = files.filter((f) => f instanceof import_obsidian9.TFile);
|
|
if (tfiles.length === 0)
|
|
return;
|
|
menu.addItem((item) => {
|
|
item.setTitle("Add to virtual folder").setIcon("folder-plus").onClick(() => {
|
|
this.VF_AddFilesToFolder(tfiles);
|
|
});
|
|
});
|
|
}));
|
|
});
|
|
}
|
|
async loadSettings() {
|
|
let saved = await this.loadData();
|
|
this.isFirstRun = !saved;
|
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, saved);
|
|
}
|
|
async saveSettings() {
|
|
await this.saveData(this.settings);
|
|
}
|
|
updateActiveFile() {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (file)
|
|
active_id.set(file.path);
|
|
else
|
|
active_id.set("");
|
|
}
|
|
setActiveFile(file) {
|
|
if (file instanceof import_obsidian9.TFile) {
|
|
active_id.set(file.path);
|
|
} else {
|
|
active_id.set("");
|
|
}
|
|
}
|
|
update_data() {
|
|
data.set(this.base);
|
|
this.updateActiveFile();
|
|
}
|
|
revealFile(path) {
|
|
for (const leaf of this.app.workspace.getLeavesOfType(VIEW_TYPE_VF)) {
|
|
if (!(leaf.view instanceof VirtFolderView))
|
|
continue;
|
|
leaf.view.component.focusTo(path);
|
|
}
|
|
}
|
|
async activateView() {
|
|
const { workspace } = this.app;
|
|
let leaf = null;
|
|
const leaves = workspace.getLeavesOfType(VIEW_TYPE_VF);
|
|
if (leaves.length > 0) {
|
|
leaf = leaves[0];
|
|
} else {
|
|
leaf = workspace.getLeftLeaf(false);
|
|
if (leaf)
|
|
await leaf.setViewState({ type: VIEW_TYPE_VF, active: true });
|
|
}
|
|
if (leaf)
|
|
workspace.revealLeaf(leaf);
|
|
}
|
|
VF_OpenTreeView() {
|
|
this.activateView();
|
|
}
|
|
async VF_RevealActiveFile() {
|
|
await this.activateView();
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
let path = this.base.get_next_path(file.path);
|
|
if (path)
|
|
this.revealFile(path);
|
|
}
|
|
updateUsedTime(file_id) {
|
|
this.base.note_list[file_id].utime = Date.now();
|
|
}
|
|
VF_TogglePin() {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
let note = this.base.note_by_id(file.path);
|
|
let isPinned = note ? note.is_pinned : false;
|
|
this.yaml.toggle_pin(file, !isPinned);
|
|
this.update_data();
|
|
}
|
|
VF_NavigateToChild() {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
let note = this.base.note_by_id(file.path);
|
|
if (!note || note.children.length === 0)
|
|
return;
|
|
this.app.workspace.openLinkText(note.children[0], note.children[0], false);
|
|
}
|
|
VF_NavigateToParent() {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
let note = this.base.note_by_id(file.path);
|
|
if (!note || note.parents.length === 0)
|
|
return;
|
|
this.app.workspace.openLinkText(note.parents[0], note.parents[0], false);
|
|
}
|
|
VF_GetSiblingList(noteId) {
|
|
let note = this.base.note_by_id(noteId);
|
|
if (!note)
|
|
return null;
|
|
if (note.parents.length > 0) {
|
|
let parentId = note.parents[0];
|
|
let lastActive = this.base.last_active;
|
|
if (lastActive.length >= 2) {
|
|
let lastParent = lastActive[lastActive.length - 2];
|
|
if (note.parents.includes(lastParent))
|
|
parentId = lastParent;
|
|
}
|
|
let parent = this.base.note_by_id(parentId);
|
|
if (!parent)
|
|
return null;
|
|
return parent.children;
|
|
}
|
|
if (note.has_children())
|
|
return this.base.top_list;
|
|
return this.base.orphans_list;
|
|
}
|
|
VF_NavigateToSibling(direction) {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
let list = this.VF_GetSiblingList(file.path);
|
|
if (!list || list.length < 2)
|
|
return;
|
|
let index = list.indexOf(file.path);
|
|
if (index === -1)
|
|
return;
|
|
let next = (index + direction + list.length) % list.length;
|
|
this.app.workspace.openLinkText(list[next], list[next], false);
|
|
}
|
|
VF_SetIcon() {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
new VF_IconPickerModal(this, (icon) => {
|
|
let activeFile = this.app.workspace.getActiveFile();
|
|
if (!activeFile)
|
|
return;
|
|
this.yaml.set_icon(activeFile, icon);
|
|
this.update_data();
|
|
}).open();
|
|
}
|
|
VF_AddFolder() {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
let excludeIds = this.base.get_all_descendants(file.path);
|
|
excludeIds.add(file.path);
|
|
new VF_SelectFile(
|
|
this,
|
|
(file_id) => {
|
|
this.yaml.add_link(this.settings.propertyName, file_id);
|
|
this.updateUsedTime(file_id);
|
|
this.update_data();
|
|
},
|
|
excludeIds
|
|
).open();
|
|
}
|
|
VF_AddFilesToFolder(files) {
|
|
let excludeIds = /* @__PURE__ */ new Set();
|
|
for (let file of files) {
|
|
excludeIds.add(file.path);
|
|
let descendants = this.base.get_all_descendants(file.path);
|
|
for (let d of descendants)
|
|
excludeIds.add(d);
|
|
}
|
|
new VF_SelectFile(
|
|
this,
|
|
(folder_id) => {
|
|
for (let file of files) {
|
|
this.yaml.add_link_to_file(file, this.settings.propertyName, folder_id);
|
|
}
|
|
this.updateUsedTime(folder_id);
|
|
this.update_data();
|
|
},
|
|
excludeIds
|
|
).open();
|
|
}
|
|
VF_MoveFolder() {
|
|
let file = this.app.workspace.getActiveFile();
|
|
if (!file)
|
|
return;
|
|
let excludeIds = this.base.get_all_descendants(file.path);
|
|
excludeIds.add(file.path);
|
|
new VF_SelectPropModal(
|
|
this,
|
|
this.settings.propertyName,
|
|
(old_link) => {
|
|
new VF_SelectFile(
|
|
this,
|
|
(file_id) => {
|
|
this.yaml.replace_link(this.settings.propertyName, old_link, file_id);
|
|
this.updateUsedTime(file_id);
|
|
this.update_data();
|
|
},
|
|
excludeIds
|
|
).open();
|
|
}
|
|
).open();
|
|
}
|
|
VF_RemoveFolder() {
|
|
new VF_SelectPropModal(
|
|
this,
|
|
this.settings.propertyName,
|
|
(old_link) => {
|
|
this.yaml.remove_link(this.settings.propertyName, old_link);
|
|
this.update_data();
|
|
}
|
|
).open();
|
|
}
|
|
async createNoteInFolder(parentId, unique = false) {
|
|
if (unique) {
|
|
let commands = this.app.commands;
|
|
if (!commands || !commands.executeCommandById) {
|
|
this.yaml.showMessage("Commands API is not available");
|
|
return;
|
|
}
|
|
let ref = this.app.vault.on("create", async (file2) => {
|
|
if (!(file2 instanceof import_obsidian9.TFile))
|
|
return;
|
|
this.app.vault.offref(ref);
|
|
if (parentId)
|
|
await this.app.fileManager.processFrontMatter(file2, (fm) => {
|
|
this.yaml._fm_add_link(fm, parentId, this.settings.propertyName);
|
|
});
|
|
let metaRef2 = this.app.metadataCache.on("resolve", (resolved) => {
|
|
if (resolved.path !== file2.path)
|
|
return;
|
|
this.app.metadataCache.offref(metaRef2);
|
|
this.update_data();
|
|
this.VF_RevealActiveFile();
|
|
});
|
|
});
|
|
let executed = commands.executeCommandById("zk-prefixer");
|
|
if (!executed) {
|
|
this.app.vault.offref(ref);
|
|
this.yaml.showMessage('Enable "Unique note creator" core plugin');
|
|
}
|
|
return;
|
|
}
|
|
let folder = this.app.fileManager.getNewFileParent("");
|
|
let prefix = folder.path === "/" ? "" : folder.path + "/";
|
|
let name = "Untitled";
|
|
let counter = 0;
|
|
let path = `${prefix}${name}.md`;
|
|
while (this.app.vault.getAbstractFileByPath(path)) {
|
|
counter++;
|
|
path = `${prefix}${name} ${counter}.md`;
|
|
}
|
|
let file = await this.app.vault.create(path, "");
|
|
if (parentId)
|
|
await this.app.fileManager.processFrontMatter(file, (fm) => {
|
|
this.yaml._fm_add_link(fm, parentId, this.settings.propertyName);
|
|
});
|
|
let metaRef = this.app.metadataCache.on("resolve", (resolved) => {
|
|
if (resolved.path !== path)
|
|
return;
|
|
this.app.metadataCache.offref(metaRef);
|
|
this.update_data();
|
|
this.VF_RevealActiveFile();
|
|
});
|
|
await this.app.workspace.openLinkText(path, path);
|
|
}
|
|
async deleteNote(noteId) {
|
|
let file = this.app.vault.getFileByPath(noteId);
|
|
if (!file)
|
|
return;
|
|
let doDelete = async () => {
|
|
await this.app.vault.trash(file, true);
|
|
new import_obsidian9.Notice("Note deleted");
|
|
this.update_data();
|
|
};
|
|
if (this.settings.confirmDelete) {
|
|
let note = this.base.note_by_id(noteId);
|
|
let displayName = note && this.settings.cmdShowTitle ? note.title : file.basename;
|
|
new VF_ConfirmModal(this.app, doDelete, "Delete note", `Delete "${displayName}"?`).open();
|
|
} else {
|
|
await doDelete();
|
|
}
|
|
}
|
|
async deleteNoteRecursive(noteId) {
|
|
let file = this.app.vault.getFileByPath(noteId);
|
|
if (!file)
|
|
return;
|
|
let descendants = this.base.get_all_descendants(noteId);
|
|
let allIds = [noteId, ...descendants];
|
|
let note = this.base.note_by_id(noteId);
|
|
let displayName = note && this.settings.cmdShowTitle ? note.title : file.basename;
|
|
let title = "Delete notes";
|
|
let message = `Delete "${displayName}" and ${descendants.size} nested notes?`;
|
|
if (descendants.size === 0) {
|
|
title = "Delete note";
|
|
message = `Delete "${displayName}"?`;
|
|
}
|
|
let doDelete = async () => {
|
|
for (let id of allIds) {
|
|
let f = this.app.vault.getFileByPath(id);
|
|
if (f)
|
|
await this.app.vault.trash(f, true);
|
|
}
|
|
new import_obsidian9.Notice(`${allIds.length} note(s) deleted`);
|
|
this.update_data();
|
|
};
|
|
new VF_ConfirmModal(this.app, doDelete, title, message).open();
|
|
}
|
|
moveNoteToFolder(noteId, oldParentId, newParentId) {
|
|
let noteFile = this.app.vault.getFileByPath(noteId);
|
|
if (!noteFile)
|
|
return;
|
|
this.yaml.move_to_folder(noteFile, this.settings.propertyName, oldParentId, newParentId);
|
|
if (newParentId) {
|
|
let note = this.base.note_by_id(newParentId);
|
|
if (note)
|
|
note.utime = Date.now();
|
|
}
|
|
this.update_data();
|
|
}
|
|
reorderNote(noteId, targetId, parentKey, insertBefore) {
|
|
let children2;
|
|
if (parentKey === "top_dir")
|
|
children2 = this.base.top_list;
|
|
else if (parentKey === "orphan_dir")
|
|
children2 = this.base.orphans_list;
|
|
else {
|
|
let parent = this.base.note_by_id(parentKey);
|
|
if (!parent)
|
|
return;
|
|
children2 = parent.children;
|
|
}
|
|
if (!this.settings.customOrder[parentKey]) {
|
|
this.settings.customOrder[parentKey] = [...children2];
|
|
}
|
|
let order = this.settings.customOrder[parentKey].filter((id) => id !== noteId);
|
|
let targetIdx = order.indexOf(targetId);
|
|
if (targetIdx === -1)
|
|
targetIdx = order.length - 1;
|
|
let insertIdx = insertBefore ? targetIdx : targetIdx + 1;
|
|
order.splice(insertIdx, 0, noteId);
|
|
this.settings.customOrder[parentKey] = order;
|
|
this.saveSettings();
|
|
this.base.sort_links();
|
|
this.update_data();
|
|
}
|
|
};
|
|
var VF_ConfirmModal = class extends import_obsidian9.Modal {
|
|
constructor(app, onConfirm, title = "Delete note", message = "") {
|
|
super(app);
|
|
this.onConfirm = onConfirm;
|
|
this.title = title;
|
|
this.message = message;
|
|
}
|
|
onOpen() {
|
|
this.titleEl.setText(this.title);
|
|
this.contentEl.createEl("p", { text: this.message });
|
|
new import_obsidian9.Setting(this.contentEl).addButton((btn) => {
|
|
btn.setButtonText("Delete").setWarning().onClick(() => {
|
|
this.close();
|
|
this.onConfirm();
|
|
});
|
|
}).addButton((btn) => {
|
|
btn.setButtonText("Cancel").onClick(() => {
|
|
this.close();
|
|
});
|
|
});
|
|
}
|
|
};
|
|
var VIEW_TYPE_VF_WHATSNEW = "virt-folder-whatsnew";
|
|
var WHATSNEW_MD = `
|
|
Thank you for using VirtFolder! \u2764\uFE0F This is an independent project, and every share helps new users discover it. If the plugin is useful to you, consider telling a friend or [starring the repo on GitHub](https://github.com/gr0grig/obsidian-virt-folder) \u2014 it really makes a difference!
|
|
|
|
---
|
|
|
|
## July 2026
|
|
|
|
- **Open without expanding** \u2014 clicking a note's title now opens it without toggling its children. Expand/collapse is done via the arrow icon. A setting (\`Expand/collapse on title click\`) restores the old click-to-toggle behavior.
|
|
- **Hide orphans** \u2014 optional setting to keep orphan notes (no parents, no children) out of the tree, useful for large vaults and keyboard navigation.
|
|
- **Reveal on folder change fix** \u2014 changing a note's folder property no longer hides it inside a collapsed branch; the active note is re-revealed at its new location.
|
|
|
|
## May 2026
|
|
|
|
- **Custom sort order** \u2014 manual note ordering via drag-and-drop in \`custom\` sort mode. Drag onto a sibling's top/bottom half to reorder. Order persists across sessions and survives renames.
|
|
- **Frontmatter as data attributes** \u2014 optional setting to expose all frontmatter as \`data-*\` HTML attributes on tree items, enabling CSS snippet styling based on any YAML property.
|
|
|
|
## April 2026
|
|
|
|
- **Tag-based highlighting** \u2014 color-coded note backgrounds based on tags. Configurable color and opacity per tag in settings.
|
|
- **Sibling navigation improvements** \u2014 Navigate next/previous sibling now stays within the current parent context for multi-parent notes.
|
|
- **Self-reference protection** \u2014 notes linking to themselves in the Folders property are now ignored, preventing them from disappearing from the tree.
|
|
- **Folder link as string** \u2014 optional setting to write single-parent folder links as a YAML string instead of a list. Auto-converts between string and list when parents change.
|
|
- **Click to collapse** \u2014 clicking a tree node now toggles expand/collapse (previously only expanded).
|
|
- **Array title support** \u2014 when the title YAML property is an array, the first element is used (PR #25).
|
|
|
|
## March 2026
|
|
|
|
- **Hide notes by tag** \u2014 filter notes from the tree by tag (Settings > Ignored tags).
|
|
- **Auto-reveal scroll fix** \u2014 notes taller than the viewport align to top instead of centering (PR #22).
|
|
- **Array property safety** \u2014 check if property is array before moving, preventing data corruption (PR #24).
|
|
- **Navigation commands** \u2014 navigate to parent, next/previous sibling, first child. Reveal active file in tree.
|
|
- **Configurable icon property** \u2014 YAML property name for emoji icons is now configurable in settings.
|
|
|
|
## February 2026
|
|
|
|
- **File explorer integration** \u2014 add files to virtual folders from Obsidian's file explorer context menu. Pin/unpin and manage icons from file explorer.
|
|
- **Delete with children** \u2014 recursive delete option in tree context menu.
|
|
- **Drag and drop** \u2014 move notes between folders by dragging in the tree. Safety: can't drop onto self or descendants.
|
|
- **Create notes from tree** \u2014 create note / create unique note via tree context menu. Works at ROOT level and under any note.
|
|
- **Database optimization** \u2014 incremental updates instead of full rescans.
|
|
- **Unicode YAML support** \u2014 folder property names now support any language characters.
|
|
- **Unique note creator** \u2014 integration with the Unique Note Creator plugin for auto-generated note names.
|
|
- **Auto-open tree on first run** \u2014 the tree view opens automatically when the plugin is installed for the first time.
|
|
|
|
## August 2024
|
|
|
|
- **Link format settings** \u2014 choose between \`[[WikiLinks]]\` and \`[Markdown](links)\` format for folder links in YAML.
|
|
- **Sorting options** \u2014 sort tree children by filename, title, creation time, or modification time. Reverse sort order toggle.
|
|
|
|
## July 2024
|
|
|
|
- **Initial release** \u2014 tree view sidebar with collapsible hierarchy built from YAML frontmatter links.
|
|
- **YAML-based structure** \u2014 notes define parent-child relationships via a configurable frontmatter property.
|
|
- **Custom display title** \u2014 use a YAML property as the display title instead of the filename.
|
|
- **Mobile support** \u2014 full compatibility with Obsidian Mobile.
|
|
- **Emoji icons** \u2014 set custom emoji icons on notes via an icon picker with categorized groups and search.
|
|
- **Pinned notes** \u2014 pin notes to the top of their sibling list.
|
|
- **Orphans section** \u2014 notes with no parents and no children are collected in a collapsible Orphans section.
|
|
- **Child counter** \u2014 badge showing the number of direct children on each note.
|
|
- **Active note highlight** \u2014 the currently open note is visually highlighted in the tree.
|
|
- **Auto-reveal** \u2014 optionally auto-scroll the tree to the active file when switching notes.
|
|
- **Confirm before deleting** \u2014 optional confirmation dialog for delete actions.
|
|
- **Ignored paths** \u2014 exclude notes by path prefix from the tree.
|
|
`;
|
|
var VF_WhatsNewView = class extends import_obsidian9.ItemView {
|
|
constructor(leaf, version) {
|
|
super(leaf);
|
|
this.version = version;
|
|
}
|
|
getViewType() {
|
|
return VIEW_TYPE_VF_WHATSNEW;
|
|
}
|
|
getDisplayText() {
|
|
return "What's new in VirtFolder";
|
|
}
|
|
getIcon() {
|
|
return "info";
|
|
}
|
|
async onOpen() {
|
|
let container = this.contentEl;
|
|
container.empty();
|
|
container.addClass("markdown-rendered");
|
|
let md = `# VirtFolder v${this.version}
|
|
` + WHATSNEW_MD;
|
|
await import_obsidian9.MarkdownRenderer.render(this.app, md, container, "", this);
|
|
}
|
|
};
|