Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- .DS_Store +0 -0
- README.md +6 -8
- __pycache__/analyze.cpython-311.pyc +0 -0
- __pycache__/fetch.cpython-311.pyc +0 -0
- __pycache__/sources.cpython-311.pyc +0 -0
- fetch.py +30 -0
- interface.py +222 -0
- lib/bindings/utils.js +189 -0
- lib/tom-select/tom-select.complete.min.js +356 -0
- lib/tom-select/tom-select.css +334 -0
- lib/vis-9.1.2/vis-network.css +0 -0
- lib/vis-9.1.2/vis-network.min.js +0 -0
- requirements.txt +8 -0
- sources.py +26 -0
- tutorials/tutorial0.ipynb +0 -0
- tutorials/tutorial1.ipynb +224 -0
- tutorials/wiki_sentences_v2.csv +0 -0
.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
README.md
CHANGED
@@ -1,12 +1,10 @@
|
|
1 |
---
|
2 |
-
title: 06
|
3 |
-
|
4 |
-
colorFrom: purple
|
5 |
-
colorTo: yellow
|
6 |
sdk: gradio
|
7 |
-
sdk_version:
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
---
|
|
|
11 |
|
12 |
-
|
|
|
|
1 |
---
|
2 |
+
title: 06-knowledge-graph
|
3 |
+
app_file: interface.py
|
|
|
|
|
4 |
sdk: gradio
|
5 |
+
sdk_version: 4.44.1
|
|
|
|
|
6 |
---
|
7 |
+
python -m spacy download en_core_web_sm
|
8 |
|
9 |
+
resources that helped
|
10 |
+
https://www.analyticsvidhya.com/blog/2019/10/how-to-build-knowledge-graph-text-using-spacy/ (Knowledge Graph: Data Science Technique to Mine Information from Text (with Python code))
|
__pycache__/analyze.cpython-311.pyc
ADDED
Binary file (6.6 kB). View file
|
|
__pycache__/fetch.cpython-311.pyc
ADDED
Binary file (2.15 kB). View file
|
|
__pycache__/sources.cpython-311.pyc
ADDED
Binary file (1.9 kB). View file
|
|
fetch.py
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import feedparser
|
2 |
+
import requests
|
3 |
+
from bs4 import BeautifulSoup
|
4 |
+
from collections import Counter
|
5 |
+
import re
|
6 |
+
|
7 |
+
def fetch_articles(feed_urls, limit=5):
|
8 |
+
all_articles = []
|
9 |
+
for name, url in feed_urls.items():
|
10 |
+
try:
|
11 |
+
feed = feedparser.parse(url)
|
12 |
+
for entry in feed.entries[:limit]:
|
13 |
+
article = {
|
14 |
+
"title": entry.title,
|
15 |
+
"link": entry.link,
|
16 |
+
"summary": entry.get("summary", "No summary"),
|
17 |
+
"published": entry.get("published", "No date")
|
18 |
+
}
|
19 |
+
all_articles.append(article)
|
20 |
+
except Exception as e:
|
21 |
+
print(f"Error parsing {url}: {e}")
|
22 |
+
return all_articles
|
23 |
+
|
24 |
+
|
25 |
+
def analyze_trends(items):
|
26 |
+
"""Dummy trend analyzer: count word frequencies in titles."""
|
27 |
+
text = " ".join(item["title"] for item in items)
|
28 |
+
words = re.findall(r'\b\w{4,}\b', text.lower()) # 4+ letter words
|
29 |
+
common = Counter(words).most_common(10)
|
30 |
+
return common
|
interface.py
ADDED
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import networkx as nx
|
3 |
+
import spacy
|
4 |
+
import plotly.graph_objects as go
|
5 |
+
|
6 |
+
from sources import RSS_FEEDS
|
7 |
+
from fetch import fetch_articles
|
8 |
+
|
9 |
+
# Imports for the LLM knowledge graph transformer
|
10 |
+
from langchain.schema import Document
|
11 |
+
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
12 |
+
from langchain_openai import ChatOpenAI
|
13 |
+
from langchain_experimental.graph_transformers import LLMGraphTransformer
|
14 |
+
|
15 |
+
# Load the spaCy model (kept for other tasks if needed)
|
16 |
+
nlp = spacy.load("en_core_web_sm")
|
17 |
+
|
18 |
+
def build_interactive_knowledge_graph(feed_items):
|
19 |
+
"""
|
20 |
+
Build an interactive knowledge graph from aggregated RSS feed text using an LLM.
|
21 |
+
|
22 |
+
Steps:
|
23 |
+
1. Combine the title and summary of all feed items.
|
24 |
+
2. Create a Document and split it into chunks.
|
25 |
+
3. Use ChatOpenAI and LLMGraphTransformer to get graph information.
|
26 |
+
4. Merge nodes and relationships into a directed NetworkX graph.
|
27 |
+
5. Compute a spring layout and convert the graph to a Plotly figure.
|
28 |
+
6. Compute node hover text showing all outgoing/incoming connections.
|
29 |
+
7. Re-add arrow annotations to indicate direction (with no extra text).
|
30 |
+
8. Return the Plotly figure.
|
31 |
+
"""
|
32 |
+
# 1. Combine all feed items into one aggregated text.
|
33 |
+
combined_text = "\n\n".join([f"{item['title']}. {item['summary']}" for item in feed_items])
|
34 |
+
|
35 |
+
# 2. Create a Document and split it.
|
36 |
+
doc = Document(page_content=combined_text)
|
37 |
+
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
|
38 |
+
docs = text_splitter.split_documents([doc])
|
39 |
+
|
40 |
+
# 3. Initialize the LLM and transformer.
|
41 |
+
llm = ChatOpenAI(temperature=0, model="gpt-4o")
|
42 |
+
llm_transformer = LLMGraphTransformer(llm=llm)
|
43 |
+
graph_documents = llm_transformer.convert_to_graph_documents(docs)
|
44 |
+
|
45 |
+
# 4. Build a directed NetworkX graph.
|
46 |
+
G = nx.DiGraph()
|
47 |
+
for graph_doc in graph_documents:
|
48 |
+
# Convert the Pydantic model to a dictionary.
|
49 |
+
gdoc = graph_doc.model_dump()
|
50 |
+
nodes = gdoc.get("nodes", [])
|
51 |
+
# In these documents, relationships are stored under "relationships".
|
52 |
+
relationships = gdoc.get("relationships", [])
|
53 |
+
|
54 |
+
# Add nodes.
|
55 |
+
for node in nodes:
|
56 |
+
node_id = node.get("id") or node.get("name")
|
57 |
+
if node_id:
|
58 |
+
G.add_node(node_id)
|
59 |
+
|
60 |
+
# Add relationships as directed edges.
|
61 |
+
for rel in relationships:
|
62 |
+
source_obj = rel.get("source", {})
|
63 |
+
target_obj = rel.get("target", {})
|
64 |
+
source = source_obj.get("id")
|
65 |
+
target = target_obj.get("id")
|
66 |
+
rel_type = rel.get("type", "")
|
67 |
+
if source and target:
|
68 |
+
if G.has_edge(source, target):
|
69 |
+
if "relation_types" in G[source][target]:
|
70 |
+
if rel_type not in G[source][target]["relation_types"]:
|
71 |
+
G[source][target]["relation_types"].append(rel_type)
|
72 |
+
else:
|
73 |
+
G[source][target]["relation_types"] = [rel_type]
|
74 |
+
G[source][target]["weight"] += 1
|
75 |
+
else:
|
76 |
+
G.add_edge(source, target, weight=1, relation_types=[rel_type])
|
77 |
+
|
78 |
+
# 5. Compute positions using a spring layout.
|
79 |
+
pos = nx.spring_layout(G, k=1.2)
|
80 |
+
#pos = nx.kamada_kawai_layout(G)
|
81 |
+
|
82 |
+
# 6. Prepare node hover text.
|
83 |
+
# For each node, list all outgoing and incoming connection details.
|
84 |
+
node_hover = {}
|
85 |
+
for node in G.nodes():
|
86 |
+
outgoing = []
|
87 |
+
for u, v, data in G.out_edges(node, data=True):
|
88 |
+
rels = ", ".join(data.get("relation_types", []))
|
89 |
+
outgoing.append(f"Out: {node} - {rels} -> {v}")
|
90 |
+
incoming = []
|
91 |
+
for u, v, data in G.in_edges(node, data=True):
|
92 |
+
rels = ", ".join(data.get("relation_types", []))
|
93 |
+
incoming.append(f"In: {u} - {rels} -> {node}")
|
94 |
+
details = outgoing + incoming
|
95 |
+
if details:
|
96 |
+
node_hover[node] = "<br>".join(details)
|
97 |
+
else:
|
98 |
+
node_hover[node] = node # Fallback if there are no connections.
|
99 |
+
|
100 |
+
# 7. Create node trace using calculated positions and hover text.
|
101 |
+
node_x = []
|
102 |
+
node_y = []
|
103 |
+
node_text = [] # Displayed text is just the node name.
|
104 |
+
node_hover_list = [] # Custom hover info with connection details.
|
105 |
+
for node in G.nodes():
|
106 |
+
x, y = pos[node]
|
107 |
+
node_x.append(x)
|
108 |
+
node_y.append(y)
|
109 |
+
node_text.append(node)
|
110 |
+
node_hover_list.append(node_hover.get(node, node))
|
111 |
+
|
112 |
+
node_trace = go.Scatter(
|
113 |
+
x=node_x,
|
114 |
+
y=node_y,
|
115 |
+
mode='markers+text',
|
116 |
+
text=node_text,
|
117 |
+
textposition="top center",
|
118 |
+
hoverinfo='text',
|
119 |
+
hovertext=node_hover_list,
|
120 |
+
marker=dict(
|
121 |
+
size=10,
|
122 |
+
color='#1f78b4'
|
123 |
+
)
|
124 |
+
)
|
125 |
+
|
126 |
+
# 8. Create edge traces: one trace per edge.
|
127 |
+
edge_traces = []
|
128 |
+
for edge in G.edges(data=True):
|
129 |
+
x0, y0 = pos[edge[0]]
|
130 |
+
x1, y1 = pos[edge[1]]
|
131 |
+
edge_trace = go.Scatter(
|
132 |
+
x=[x0, x1],
|
133 |
+
y=[y0, y1],
|
134 |
+
mode='lines',
|
135 |
+
line=dict(width=1, color='#888'),
|
136 |
+
hoverinfo='none'
|
137 |
+
)
|
138 |
+
edge_traces.append(edge_trace)
|
139 |
+
|
140 |
+
# 9. Build the interactive Plotly figure.
|
141 |
+
fig = go.Figure(
|
142 |
+
data=edge_traces + [node_trace],
|
143 |
+
layout=go.Layout(
|
144 |
+
title='<br>Interactive Knowledge Graph (LLM-derived)',
|
145 |
+
showlegend=False,
|
146 |
+
hovermode='closest',
|
147 |
+
margin=dict(b=20, l=5, r=5, t=40),
|
148 |
+
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
|
149 |
+
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
|
150 |
+
width=1200, # wider figure
|
151 |
+
height=800, # taller figure
|
152 |
+
dragmode='pan'
|
153 |
+
)
|
154 |
+
)
|
155 |
+
|
156 |
+
# 10. Re-add arrow annotations for each edge (without hover text).
|
157 |
+
for edge in G.edges(data=True):
|
158 |
+
x0, y0 = pos[edge[0]]
|
159 |
+
x1, y1 = pos[edge[1]]
|
160 |
+
fig.add_annotation(
|
161 |
+
x=x1,
|
162 |
+
y=y1,
|
163 |
+
ax=x0,
|
164 |
+
ay=y0,
|
165 |
+
xref='x',
|
166 |
+
yref='y',
|
167 |
+
axref='x',
|
168 |
+
ayref='y',
|
169 |
+
showarrow=True,
|
170 |
+
arrowhead=3,
|
171 |
+
arrowcolor='#888',
|
172 |
+
arrowwidth=2,
|
173 |
+
text="", # No text; rely on node hover for details.
|
174 |
+
)
|
175 |
+
|
176 |
+
return fig
|
177 |
+
|
178 |
+
def get_combined_feed(source_choice, selected_news_sites):
|
179 |
+
"""
|
180 |
+
Create an aggregated feed from selected RSS sources
|
181 |
+
and build an interactive Plotly knowledge graph.
|
182 |
+
"""
|
183 |
+
feed_items = []
|
184 |
+
|
185 |
+
# Fetch articles from selected news sites.
|
186 |
+
if "News" in source_choice and selected_news_sites:
|
187 |
+
selected_feeds = {name: url for name, url in RSS_FEEDS.items() if name in selected_news_sites}
|
188 |
+
feed_items += fetch_articles(selected_feeds, limit=6)
|
189 |
+
|
190 |
+
# Aggregate feed text.
|
191 |
+
feed_text = "\n\n".join([f"🔹 {item['title']} ({item['published']})\n{item['link']}" for item in feed_items])
|
192 |
+
|
193 |
+
# Build an interactive knowledge graph using Plotly.
|
194 |
+
graph_fig = build_interactive_knowledge_graph(feed_items)
|
195 |
+
|
196 |
+
return feed_text, graph_fig
|
197 |
+
|
198 |
+
# Define the Gradio interface with a button to trigger processing.
|
199 |
+
with gr.Blocks() as demo:
|
200 |
+
with gr.Row():
|
201 |
+
with gr.Column():
|
202 |
+
source_selector = gr.CheckboxGroup(
|
203 |
+
["News"], value=["News"], label="Select Sources"
|
204 |
+
)
|
205 |
+
news_site_selector = gr.CheckboxGroup(
|
206 |
+
list(RSS_FEEDS.keys()), value=["BBC", "Wired"], label="News Sites"
|
207 |
+
)
|
208 |
+
with gr.Column():
|
209 |
+
feed_output = gr.Textbox(label="Aggregated Feed", lines=20)
|
210 |
+
with gr.Row():
|
211 |
+
with gr.Column():
|
212 |
+
graph_output = gr.Plot(label="Interactive Knowledge Graph")
|
213 |
+
|
214 |
+
# Button to trigger graph generation.
|
215 |
+
generate_button = gr.Button("Generate Graph")
|
216 |
+
generate_button.click(
|
217 |
+
fn=get_combined_feed,
|
218 |
+
inputs=[source_selector, news_site_selector],
|
219 |
+
outputs=[feed_output, graph_output]
|
220 |
+
)
|
221 |
+
|
222 |
+
demo.launch()
|
lib/bindings/utils.js
ADDED
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function neighbourhoodHighlight(params) {
|
2 |
+
// console.log("in nieghbourhoodhighlight");
|
3 |
+
allNodes = nodes.get({ returnType: "Object" });
|
4 |
+
// originalNodes = JSON.parse(JSON.stringify(allNodes));
|
5 |
+
// if something is selected:
|
6 |
+
if (params.nodes.length > 0) {
|
7 |
+
highlightActive = true;
|
8 |
+
var i, j;
|
9 |
+
var selectedNode = params.nodes[0];
|
10 |
+
var degrees = 2;
|
11 |
+
|
12 |
+
// mark all nodes as hard to read.
|
13 |
+
for (let nodeId in allNodes) {
|
14 |
+
// nodeColors[nodeId] = allNodes[nodeId].color;
|
15 |
+
allNodes[nodeId].color = "rgba(200,200,200,0.5)";
|
16 |
+
if (allNodes[nodeId].hiddenLabel === undefined) {
|
17 |
+
allNodes[nodeId].hiddenLabel = allNodes[nodeId].label;
|
18 |
+
allNodes[nodeId].label = undefined;
|
19 |
+
}
|
20 |
+
}
|
21 |
+
var connectedNodes = network.getConnectedNodes(selectedNode);
|
22 |
+
var allConnectedNodes = [];
|
23 |
+
|
24 |
+
// get the second degree nodes
|
25 |
+
for (i = 1; i < degrees; i++) {
|
26 |
+
for (j = 0; j < connectedNodes.length; j++) {
|
27 |
+
allConnectedNodes = allConnectedNodes.concat(
|
28 |
+
network.getConnectedNodes(connectedNodes[j])
|
29 |
+
);
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
// all second degree nodes get a different color and their label back
|
34 |
+
for (i = 0; i < allConnectedNodes.length; i++) {
|
35 |
+
// allNodes[allConnectedNodes[i]].color = "pink";
|
36 |
+
allNodes[allConnectedNodes[i]].color = "rgba(150,150,150,0.75)";
|
37 |
+
if (allNodes[allConnectedNodes[i]].hiddenLabel !== undefined) {
|
38 |
+
allNodes[allConnectedNodes[i]].label =
|
39 |
+
allNodes[allConnectedNodes[i]].hiddenLabel;
|
40 |
+
allNodes[allConnectedNodes[i]].hiddenLabel = undefined;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
// all first degree nodes get their own color and their label back
|
45 |
+
for (i = 0; i < connectedNodes.length; i++) {
|
46 |
+
// allNodes[connectedNodes[i]].color = undefined;
|
47 |
+
allNodes[connectedNodes[i]].color = nodeColors[connectedNodes[i]];
|
48 |
+
if (allNodes[connectedNodes[i]].hiddenLabel !== undefined) {
|
49 |
+
allNodes[connectedNodes[i]].label =
|
50 |
+
allNodes[connectedNodes[i]].hiddenLabel;
|
51 |
+
allNodes[connectedNodes[i]].hiddenLabel = undefined;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
// the main node gets its own color and its label back.
|
56 |
+
// allNodes[selectedNode].color = undefined;
|
57 |
+
allNodes[selectedNode].color = nodeColors[selectedNode];
|
58 |
+
if (allNodes[selectedNode].hiddenLabel !== undefined) {
|
59 |
+
allNodes[selectedNode].label = allNodes[selectedNode].hiddenLabel;
|
60 |
+
allNodes[selectedNode].hiddenLabel = undefined;
|
61 |
+
}
|
62 |
+
} else if (highlightActive === true) {
|
63 |
+
// console.log("highlightActive was true");
|
64 |
+
// reset all nodes
|
65 |
+
for (let nodeId in allNodes) {
|
66 |
+
// allNodes[nodeId].color = "purple";
|
67 |
+
allNodes[nodeId].color = nodeColors[nodeId];
|
68 |
+
// delete allNodes[nodeId].color;
|
69 |
+
if (allNodes[nodeId].hiddenLabel !== undefined) {
|
70 |
+
allNodes[nodeId].label = allNodes[nodeId].hiddenLabel;
|
71 |
+
allNodes[nodeId].hiddenLabel = undefined;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
highlightActive = false;
|
75 |
+
}
|
76 |
+
|
77 |
+
// transform the object into an array
|
78 |
+
var updateArray = [];
|
79 |
+
if (params.nodes.length > 0) {
|
80 |
+
for (let nodeId in allNodes) {
|
81 |
+
if (allNodes.hasOwnProperty(nodeId)) {
|
82 |
+
// console.log(allNodes[nodeId]);
|
83 |
+
updateArray.push(allNodes[nodeId]);
|
84 |
+
}
|
85 |
+
}
|
86 |
+
nodes.update(updateArray);
|
87 |
+
} else {
|
88 |
+
// console.log("Nothing was selected");
|
89 |
+
for (let nodeId in allNodes) {
|
90 |
+
if (allNodes.hasOwnProperty(nodeId)) {
|
91 |
+
// console.log(allNodes[nodeId]);
|
92 |
+
// allNodes[nodeId].color = {};
|
93 |
+
updateArray.push(allNodes[nodeId]);
|
94 |
+
}
|
95 |
+
}
|
96 |
+
nodes.update(updateArray);
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
function filterHighlight(params) {
|
101 |
+
allNodes = nodes.get({ returnType: "Object" });
|
102 |
+
// if something is selected:
|
103 |
+
if (params.nodes.length > 0) {
|
104 |
+
filterActive = true;
|
105 |
+
let selectedNodes = params.nodes;
|
106 |
+
|
107 |
+
// hiding all nodes and saving the label
|
108 |
+
for (let nodeId in allNodes) {
|
109 |
+
allNodes[nodeId].hidden = true;
|
110 |
+
if (allNodes[nodeId].savedLabel === undefined) {
|
111 |
+
allNodes[nodeId].savedLabel = allNodes[nodeId].label;
|
112 |
+
allNodes[nodeId].label = undefined;
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
for (let i=0; i < selectedNodes.length; i++) {
|
117 |
+
allNodes[selectedNodes[i]].hidden = false;
|
118 |
+
if (allNodes[selectedNodes[i]].savedLabel !== undefined) {
|
119 |
+
allNodes[selectedNodes[i]].label = allNodes[selectedNodes[i]].savedLabel;
|
120 |
+
allNodes[selectedNodes[i]].savedLabel = undefined;
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
} else if (filterActive === true) {
|
125 |
+
// reset all nodes
|
126 |
+
for (let nodeId in allNodes) {
|
127 |
+
allNodes[nodeId].hidden = false;
|
128 |
+
if (allNodes[nodeId].savedLabel !== undefined) {
|
129 |
+
allNodes[nodeId].label = allNodes[nodeId].savedLabel;
|
130 |
+
allNodes[nodeId].savedLabel = undefined;
|
131 |
+
}
|
132 |
+
}
|
133 |
+
filterActive = false;
|
134 |
+
}
|
135 |
+
|
136 |
+
// transform the object into an array
|
137 |
+
var updateArray = [];
|
138 |
+
if (params.nodes.length > 0) {
|
139 |
+
for (let nodeId in allNodes) {
|
140 |
+
if (allNodes.hasOwnProperty(nodeId)) {
|
141 |
+
updateArray.push(allNodes[nodeId]);
|
142 |
+
}
|
143 |
+
}
|
144 |
+
nodes.update(updateArray);
|
145 |
+
} else {
|
146 |
+
for (let nodeId in allNodes) {
|
147 |
+
if (allNodes.hasOwnProperty(nodeId)) {
|
148 |
+
updateArray.push(allNodes[nodeId]);
|
149 |
+
}
|
150 |
+
}
|
151 |
+
nodes.update(updateArray);
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
function selectNode(nodes) {
|
156 |
+
network.selectNodes(nodes);
|
157 |
+
neighbourhoodHighlight({ nodes: nodes });
|
158 |
+
return nodes;
|
159 |
+
}
|
160 |
+
|
161 |
+
function selectNodes(nodes) {
|
162 |
+
network.selectNodes(nodes);
|
163 |
+
filterHighlight({nodes: nodes});
|
164 |
+
return nodes;
|
165 |
+
}
|
166 |
+
|
167 |
+
function highlightFilter(filter) {
|
168 |
+
let selectedNodes = []
|
169 |
+
let selectedProp = filter['property']
|
170 |
+
if (filter['item'] === 'node') {
|
171 |
+
let allNodes = nodes.get({ returnType: "Object" });
|
172 |
+
for (let nodeId in allNodes) {
|
173 |
+
if (allNodes[nodeId][selectedProp] && filter['value'].includes((allNodes[nodeId][selectedProp]).toString())) {
|
174 |
+
selectedNodes.push(nodeId)
|
175 |
+
}
|
176 |
+
}
|
177 |
+
}
|
178 |
+
else if (filter['item'] === 'edge'){
|
179 |
+
let allEdges = edges.get({returnType: 'object'});
|
180 |
+
// check if the selected property exists for selected edge and select the nodes connected to the edge
|
181 |
+
for (let edge in allEdges) {
|
182 |
+
if (allEdges[edge][selectedProp] && filter['value'].includes((allEdges[edge][selectedProp]).toString())) {
|
183 |
+
selectedNodes.push(allEdges[edge]['from'])
|
184 |
+
selectedNodes.push(allEdges[edge]['to'])
|
185 |
+
}
|
186 |
+
}
|
187 |
+
}
|
188 |
+
selectNodes(selectedNodes)
|
189 |
+
}
|
lib/tom-select/tom-select.complete.min.js
ADDED
@@ -0,0 +1,356 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Tom Select v2.0.0-rc.4
|
3 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
4 |
+
*/
|
5 |
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).TomSelect=t()}(this,(function(){"use strict"
|
6 |
+
function e(e,t){e.split(/\s+/).forEach((e=>{t(e)}))}class t{constructor(){this._events={}}on(t,i){e(t,(e=>{this._events[e]=this._events[e]||[],this._events[e].push(i)}))}off(t,i){var s=arguments.length
|
7 |
+
0!==s?e(t,(e=>{if(1===s)return delete this._events[e]
|
8 |
+
e in this._events!=!1&&this._events[e].splice(this._events[e].indexOf(i),1)})):this._events={}}trigger(t,...i){var s=this
|
9 |
+
e(t,(e=>{if(e in s._events!=!1)for(let t of s._events[e])t.apply(s,i)}))}}var i
|
10 |
+
const s="[̀-ͯ·ʾ]",n=new RegExp(s,"g")
|
11 |
+
var o
|
12 |
+
const r={"æ":"ae","ⱥ":"a","ø":"o"},l=new RegExp(Object.keys(r).join("|"),"g"),a=[[67,67],[160,160],[192,438],[452,652],[961,961],[1019,1019],[1083,1083],[1281,1289],[1984,1984],[5095,5095],[7429,7441],[7545,7549],[7680,7935],[8580,8580],[9398,9449],[11360,11391],[42792,42793],[42802,42851],[42873,42897],[42912,42922],[64256,64260],[65313,65338],[65345,65370]],c=e=>e.normalize("NFKD").replace(n,"").toLowerCase().replace(l,(function(e){return r[e]})),d=(e,t="|")=>{if(1==e.length)return e[0]
|
13 |
+
var i=1
|
14 |
+
return e.forEach((e=>{i=Math.max(i,e.length)})),1==i?"["+e.join("")+"]":"(?:"+e.join(t)+")"},p=e=>{if(1===e.length)return[[e]]
|
15 |
+
var t=[]
|
16 |
+
return p(e.substring(1)).forEach((function(i){var s=i.slice(0)
|
17 |
+
s[0]=e.charAt(0)+s[0],t.push(s),(s=i.slice(0)).unshift(e.charAt(0)),t.push(s)})),t},u=e=>{void 0===o&&(o=(()=>{var e={}
|
18 |
+
a.forEach((t=>{for(let s=t[0];s<=t[1];s++){let t=String.fromCharCode(s),n=c(t)
|
19 |
+
if(n!=t.toLowerCase()){n in e||(e[n]=[n])
|
20 |
+
var i=new RegExp(d(e[n]),"iu")
|
21 |
+
t.match(i)||e[n].push(t)}}}))
|
22 |
+
var t=Object.keys(e)
|
23 |
+
t=t.sort(((e,t)=>t.length-e.length)),i=new RegExp("("+d(t)+"[̀-ͯ·ʾ]*)","g")
|
24 |
+
var s={}
|
25 |
+
return t.sort(((e,t)=>e.length-t.length)).forEach((t=>{var i=p(t).map((t=>(t=t.map((t=>e.hasOwnProperty(t)?d(e[t]):t)),d(t,""))))
|
26 |
+
s[t]=d(i)})),s})())
|
27 |
+
return e.normalize("NFKD").toLowerCase().split(i).map((e=>{if(""==e)return""
|
28 |
+
const t=c(e)
|
29 |
+
if(o.hasOwnProperty(t))return o[t]
|
30 |
+
const i=e.normalize("NFC")
|
31 |
+
return i!=e?d([e,i]):e})).join("")},h=(e,t)=>{if(e)return e[t]},g=(e,t)=>{if(e){for(var i,s=t.split(".");(i=s.shift())&&(e=e[i]););return e}},f=(e,t,i)=>{var s,n
|
32 |
+
return e?-1===(n=(e+="").search(t.regex))?0:(s=t.string.length/e.length,0===n&&(s+=.5),s*i):0},v=e=>(e+"").replace(/([\$\(-\+\.\?\[-\^\{-\}])/g,"\\$1"),m=(e,t)=>{var i=e[t]
|
33 |
+
if("function"==typeof i)return i
|
34 |
+
i&&!Array.isArray(i)&&(e[t]=[i])},y=(e,t)=>{if(Array.isArray(e))e.forEach(t)
|
35 |
+
else for(var i in e)e.hasOwnProperty(i)&&t(e[i],i)},O=(e,t)=>"number"==typeof e&&"number"==typeof t?e>t?1:e<t?-1:0:(e=c(e+"").toLowerCase())>(t=c(t+"").toLowerCase())?1:t>e?-1:0
|
36 |
+
class b{constructor(e,t){this.items=e,this.settings=t||{diacritics:!0}}tokenize(e,t,i){if(!e||!e.length)return[]
|
37 |
+
const s=[],n=e.split(/\s+/)
|
38 |
+
var o
|
39 |
+
return i&&(o=new RegExp("^("+Object.keys(i).map(v).join("|")+"):(.*)$")),n.forEach((e=>{let i,n=null,r=null
|
40 |
+
o&&(i=e.match(o))&&(n=i[1],e=i[2]),e.length>0&&(r=v(e),this.settings.diacritics&&(r=u(r)),t&&(r="\\b"+r)),s.push({string:e,regex:r?new RegExp(r,"iu"):null,field:n})})),s}getScoreFunction(e,t){var i=this.prepareSearch(e,t)
|
41 |
+
return this._getScoreFunction(i)}_getScoreFunction(e){const t=e.tokens,i=t.length
|
42 |
+
if(!i)return function(){return 0}
|
43 |
+
const s=e.options.fields,n=e.weights,o=s.length,r=e.getAttrFn
|
44 |
+
if(!o)return function(){return 1}
|
45 |
+
const l=1===o?function(e,t){const i=s[0].field
|
46 |
+
return f(r(t,i),e,n[i])}:function(e,t){var i=0
|
47 |
+
if(e.field){const s=r(t,e.field)
|
48 |
+
!e.regex&&s?i+=1/o:i+=f(s,e,1)}else y(n,((s,n)=>{i+=f(r(t,n),e,s)}))
|
49 |
+
return i/o}
|
50 |
+
return 1===i?function(e){return l(t[0],e)}:"and"===e.options.conjunction?function(e){for(var s,n=0,o=0;n<i;n++){if((s=l(t[n],e))<=0)return 0
|
51 |
+
o+=s}return o/i}:function(e){var s=0
|
52 |
+
return y(t,(t=>{s+=l(t,e)})),s/i}}getSortFunction(e,t){var i=this.prepareSearch(e,t)
|
53 |
+
return this._getSortFunction(i)}_getSortFunction(e){var t,i,s
|
54 |
+
const n=this,o=e.options,r=!e.query&&o.sort_empty?o.sort_empty:o.sort,l=[],a=[]
|
55 |
+
if("function"==typeof r)return r.bind(this)
|
56 |
+
const c=function(t,i){return"$score"===t?i.score:e.getAttrFn(n.items[i.id],t)}
|
57 |
+
if(r)for(t=0,i=r.length;t<i;t++)(e.query||"$score"!==r[t].field)&&l.push(r[t])
|
58 |
+
if(e.query){for(s=!0,t=0,i=l.length;t<i;t++)if("$score"===l[t].field){s=!1
|
59 |
+
break}s&&l.unshift({field:"$score",direction:"desc"})}else for(t=0,i=l.length;t<i;t++)if("$score"===l[t].field){l.splice(t,1)
|
60 |
+
break}for(t=0,i=l.length;t<i;t++)a.push("desc"===l[t].direction?-1:1)
|
61 |
+
const d=l.length
|
62 |
+
if(d){if(1===d){const e=l[0].field,t=a[0]
|
63 |
+
return function(i,s){return t*O(c(e,i),c(e,s))}}return function(e,t){var i,s,n
|
64 |
+
for(i=0;i<d;i++)if(n=l[i].field,s=a[i]*O(c(n,e),c(n,t)))return s
|
65 |
+
return 0}}return null}prepareSearch(e,t){const i={}
|
66 |
+
var s=Object.assign({},t)
|
67 |
+
if(m(s,"sort"),m(s,"sort_empty"),s.fields){m(s,"fields")
|
68 |
+
const e=[]
|
69 |
+
s.fields.forEach((t=>{"string"==typeof t&&(t={field:t,weight:1}),e.push(t),i[t.field]="weight"in t?t.weight:1})),s.fields=e}return{options:s,query:e.toLowerCase().trim(),tokens:this.tokenize(e,s.respect_word_boundaries,i),total:0,items:[],weights:i,getAttrFn:s.nesting?g:h}}search(e,t){var i,s,n=this
|
70 |
+
s=this.prepareSearch(e,t),t=s.options,e=s.query
|
71 |
+
const o=t.score||n._getScoreFunction(s)
|
72 |
+
e.length?y(n.items,((e,n)=>{i=o(e),(!1===t.filter||i>0)&&s.items.push({score:i,id:n})})):y(n.items,((e,t)=>{s.items.push({score:1,id:t})}))
|
73 |
+
const r=n._getSortFunction(s)
|
74 |
+
return r&&s.items.sort(r),s.total=s.items.length,"number"==typeof t.limit&&(s.items=s.items.slice(0,t.limit)),s}}const w=e=>{if(e.jquery)return e[0]
|
75 |
+
if(e instanceof HTMLElement)return e
|
76 |
+
if(e.indexOf("<")>-1){let t=document.createElement("div")
|
77 |
+
return t.innerHTML=e.trim(),t.firstChild}return document.querySelector(e)},_=(e,t)=>{var i=document.createEvent("HTMLEvents")
|
78 |
+
i.initEvent(t,!0,!1),e.dispatchEvent(i)},I=(e,t)=>{Object.assign(e.style,t)},C=(e,...t)=>{var i=A(t);(e=x(e)).map((e=>{i.map((t=>{e.classList.add(t)}))}))},S=(e,...t)=>{var i=A(t);(e=x(e)).map((e=>{i.map((t=>{e.classList.remove(t)}))}))},A=e=>{var t=[]
|
79 |
+
return y(e,(e=>{"string"==typeof e&&(e=e.trim().split(/[\11\12\14\15\40]/)),Array.isArray(e)&&(t=t.concat(e))})),t.filter(Boolean)},x=e=>(Array.isArray(e)||(e=[e]),e),k=(e,t,i)=>{if(!i||i.contains(e))for(;e&&e.matches;){if(e.matches(t))return e
|
80 |
+
e=e.parentNode}},F=(e,t=0)=>t>0?e[e.length-1]:e[0],L=(e,t)=>{if(!e)return-1
|
81 |
+
t=t||e.nodeName
|
82 |
+
for(var i=0;e=e.previousElementSibling;)e.matches(t)&&i++
|
83 |
+
return i},P=(e,t)=>{y(t,((t,i)=>{null==t?e.removeAttribute(i):e.setAttribute(i,""+t)}))},E=(e,t)=>{e.parentNode&&e.parentNode.replaceChild(t,e)},T=(e,t)=>{if(null===t)return
|
84 |
+
if("string"==typeof t){if(!t.length)return
|
85 |
+
t=new RegExp(t,"i")}const i=e=>3===e.nodeType?(e=>{var i=e.data.match(t)
|
86 |
+
if(i&&e.data.length>0){var s=document.createElement("span")
|
87 |
+
s.className="highlight"
|
88 |
+
var n=e.splitText(i.index)
|
89 |
+
n.splitText(i[0].length)
|
90 |
+
var o=n.cloneNode(!0)
|
91 |
+
return s.appendChild(o),E(n,s),1}return 0})(e):((e=>{if(1===e.nodeType&&e.childNodes&&!/(script|style)/i.test(e.tagName)&&("highlight"!==e.className||"SPAN"!==e.tagName))for(var t=0;t<e.childNodes.length;++t)t+=i(e.childNodes[t])})(e),0)
|
92 |
+
i(e)},V="undefined"!=typeof navigator&&/Mac/.test(navigator.userAgent)?"metaKey":"ctrlKey"
|
93 |
+
var j={options:[],optgroups:[],plugins:[],delimiter:",",splitOn:null,persist:!0,diacritics:!0,create:null,createOnBlur:!1,createFilter:null,highlight:!0,openOnFocus:!0,shouldOpen:null,maxOptions:50,maxItems:null,hideSelected:null,duplicates:!1,addPrecedence:!1,selectOnTab:!1,preload:null,allowEmptyOption:!1,loadThrottle:300,loadingClass:"loading",dataAttr:null,optgroupField:"optgroup",valueField:"value",labelField:"text",disabledField:"disabled",optgroupLabelField:"label",optgroupValueField:"value",lockOptgroupOrder:!1,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"ts-wrapper",controlClass:"ts-control",dropdownClass:"ts-dropdown",dropdownContentClass:"ts-dropdown-content",itemClass:"item",optionClass:"option",dropdownParent:null,copyClassesToDropdown:!1,placeholder:null,hidePlaceholder:null,shouldLoad:function(e){return e.length>0},render:{}}
|
94 |
+
const q=e=>null==e?null:D(e),D=e=>"boolean"==typeof e?e?"1":"0":e+"",N=e=>(e+"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""),z=(e,t)=>{var i
|
95 |
+
return function(s,n){var o=this
|
96 |
+
i&&(o.loading=Math.max(o.loading-1,0),clearTimeout(i)),i=setTimeout((function(){i=null,o.loadedSearches[s]=!0,e.call(o,s,n)}),t)}},R=(e,t,i)=>{var s,n=e.trigger,o={}
|
97 |
+
for(s in e.trigger=function(){var i=arguments[0]
|
98 |
+
if(-1===t.indexOf(i))return n.apply(e,arguments)
|
99 |
+
o[i]=arguments},i.apply(e,[]),e.trigger=n,o)n.apply(e,o[s])},H=(e,t=!1)=>{e&&(e.preventDefault(),t&&e.stopPropagation())},B=(e,t,i,s)=>{e.addEventListener(t,i,s)},K=(e,t)=>!!t&&(!!t[e]&&1===(t.altKey?1:0)+(t.ctrlKey?1:0)+(t.shiftKey?1:0)+(t.metaKey?1:0)),M=(e,t)=>{const i=e.getAttribute("id")
|
100 |
+
return i||(e.setAttribute("id",t),t)},Q=e=>e.replace(/[\\"']/g,"\\$&"),G=(e,t)=>{t&&e.append(t)}
|
101 |
+
function U(e,t){var i=Object.assign({},j,t),s=i.dataAttr,n=i.labelField,o=i.valueField,r=i.disabledField,l=i.optgroupField,a=i.optgroupLabelField,c=i.optgroupValueField,d=e.tagName.toLowerCase(),p=e.getAttribute("placeholder")||e.getAttribute("data-placeholder")
|
102 |
+
if(!p&&!i.allowEmptyOption){let t=e.querySelector('option[value=""]')
|
103 |
+
t&&(p=t.textContent)}var u,h,g,f,v,m,O={placeholder:p,options:[],optgroups:[],items:[],maxItems:null}
|
104 |
+
return"select"===d?(h=O.options,g={},f=1,v=e=>{var t=Object.assign({},e.dataset),i=s&&t[s]
|
105 |
+
return"string"==typeof i&&i.length&&(t=Object.assign(t,JSON.parse(i))),t},m=(e,t)=>{var s=q(e.value)
|
106 |
+
if(null!=s&&(s||i.allowEmptyOption)){if(g.hasOwnProperty(s)){if(t){var a=g[s][l]
|
107 |
+
a?Array.isArray(a)?a.push(t):g[s][l]=[a,t]:g[s][l]=t}}else{var c=v(e)
|
108 |
+
c[n]=c[n]||e.textContent,c[o]=c[o]||s,c[r]=c[r]||e.disabled,c[l]=c[l]||t,c.$option=e,g[s]=c,h.push(c)}e.selected&&O.items.push(s)}},O.maxItems=e.hasAttribute("multiple")?null:1,y(e.children,(e=>{var t,i,s
|
109 |
+
"optgroup"===(u=e.tagName.toLowerCase())?((s=v(t=e))[a]=s[a]||t.getAttribute("label")||"",s[c]=s[c]||f++,s[r]=s[r]||t.disabled,O.optgroups.push(s),i=s[c],y(t.children,(e=>{m(e,i)}))):"option"===u&&m(e)}))):(()=>{const t=e.getAttribute(s)
|
110 |
+
if(t)O.options=JSON.parse(t),y(O.options,(e=>{O.items.push(e[o])}))
|
111 |
+
else{var r=e.value.trim()||""
|
112 |
+
if(!i.allowEmptyOption&&!r.length)return
|
113 |
+
const t=r.split(i.delimiter)
|
114 |
+
y(t,(e=>{const t={}
|
115 |
+
t[n]=e,t[o]=e,O.options.push(t)})),O.items=t}})(),Object.assign({},j,O,t)}var W=0
|
116 |
+
class J extends(function(e){return e.plugins={},class extends e{constructor(...e){super(...e),this.plugins={names:[],settings:{},requested:{},loaded:{}}}static define(t,i){e.plugins[t]={name:t,fn:i}}initializePlugins(e){var t,i
|
117 |
+
const s=this,n=[]
|
118 |
+
if(Array.isArray(e))e.forEach((e=>{"string"==typeof e?n.push(e):(s.plugins.settings[e.name]=e.options,n.push(e.name))}))
|
119 |
+
else if(e)for(t in e)e.hasOwnProperty(t)&&(s.plugins.settings[t]=e[t],n.push(t))
|
120 |
+
for(;i=n.shift();)s.require(i)}loadPlugin(t){var i=this,s=i.plugins,n=e.plugins[t]
|
121 |
+
if(!e.plugins.hasOwnProperty(t))throw new Error('Unable to find "'+t+'" plugin')
|
122 |
+
s.requested[t]=!0,s.loaded[t]=n.fn.apply(i,[i.plugins.settings[t]||{}]),s.names.push(t)}require(e){var t=this,i=t.plugins
|
123 |
+
if(!t.plugins.loaded.hasOwnProperty(e)){if(i.requested[e])throw new Error('Plugin has circular dependency ("'+e+'")')
|
124 |
+
t.loadPlugin(e)}return i.loaded[e]}}}(t)){constructor(e,t){var i
|
125 |
+
super(),this.order=0,this.isOpen=!1,this.isDisabled=!1,this.isInvalid=!1,this.isValid=!0,this.isLocked=!1,this.isFocused=!1,this.isInputHidden=!1,this.isSetup=!1,this.ignoreFocus=!1,this.hasOptions=!1,this.lastValue="",this.caretPos=0,this.loading=0,this.loadedSearches={},this.activeOption=null,this.activeItems=[],this.optgroups={},this.options={},this.userOptions={},this.items=[],W++
|
126 |
+
var s=w(e)
|
127 |
+
if(s.tomselect)throw new Error("Tom Select already initialized on this element")
|
128 |
+
s.tomselect=this,i=(window.getComputedStyle&&window.getComputedStyle(s,null)).getPropertyValue("direction")
|
129 |
+
const n=U(s,t)
|
130 |
+
this.settings=n,this.input=s,this.tabIndex=s.tabIndex||0,this.is_select_tag="select"===s.tagName.toLowerCase(),this.rtl=/rtl/i.test(i),this.inputId=M(s,"tomselect-"+W),this.isRequired=s.required,this.sifter=new b(this.options,{diacritics:n.diacritics}),n.mode=n.mode||(1===n.maxItems?"single":"multi"),"boolean"!=typeof n.hideSelected&&(n.hideSelected="multi"===n.mode),"boolean"!=typeof n.hidePlaceholder&&(n.hidePlaceholder="multi"!==n.mode)
|
131 |
+
var o=n.createFilter
|
132 |
+
"function"!=typeof o&&("string"==typeof o&&(o=new RegExp(o)),o instanceof RegExp?n.createFilter=e=>o.test(e):n.createFilter=()=>!0),this.initializePlugins(n.plugins),this.setupCallbacks(),this.setupTemplates()
|
133 |
+
const r=w("<div>"),l=w("<div>"),a=this._render("dropdown"),c=w('<div role="listbox" tabindex="-1">'),d=this.input.getAttribute("class")||"",p=n.mode
|
134 |
+
var u
|
135 |
+
if(C(r,n.wrapperClass,d,p),C(l,n.controlClass),G(r,l),C(a,n.dropdownClass,p),n.copyClassesToDropdown&&C(a,d),C(c,n.dropdownContentClass),G(a,c),w(n.dropdownParent||r).appendChild(a),n.hasOwnProperty("controlInput"))n.controlInput?(u=w(n.controlInput),this.focus_node=u):(u=w("<input/>"),this.focus_node=l)
|
136 |
+
else{u=w('<input type="text" autocomplete="off" size="1" />')
|
137 |
+
y(["autocorrect","autocapitalize","autocomplete"],(e=>{s.getAttribute(e)&&P(u,{[e]:s.getAttribute(e)})})),u.tabIndex=-1,l.appendChild(u),this.focus_node=u}this.wrapper=r,this.dropdown=a,this.dropdown_content=c,this.control=l,this.control_input=u,this.setup()}setup(){const e=this,t=e.settings,i=e.control_input,s=e.dropdown,n=e.dropdown_content,o=e.wrapper,r=e.control,l=e.input,a=e.focus_node,c={passive:!0},d=e.inputId+"-ts-dropdown"
|
138 |
+
P(n,{id:d}),P(a,{role:"combobox","aria-haspopup":"listbox","aria-expanded":"false","aria-controls":d})
|
139 |
+
const p=M(a,e.inputId+"-ts-control"),u="label[for='"+(e=>e.replace(/['"\\]/g,"\\$&"))(e.inputId)+"']",h=document.querySelector(u),g=e.focus.bind(e)
|
140 |
+
if(h){B(h,"click",g),P(h,{for:p})
|
141 |
+
const t=M(h,e.inputId+"-ts-label")
|
142 |
+
P(a,{"aria-labelledby":t}),P(n,{"aria-labelledby":t})}if(o.style.width=l.style.width,e.plugins.names.length){const t="plugin-"+e.plugins.names.join(" plugin-")
|
143 |
+
C([o,s],t)}(null===t.maxItems||t.maxItems>1)&&e.is_select_tag&&P(l,{multiple:"multiple"}),e.settings.placeholder&&P(i,{placeholder:t.placeholder}),!e.settings.splitOn&&e.settings.delimiter&&(e.settings.splitOn=new RegExp("\\s*"+v(e.settings.delimiter)+"+\\s*")),t.load&&t.loadThrottle&&(t.load=z(t.load,t.loadThrottle)),e.control_input.type=l.type,B(s,"click",(t=>{const i=k(t.target,"[data-selectable]")
|
144 |
+
i&&(e.onOptionSelect(t,i),H(t,!0))})),B(r,"click",(t=>{var s=k(t.target,"[data-ts-item]",r)
|
145 |
+
s&&e.onItemSelect(t,s)?H(t,!0):""==i.value&&(e.onClick(),H(t,!0))})),B(i,"mousedown",(e=>{""!==i.value&&e.stopPropagation()})),B(a,"keydown",(t=>e.onKeyDown(t))),B(i,"keypress",(t=>e.onKeyPress(t))),B(i,"input",(t=>e.onInput(t))),B(a,"resize",(()=>e.positionDropdown()),c),B(a,"blur",(t=>e.onBlur(t))),B(a,"focus",(t=>e.onFocus(t))),B(a,"paste",(t=>e.onPaste(t)))
|
146 |
+
const f=t=>{const i=t.composedPath()[0]
|
147 |
+
if(!o.contains(i)&&!s.contains(i))return e.isFocused&&e.blur(),void e.inputState()
|
148 |
+
H(t,!0)}
|
149 |
+
var m=()=>{e.isOpen&&e.positionDropdown()}
|
150 |
+
B(document,"mousedown",f),B(window,"scroll",m,c),B(window,"resize",m,c),this._destroy=()=>{document.removeEventListener("mousedown",f),window.removeEventListener("sroll",m),window.removeEventListener("resize",m),h&&h.removeEventListener("click",g)},this.revertSettings={innerHTML:l.innerHTML,tabIndex:l.tabIndex},l.tabIndex=-1,l.insertAdjacentElement("afterend",e.wrapper),e.sync(!1),t.items=[],delete t.optgroups,delete t.options,B(l,"invalid",(t=>{e.isValid&&(e.isValid=!1,e.isInvalid=!0,e.refreshState())})),e.updateOriginalInput(),e.refreshItems(),e.close(!1),e.inputState(),e.isSetup=!0,l.disabled?e.disable():e.enable(),e.on("change",this.onChange),C(l,"tomselected","ts-hidden-accessible"),e.trigger("initialize"),!0===t.preload&&e.preload()}setupOptions(e=[],t=[]){this.addOptions(e),y(t,(e=>{this.registerOptionGroup(e)}))}setupTemplates(){var e=this,t=e.settings.labelField,i=e.settings.optgroupLabelField,s={optgroup:e=>{let t=document.createElement("div")
|
151 |
+
return t.className="optgroup",t.appendChild(e.options),t},optgroup_header:(e,t)=>'<div class="optgroup-header">'+t(e[i])+"</div>",option:(e,i)=>"<div>"+i(e[t])+"</div>",item:(e,i)=>"<div>"+i(e[t])+"</div>",option_create:(e,t)=>'<div class="create">Add <strong>'+t(e.input)+"</strong>…</div>",no_results:()=>'<div class="no-results">No results found</div>',loading:()=>'<div class="spinner"></div>',not_loading:()=>{},dropdown:()=>"<div></div>"}
|
152 |
+
e.settings.render=Object.assign({},s,e.settings.render)}setupCallbacks(){var e,t,i={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",item_select:"onItemSelect",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",optgroup_add:"onOptionGroupAdd",optgroup_remove:"onOptionGroupRemove",optgroup_clear:"onOptionGroupClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType",load:"onLoad",focus:"onFocus",blur:"onBlur"}
|
153 |
+
for(e in i)(t=this.settings[i[e]])&&this.on(e,t)}sync(e=!0){const t=this,i=e?U(t.input,{delimiter:t.settings.delimiter}):t.settings
|
154 |
+
t.setupOptions(i.options,i.optgroups),t.setValue(i.items,!0),t.lastQuery=null}onClick(){var e=this
|
155 |
+
if(e.activeItems.length>0)return e.clearActiveItems(),void e.focus()
|
156 |
+
e.isFocused&&e.isOpen?e.blur():e.focus()}onMouseDown(){}onChange(){_(this.input,"input"),_(this.input,"change")}onPaste(e){var t=this
|
157 |
+
t.isFull()||t.isInputHidden||t.isLocked?H(e):t.settings.splitOn&&setTimeout((()=>{var e=t.inputValue()
|
158 |
+
if(e.match(t.settings.splitOn)){var i=e.trim().split(t.settings.splitOn)
|
159 |
+
y(i,(e=>{t.createItem(e)}))}}),0)}onKeyPress(e){var t=this
|
160 |
+
if(!t.isLocked){var i=String.fromCharCode(e.keyCode||e.which)
|
161 |
+
return t.settings.create&&"multi"===t.settings.mode&&i===t.settings.delimiter?(t.createItem(),void H(e)):void 0}H(e)}onKeyDown(e){var t=this
|
162 |
+
if(t.isLocked)9!==e.keyCode&&H(e)
|
163 |
+
else{switch(e.keyCode){case 65:if(K(V,e))return H(e),void t.selectAll()
|
164 |
+
break
|
165 |
+
case 27:return t.isOpen&&(H(e,!0),t.close()),void t.clearActiveItems()
|
166 |
+
case 40:if(!t.isOpen&&t.hasOptions)t.open()
|
167 |
+
else if(t.activeOption){let e=t.getAdjacent(t.activeOption,1)
|
168 |
+
e&&t.setActiveOption(e)}return void H(e)
|
169 |
+
case 38:if(t.activeOption){let e=t.getAdjacent(t.activeOption,-1)
|
170 |
+
e&&t.setActiveOption(e)}return void H(e)
|
171 |
+
case 13:return void(t.isOpen&&t.activeOption?(t.onOptionSelect(e,t.activeOption),H(e)):t.settings.create&&t.createItem()&&H(e))
|
172 |
+
case 37:return void t.advanceSelection(-1,e)
|
173 |
+
case 39:return void t.advanceSelection(1,e)
|
174 |
+
case 9:return void(t.settings.selectOnTab&&(t.isOpen&&t.activeOption&&(t.onOptionSelect(e,t.activeOption),H(e)),t.settings.create&&t.createItem()&&H(e)))
|
175 |
+
case 8:case 46:return void t.deleteSelection(e)}t.isInputHidden&&!K(V,e)&&H(e)}}onInput(e){var t=this
|
176 |
+
if(!t.isLocked){var i=t.inputValue()
|
177 |
+
t.lastValue!==i&&(t.lastValue=i,t.settings.shouldLoad.call(t,i)&&t.load(i),t.refreshOptions(),t.trigger("type",i))}}onFocus(e){var t=this,i=t.isFocused
|
178 |
+
if(t.isDisabled)return t.blur(),void H(e)
|
179 |
+
t.ignoreFocus||(t.isFocused=!0,"focus"===t.settings.preload&&t.preload(),i||t.trigger("focus"),t.activeItems.length||(t.showInput(),t.refreshOptions(!!t.settings.openOnFocus)),t.refreshState())}onBlur(e){if(!1!==document.hasFocus()){var t=this
|
180 |
+
if(t.isFocused){t.isFocused=!1,t.ignoreFocus=!1
|
181 |
+
var i=()=>{t.close(),t.setActiveItem(),t.setCaret(t.items.length),t.trigger("blur")}
|
182 |
+
t.settings.create&&t.settings.createOnBlur?t.createItem(null,!1,i):i()}}}onOptionSelect(e,t){var i,s=this
|
183 |
+
t&&(t.parentElement&&t.parentElement.matches("[data-disabled]")||(t.classList.contains("create")?s.createItem(null,!0,(()=>{s.settings.closeAfterSelect&&s.close()})):void 0!==(i=t.dataset.value)&&(s.lastQuery=null,s.addItem(i),s.settings.closeAfterSelect&&s.close(),!s.settings.hideSelected&&e.type&&/click/.test(e.type)&&s.setActiveOption(t))))}onItemSelect(e,t){var i=this
|
184 |
+
return!i.isLocked&&"multi"===i.settings.mode&&(H(e),i.setActiveItem(t,e),!0)}canLoad(e){return!!this.settings.load&&!this.loadedSearches.hasOwnProperty(e)}load(e){const t=this
|
185 |
+
if(!t.canLoad(e))return
|
186 |
+
C(t.wrapper,t.settings.loadingClass),t.loading++
|
187 |
+
const i=t.loadCallback.bind(t)
|
188 |
+
t.settings.load.call(t,e,i)}loadCallback(e,t){const i=this
|
189 |
+
i.loading=Math.max(i.loading-1,0),i.lastQuery=null,i.clearActiveOption(),i.setupOptions(e,t),i.refreshOptions(i.isFocused&&!i.isInputHidden),i.loading||S(i.wrapper,i.settings.loadingClass),i.trigger("load",e,t)}preload(){var e=this.wrapper.classList
|
190 |
+
e.contains("preloaded")||(e.add("preloaded"),this.load(""))}setTextboxValue(e=""){var t=this.control_input
|
191 |
+
t.value!==e&&(t.value=e,_(t,"update"),this.lastValue=e)}getValue(){return this.is_select_tag&&this.input.hasAttribute("multiple")?this.items:this.items.join(this.settings.delimiter)}setValue(e,t){R(this,t?[]:["change"],(()=>{this.clear(t),this.addItems(e,t)}))}setMaxItems(e){0===e&&(e=null),this.settings.maxItems=e,this.refreshState()}setActiveItem(e,t){var i,s,n,o,r,l,a=this
|
192 |
+
if("single"!==a.settings.mode){if(!e)return a.clearActiveItems(),void(a.isFocused&&a.showInput())
|
193 |
+
if("click"===(i=t&&t.type.toLowerCase())&&K("shiftKey",t)&&a.activeItems.length){for(l=a.getLastActive(),(n=Array.prototype.indexOf.call(a.control.children,l))>(o=Array.prototype.indexOf.call(a.control.children,e))&&(r=n,n=o,o=r),s=n;s<=o;s++)e=a.control.children[s],-1===a.activeItems.indexOf(e)&&a.setActiveItemClass(e)
|
194 |
+
H(t)}else"click"===i&&K(V,t)||"keydown"===i&&K("shiftKey",t)?e.classList.contains("active")?a.removeActiveItem(e):a.setActiveItemClass(e):(a.clearActiveItems(),a.setActiveItemClass(e))
|
195 |
+
a.hideInput(),a.isFocused||a.focus()}}setActiveItemClass(e){const t=this,i=t.control.querySelector(".last-active")
|
196 |
+
i&&S(i,"last-active"),C(e,"active last-active"),t.trigger("item_select",e),-1==t.activeItems.indexOf(e)&&t.activeItems.push(e)}removeActiveItem(e){var t=this.activeItems.indexOf(e)
|
197 |
+
this.activeItems.splice(t,1),S(e,"active")}clearActiveItems(){S(this.activeItems,"active"),this.activeItems=[]}setActiveOption(e){e!==this.activeOption&&(this.clearActiveOption(),e&&(this.activeOption=e,P(this.focus_node,{"aria-activedescendant":e.getAttribute("id")}),P(e,{"aria-selected":"true"}),C(e,"active"),this.scrollToOption(e)))}scrollToOption(e,t){if(!e)return
|
198 |
+
const i=this.dropdown_content,s=i.clientHeight,n=i.scrollTop||0,o=e.offsetHeight,r=e.getBoundingClientRect().top-i.getBoundingClientRect().top+n
|
199 |
+
r+o>s+n?this.scroll(r-s+o,t):r<n&&this.scroll(r,t)}scroll(e,t){const i=this.dropdown_content
|
200 |
+
t&&(i.style.scrollBehavior=t),i.scrollTop=e,i.style.scrollBehavior=""}clearActiveOption(){this.activeOption&&(S(this.activeOption,"active"),P(this.activeOption,{"aria-selected":null})),this.activeOption=null,P(this.focus_node,{"aria-activedescendant":null})}selectAll(){if("single"===this.settings.mode)return
|
201 |
+
const e=this.controlChildren()
|
202 |
+
e.length&&(this.hideInput(),this.close(),this.activeItems=e,C(e,"active"))}inputState(){var e=this
|
203 |
+
e.control.contains(e.control_input)&&(P(e.control_input,{placeholder:e.settings.placeholder}),e.activeItems.length>0||!e.isFocused&&e.settings.hidePlaceholder&&e.items.length>0?(e.setTextboxValue(),e.isInputHidden=!0):(e.settings.hidePlaceholder&&e.items.length>0&&P(e.control_input,{placeholder:""}),e.isInputHidden=!1),e.wrapper.classList.toggle("input-hidden",e.isInputHidden))}hideInput(){this.inputState()}showInput(){this.inputState()}inputValue(){return this.control_input.value.trim()}focus(){var e=this
|
204 |
+
e.isDisabled||(e.ignoreFocus=!0,e.control_input.offsetWidth?e.control_input.focus():e.focus_node.focus(),setTimeout((()=>{e.ignoreFocus=!1,e.onFocus()}),0))}blur(){this.focus_node.blur(),this.onBlur()}getScoreFunction(e){return this.sifter.getScoreFunction(e,this.getSearchOptions())}getSearchOptions(){var e=this.settings,t=e.sortField
|
205 |
+
return"string"==typeof e.sortField&&(t=[{field:e.sortField}]),{fields:e.searchField,conjunction:e.searchConjunction,sort:t,nesting:e.nesting}}search(e){var t,i,s,n=this,o=this.getSearchOptions()
|
206 |
+
if(n.settings.score&&"function"!=typeof(s=n.settings.score.call(n,e)))throw new Error('Tom Select "score" setting must be a function that returns a function')
|
207 |
+
if(e!==n.lastQuery?(n.lastQuery=e,i=n.sifter.search(e,Object.assign(o,{score:s})),n.currentResults=i):i=Object.assign({},n.currentResults),n.settings.hideSelected)for(t=i.items.length-1;t>=0;t--){let e=q(i.items[t].id)
|
208 |
+
e&&-1!==n.items.indexOf(e)&&i.items.splice(t,1)}return i}refreshOptions(e=!0){var t,i,s,n,o,r,l,a,c,d,p
|
209 |
+
const u={},h=[]
|
210 |
+
var g,f=this,v=f.inputValue(),m=f.search(v),O=f.activeOption,b=f.settings.shouldOpen||!1,w=f.dropdown_content
|
211 |
+
for(O&&(c=O.dataset.value,d=O.closest("[data-group]")),n=m.items.length,"number"==typeof f.settings.maxOptions&&(n=Math.min(n,f.settings.maxOptions)),n>0&&(b=!0),t=0;t<n;t++){let e=m.items[t].id,n=f.options[e],l=f.getOption(e,!0)
|
212 |
+
for(f.settings.hideSelected||l.classList.toggle("selected",f.items.includes(e)),o=n[f.settings.optgroupField]||"",i=0,s=(r=Array.isArray(o)?o:[o])&&r.length;i<s;i++)o=r[i],f.optgroups.hasOwnProperty(o)||(o=""),u.hasOwnProperty(o)||(u[o]=document.createDocumentFragment(),h.push(o)),i>0&&(l=l.cloneNode(!0),P(l,{id:n.$id+"-clone-"+i,"aria-selected":null}),l.classList.add("ts-cloned"),S(l,"active")),c==e&&d&&d.dataset.group===o&&(O=l),u[o].appendChild(l)}this.settings.lockOptgroupOrder&&h.sort(((e,t)=>(f.optgroups[e]&&f.optgroups[e].$order||0)-(f.optgroups[t]&&f.optgroups[t].$order||0))),l=document.createDocumentFragment(),y(h,(e=>{if(f.optgroups.hasOwnProperty(e)&&u[e].children.length){let t=document.createDocumentFragment(),i=f.render("optgroup_header",f.optgroups[e])
|
213 |
+
G(t,i),G(t,u[e])
|
214 |
+
let s=f.render("optgroup",{group:f.optgroups[e],options:t})
|
215 |
+
G(l,s)}else G(l,u[e])})),w.innerHTML="",G(w,l),f.settings.highlight&&(g=w.querySelectorAll("span.highlight"),Array.prototype.forEach.call(g,(function(e){var t=e.parentNode
|
216 |
+
t.replaceChild(e.firstChild,e),t.normalize()})),m.query.length&&m.tokens.length&&y(m.tokens,(e=>{T(w,e.regex)})))
|
217 |
+
var _=e=>{let t=f.render(e,{input:v})
|
218 |
+
return t&&(b=!0,w.insertBefore(t,w.firstChild)),t}
|
219 |
+
if(f.loading?_("loading"):f.settings.shouldLoad.call(f,v)?0===m.items.length&&_("no_results"):_("not_loading"),(a=f.canCreate(v))&&(p=_("option_create")),f.hasOptions=m.items.length>0||a,b){if(m.items.length>0){if(!w.contains(O)&&"single"===f.settings.mode&&f.items.length&&(O=f.getOption(f.items[0])),!w.contains(O)){let e=0
|
220 |
+
p&&!f.settings.addPrecedence&&(e=1),O=f.selectable()[e]}}else p&&(O=p)
|
221 |
+
e&&!f.isOpen&&(f.open(),f.scrollToOption(O,"auto")),f.setActiveOption(O)}else f.clearActiveOption(),e&&f.isOpen&&f.close(!1)}selectable(){return this.dropdown_content.querySelectorAll("[data-selectable]")}addOption(e,t=!1){const i=this
|
222 |
+
if(Array.isArray(e))return i.addOptions(e,t),!1
|
223 |
+
const s=q(e[i.settings.valueField])
|
224 |
+
return null!==s&&!i.options.hasOwnProperty(s)&&(e.$order=e.$order||++i.order,e.$id=i.inputId+"-opt-"+e.$order,i.options[s]=e,i.lastQuery=null,t&&(i.userOptions[s]=t,i.trigger("option_add",s,e)),s)}addOptions(e,t=!1){y(e,(e=>{this.addOption(e,t)}))}registerOption(e){return this.addOption(e)}registerOptionGroup(e){var t=q(e[this.settings.optgroupValueField])
|
225 |
+
return null!==t&&(e.$order=e.$order||++this.order,this.optgroups[t]=e,t)}addOptionGroup(e,t){var i
|
226 |
+
t[this.settings.optgroupValueField]=e,(i=this.registerOptionGroup(t))&&this.trigger("optgroup_add",i,t)}removeOptionGroup(e){this.optgroups.hasOwnProperty(e)&&(delete this.optgroups[e],this.clearCache(),this.trigger("optgroup_remove",e))}clearOptionGroups(){this.optgroups={},this.clearCache(),this.trigger("optgroup_clear")}updateOption(e,t){const i=this
|
227 |
+
var s,n
|
228 |
+
const o=q(e),r=q(t[i.settings.valueField])
|
229 |
+
if(null===o)return
|
230 |
+
if(!i.options.hasOwnProperty(o))return
|
231 |
+
if("string"!=typeof r)throw new Error("Value must be set in option data")
|
232 |
+
const l=i.getOption(o),a=i.getItem(o)
|
233 |
+
if(t.$order=t.$order||i.options[o].$order,delete i.options[o],i.uncacheValue(r),i.options[r]=t,l){if(i.dropdown_content.contains(l)){const e=i._render("option",t)
|
234 |
+
E(l,e),i.activeOption===l&&i.setActiveOption(e)}l.remove()}a&&(-1!==(n=i.items.indexOf(o))&&i.items.splice(n,1,r),s=i._render("item",t),a.classList.contains("active")&&C(s,"active"),E(a,s)),i.lastQuery=null}removeOption(e,t){const i=this
|
235 |
+
e=D(e),i.uncacheValue(e),delete i.userOptions[e],delete i.options[e],i.lastQuery=null,i.trigger("option_remove",e),i.removeItem(e,t)}clearOptions(){this.loadedSearches={},this.userOptions={},this.clearCache()
|
236 |
+
var e={}
|
237 |
+
y(this.options,((t,i)=>{this.items.indexOf(i)>=0&&(e[i]=this.options[i])})),this.options=this.sifter.items=e,this.lastQuery=null,this.trigger("option_clear")}getOption(e,t=!1){const i=q(e)
|
238 |
+
if(null!==i&&this.options.hasOwnProperty(i)){const e=this.options[i]
|
239 |
+
if(e.$div)return e.$div
|
240 |
+
if(t)return this._render("option",e)}return null}getAdjacent(e,t,i="option"){var s
|
241 |
+
if(!e)return null
|
242 |
+
s="item"==i?this.controlChildren():this.dropdown_content.querySelectorAll("[data-selectable]")
|
243 |
+
for(let i=0;i<s.length;i++)if(s[i]==e)return t>0?s[i+1]:s[i-1]
|
244 |
+
return null}getItem(e){if("object"==typeof e)return e
|
245 |
+
var t=q(e)
|
246 |
+
return null!==t?this.control.querySelector(`[data-value="${Q(t)}"]`):null}addItems(e,t){var i=this,s=Array.isArray(e)?e:[e]
|
247 |
+
for(let e=0,n=(s=s.filter((e=>-1===i.items.indexOf(e)))).length;e<n;e++)i.isPending=e<n-1,i.addItem(s[e],t)}addItem(e,t){R(this,t?[]:["change"],(()=>{var i,s
|
248 |
+
const n=this,o=n.settings.mode,r=q(e)
|
249 |
+
if((!r||-1===n.items.indexOf(r)||("single"===o&&n.close(),"single"!==o&&n.settings.duplicates))&&null!==r&&n.options.hasOwnProperty(r)&&("single"===o&&n.clear(t),"multi"!==o||!n.isFull())){if(i=n._render("item",n.options[r]),n.control.contains(i)&&(i=i.cloneNode(!0)),s=n.isFull(),n.items.splice(n.caretPos,0,r),n.insertAtCaret(i),n.isSetup){if(!n.isPending&&n.settings.hideSelected){let e=n.getOption(r),t=n.getAdjacent(e,1)
|
250 |
+
t&&n.setActiveOption(t)}n.isPending||n.refreshOptions(n.isFocused&&"single"!==o),0!=n.settings.closeAfterSelect&&n.isFull()?n.close():n.isPending||n.positionDropdown(),n.trigger("item_add",r,i),n.isPending||n.updateOriginalInput({silent:t})}(!n.isPending||!s&&n.isFull())&&(n.inputState(),n.refreshState())}}))}removeItem(e=null,t){const i=this
|
251 |
+
if(!(e=i.getItem(e)))return
|
252 |
+
var s,n
|
253 |
+
const o=e.dataset.value
|
254 |
+
s=L(e),e.remove(),e.classList.contains("active")&&(n=i.activeItems.indexOf(e),i.activeItems.splice(n,1),S(e,"active")),i.items.splice(s,1),i.lastQuery=null,!i.settings.persist&&i.userOptions.hasOwnProperty(o)&&i.removeOption(o,t),s<i.caretPos&&i.setCaret(i.caretPos-1),i.updateOriginalInput({silent:t}),i.refreshState(),i.positionDropdown(),i.trigger("item_remove",o,e)}createItem(e=null,t=!0,i=(()=>{})){var s,n=this,o=n.caretPos
|
255 |
+
if(e=e||n.inputValue(),!n.canCreate(e))return i(),!1
|
256 |
+
n.lock()
|
257 |
+
var r=!1,l=e=>{if(n.unlock(),!e||"object"!=typeof e)return i()
|
258 |
+
var s=q(e[n.settings.valueField])
|
259 |
+
if("string"!=typeof s)return i()
|
260 |
+
n.setTextboxValue(),n.addOption(e,!0),n.setCaret(o),n.addItem(s),n.refreshOptions(t&&"single"!==n.settings.mode),i(e),r=!0}
|
261 |
+
return s="function"==typeof n.settings.create?n.settings.create.call(this,e,l):{[n.settings.labelField]:e,[n.settings.valueField]:e},r||l(s),!0}refreshItems(){var e=this
|
262 |
+
e.lastQuery=null,e.isSetup&&e.addItems(e.items),e.updateOriginalInput(),e.refreshState()}refreshState(){const e=this
|
263 |
+
e.refreshValidityState()
|
264 |
+
const t=e.isFull(),i=e.isLocked
|
265 |
+
e.wrapper.classList.toggle("rtl",e.rtl)
|
266 |
+
const s=e.wrapper.classList
|
267 |
+
var n
|
268 |
+
s.toggle("focus",e.isFocused),s.toggle("disabled",e.isDisabled),s.toggle("required",e.isRequired),s.toggle("invalid",!e.isValid),s.toggle("locked",i),s.toggle("full",t),s.toggle("input-active",e.isFocused&&!e.isInputHidden),s.toggle("dropdown-active",e.isOpen),s.toggle("has-options",(n=e.options,0===Object.keys(n).length)),s.toggle("has-items",e.items.length>0)}refreshValidityState(){var e=this
|
269 |
+
e.input.checkValidity&&(e.isValid=e.input.checkValidity(),e.isInvalid=!e.isValid)}isFull(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems}updateOriginalInput(e={}){const t=this
|
270 |
+
var i,s
|
271 |
+
const n=t.input.querySelector('option[value=""]')
|
272 |
+
if(t.is_select_tag){const e=[]
|
273 |
+
function o(i,s,o){return i||(i=w('<option value="'+N(s)+'">'+N(o)+"</option>")),i!=n&&t.input.append(i),e.push(i),i.selected=!0,i}t.input.querySelectorAll("option:checked").forEach((e=>{e.selected=!1})),0==t.items.length&&"single"==t.settings.mode?o(n,"",""):t.items.forEach((n=>{if(i=t.options[n],s=i[t.settings.labelField]||"",e.includes(i.$option)){o(t.input.querySelector(`option[value="${Q(n)}"]:not(:checked)`),n,s)}else i.$option=o(i.$option,n,s)}))}else t.input.value=t.getValue()
|
274 |
+
t.isSetup&&(e.silent||t.trigger("change",t.getValue()))}open(){var e=this
|
275 |
+
e.isLocked||e.isOpen||"multi"===e.settings.mode&&e.isFull()||(e.isOpen=!0,P(e.focus_node,{"aria-expanded":"true"}),e.refreshState(),I(e.dropdown,{visibility:"hidden",display:"block"}),e.positionDropdown(),I(e.dropdown,{visibility:"visible",display:"block"}),e.focus(),e.trigger("dropdown_open",e.dropdown))}close(e=!0){var t=this,i=t.isOpen
|
276 |
+
e&&(t.setTextboxValue(),"single"===t.settings.mode&&t.items.length&&t.hideInput()),t.isOpen=!1,P(t.focus_node,{"aria-expanded":"false"}),I(t.dropdown,{display:"none"}),t.settings.hideSelected&&t.clearActiveOption(),t.refreshState(),i&&t.trigger("dropdown_close",t.dropdown)}positionDropdown(){if("body"===this.settings.dropdownParent){var e=this.control,t=e.getBoundingClientRect(),i=e.offsetHeight+t.top+window.scrollY,s=t.left+window.scrollX
|
277 |
+
I(this.dropdown,{width:t.width+"px",top:i+"px",left:s+"px"})}}clear(e){var t=this
|
278 |
+
if(t.items.length){var i=t.controlChildren()
|
279 |
+
y(i,(e=>{t.removeItem(e,!0)})),t.showInput(),e||t.updateOriginalInput(),t.trigger("clear")}}insertAtCaret(e){const t=this,i=t.caretPos,s=t.control
|
280 |
+
s.insertBefore(e,s.children[i]),t.setCaret(i+1)}deleteSelection(e){var t,i,s,n,o,r=this
|
281 |
+
t=e&&8===e.keyCode?-1:1,i={start:(o=r.control_input).selectionStart||0,length:(o.selectionEnd||0)-(o.selectionStart||0)}
|
282 |
+
const l=[]
|
283 |
+
if(r.activeItems.length)n=F(r.activeItems,t),s=L(n),t>0&&s++,y(r.activeItems,(e=>l.push(e)))
|
284 |
+
else if((r.isFocused||"single"===r.settings.mode)&&r.items.length){const e=r.controlChildren()
|
285 |
+
t<0&&0===i.start&&0===i.length?l.push(e[r.caretPos-1]):t>0&&i.start===r.inputValue().length&&l.push(e[r.caretPos])}const a=l.map((e=>e.dataset.value))
|
286 |
+
if(!a.length||"function"==typeof r.settings.onDelete&&!1===r.settings.onDelete.call(r,a,e))return!1
|
287 |
+
for(H(e,!0),void 0!==s&&r.setCaret(s);l.length;)r.removeItem(l.pop())
|
288 |
+
return r.showInput(),r.positionDropdown(),r.refreshOptions(!1),!0}advanceSelection(e,t){var i,s,n=this
|
289 |
+
n.rtl&&(e*=-1),n.inputValue().length||(K(V,t)||K("shiftKey",t)?(s=(i=n.getLastActive(e))?i.classList.contains("active")?n.getAdjacent(i,e,"item"):i:e>0?n.control_input.nextElementSibling:n.control_input.previousElementSibling)&&(s.classList.contains("active")&&n.removeActiveItem(i),n.setActiveItemClass(s)):n.moveCaret(e))}moveCaret(e){}getLastActive(e){let t=this.control.querySelector(".last-active")
|
290 |
+
if(t)return t
|
291 |
+
var i=this.control.querySelectorAll(".active")
|
292 |
+
return i?F(i,e):void 0}setCaret(e){this.caretPos=this.items.length}controlChildren(){return Array.from(this.control.querySelectorAll("[data-ts-item]"))}lock(){this.close(),this.isLocked=!0,this.refreshState()}unlock(){this.isLocked=!1,this.refreshState()}disable(){var e=this
|
293 |
+
e.input.disabled=!0,e.control_input.disabled=!0,e.focus_node.tabIndex=-1,e.isDisabled=!0,e.lock()}enable(){var e=this
|
294 |
+
e.input.disabled=!1,e.control_input.disabled=!1,e.focus_node.tabIndex=e.tabIndex,e.isDisabled=!1,e.unlock()}destroy(){var e=this,t=e.revertSettings
|
295 |
+
e.trigger("destroy"),e.off(),e.wrapper.remove(),e.dropdown.remove(),e.input.innerHTML=t.innerHTML,e.input.tabIndex=t.tabIndex,S(e.input,"tomselected","ts-hidden-accessible"),e._destroy(),delete e.input.tomselect}render(e,t){return"function"!=typeof this.settings.render[e]?null:this._render(e,t)}_render(e,t){var i,s,n=""
|
296 |
+
const o=this
|
297 |
+
return"option"!==e&&"item"!=e||(n=D(t[o.settings.valueField])),null==(s=o.settings.render[e].call(this,t,N))||(s=w(s),"option"===e||"option_create"===e?t[o.settings.disabledField]?P(s,{"aria-disabled":"true"}):P(s,{"data-selectable":""}):"optgroup"===e&&(i=t.group[o.settings.optgroupValueField],P(s,{"data-group":i}),t.group[o.settings.disabledField]&&P(s,{"data-disabled":""})),"option"!==e&&"item"!==e||(P(s,{"data-value":n}),"item"===e?(C(s,o.settings.itemClass),P(s,{"data-ts-item":""})):(C(s,o.settings.optionClass),P(s,{role:"option",id:t.$id}),o.options[n].$div=s))),s}clearCache(){y(this.options,((e,t)=>{e.$div&&(e.$div.remove(),delete e.$div)}))}uncacheValue(e){const t=this.getOption(e)
|
298 |
+
t&&t.remove()}canCreate(e){return this.settings.create&&e.length>0&&this.settings.createFilter.call(this,e)}hook(e,t,i){var s=this,n=s[t]
|
299 |
+
s[t]=function(){var t,o
|
300 |
+
return"after"===e&&(t=n.apply(s,arguments)),o=i.apply(s,arguments),"instead"===e?o:("before"===e&&(t=n.apply(s,arguments)),t)}}}return J.define("change_listener",(function(){B(this.input,"change",(()=>{this.sync()}))})),J.define("checkbox_options",(function(){var e=this,t=e.onOptionSelect
|
301 |
+
e.settings.hideSelected=!1
|
302 |
+
var i=function(e){setTimeout((()=>{var t=e.querySelector("input")
|
303 |
+
e.classList.contains("selected")?t.checked=!0:t.checked=!1}),1)}
|
304 |
+
e.hook("after","setupTemplates",(()=>{var t=e.settings.render.option
|
305 |
+
e.settings.render.option=(i,s)=>{var n=w(t.call(e,i,s)),o=document.createElement("input")
|
306 |
+
o.addEventListener("click",(function(e){H(e)})),o.type="checkbox"
|
307 |
+
const r=q(i[e.settings.valueField])
|
308 |
+
return r&&e.items.indexOf(r)>-1&&(o.checked=!0),n.prepend(o),n}})),e.on("item_remove",(t=>{var s=e.getOption(t)
|
309 |
+
s&&(s.classList.remove("selected"),i(s))})),e.hook("instead","onOptionSelect",((s,n)=>{if(n.classList.contains("selected"))return n.classList.remove("selected"),e.removeItem(n.dataset.value),e.refreshOptions(),void H(s,!0)
|
310 |
+
t.call(e,s,n),i(n)}))})),J.define("clear_button",(function(e){const t=this,i=Object.assign({className:"clear-button",title:"Clear All",html:e=>`<div class="${e.className}" title="${e.title}">×</div>`},e)
|
311 |
+
t.on("initialize",(()=>{var e=w(i.html(i))
|
312 |
+
e.addEventListener("click",(e=>{t.clear(),"single"===t.settings.mode&&t.settings.allowEmptyOption&&t.addItem(""),e.preventDefault(),e.stopPropagation()})),t.control.appendChild(e)}))})),J.define("drag_drop",(function(){var e=this
|
313 |
+
if(!$.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".')
|
314 |
+
if("multi"===e.settings.mode){var t=e.lock,i=e.unlock
|
315 |
+
e.hook("instead","lock",(()=>{var i=$(e.control).data("sortable")
|
316 |
+
return i&&i.disable(),t.call(e)})),e.hook("instead","unlock",(()=>{var t=$(e.control).data("sortable")
|
317 |
+
return t&&t.enable(),i.call(e)})),e.on("initialize",(()=>{var t=$(e.control).sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:e.isLocked,start:(e,i)=>{i.placeholder.css("width",i.helper.css("width")),t.css({overflow:"visible"})},stop:()=>{t.css({overflow:"hidden"})
|
318 |
+
var i=[]
|
319 |
+
t.children("[data-value]").each((function(){this.dataset.value&&i.push(this.dataset.value)})),e.setValue(i)}})}))}})),J.define("dropdown_header",(function(e){const t=this,i=Object.assign({title:"Untitled",headerClass:"dropdown-header",titleRowClass:"dropdown-header-title",labelClass:"dropdown-header-label",closeClass:"dropdown-header-close",html:e=>'<div class="'+e.headerClass+'"><div class="'+e.titleRowClass+'"><span class="'+e.labelClass+'">'+e.title+'</span><a class="'+e.closeClass+'">×</a></div></div>'},e)
|
320 |
+
t.on("initialize",(()=>{var e=w(i.html(i)),s=e.querySelector("."+i.closeClass)
|
321 |
+
s&&s.addEventListener("click",(e=>{H(e,!0),t.close()})),t.dropdown.insertBefore(e,t.dropdown.firstChild)}))})),J.define("caret_position",(function(){var e=this
|
322 |
+
e.hook("instead","setCaret",(t=>{"single"!==e.settings.mode&&e.control.contains(e.control_input)?(t=Math.max(0,Math.min(e.items.length,t)))==e.caretPos||e.isPending||e.controlChildren().forEach(((i,s)=>{s<t?e.control_input.insertAdjacentElement("beforebegin",i):e.control.appendChild(i)})):t=e.items.length,e.caretPos=t})),e.hook("instead","moveCaret",(t=>{if(!e.isFocused)return
|
323 |
+
const i=e.getLastActive(t)
|
324 |
+
if(i){const s=L(i)
|
325 |
+
e.setCaret(t>0?s+1:s),e.setActiveItem()}else e.setCaret(e.caretPos+t)}))})),J.define("dropdown_input",(function(){var e=this
|
326 |
+
e.settings.shouldOpen=!0,e.hook("before","setup",(()=>{e.focus_node=e.control,C(e.control_input,"dropdown-input")
|
327 |
+
const t=w('<div class="dropdown-input-wrap">')
|
328 |
+
t.append(e.control_input),e.dropdown.insertBefore(t,e.dropdown.firstChild)})),e.on("initialize",(()=>{e.control_input.addEventListener("keydown",(t=>{switch(t.keyCode){case 27:return e.isOpen&&(H(t,!0),e.close()),void e.clearActiveItems()
|
329 |
+
case 9:e.focus_node.tabIndex=-1}return e.onKeyDown.call(e,t)})),e.on("blur",(()=>{e.focus_node.tabIndex=e.isDisabled?-1:e.tabIndex})),e.on("dropdown_open",(()=>{e.control_input.focus()}))
|
330 |
+
const t=e.onBlur
|
331 |
+
e.hook("instead","onBlur",(i=>{if(!i||i.relatedTarget!=e.control_input)return t.call(e)})),B(e.control_input,"blur",(()=>e.onBlur())),e.hook("before","close",(()=>{e.isOpen&&e.focus_node.focus()}))}))})),J.define("input_autogrow",(function(){var e=this
|
332 |
+
e.on("initialize",(()=>{var t=document.createElement("span"),i=e.control_input
|
333 |
+
t.style.cssText="position:absolute; top:-99999px; left:-99999px; width:auto; padding:0; white-space:pre; ",e.wrapper.appendChild(t)
|
334 |
+
for(const e of["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"])t.style[e]=i.style[e]
|
335 |
+
var s=()=>{e.items.length>0?(t.textContent=i.value,i.style.width=t.clientWidth+"px"):i.style.width=""}
|
336 |
+
s(),e.on("update item_add item_remove",s),B(i,"input",s),B(i,"keyup",s),B(i,"blur",s),B(i,"update",s)}))})),J.define("no_backspace_delete",(function(){var e=this,t=e.deleteSelection
|
337 |
+
this.hook("instead","deleteSelection",(i=>!!e.activeItems.length&&t.call(e,i)))})),J.define("no_active_items",(function(){this.hook("instead","setActiveItem",(()=>{})),this.hook("instead","selectAll",(()=>{}))})),J.define("optgroup_columns",(function(){var e=this,t=e.onKeyDown
|
338 |
+
e.hook("instead","onKeyDown",(i=>{var s,n,o,r
|
339 |
+
if(!e.isOpen||37!==i.keyCode&&39!==i.keyCode)return t.call(e,i)
|
340 |
+
r=k(e.activeOption,"[data-group]"),s=L(e.activeOption,"[data-selectable]"),r&&(r=37===i.keyCode?r.previousSibling:r.nextSibling)&&(n=(o=r.querySelectorAll("[data-selectable]"))[Math.min(o.length-1,s)])&&e.setActiveOption(n)}))})),J.define("remove_button",(function(e){const t=Object.assign({label:"×",title:"Remove",className:"remove",append:!0},e)
|
341 |
+
var i=this
|
342 |
+
if(t.append){var s='<a href="javascript:void(0)" class="'+t.className+'" tabindex="-1" title="'+N(t.title)+'">'+t.label+"</a>"
|
343 |
+
i.hook("after","setupTemplates",(()=>{var e=i.settings.render.item
|
344 |
+
i.settings.render.item=(t,n)=>{var o=w(e.call(i,t,n)),r=w(s)
|
345 |
+
return o.appendChild(r),B(r,"mousedown",(e=>{H(e,!0)})),B(r,"click",(e=>{if(H(e,!0),!i.isLocked){var t=o.dataset.value
|
346 |
+
i.removeItem(t),i.refreshOptions(!1)}})),o}}))}})),J.define("restore_on_backspace",(function(e){const t=this,i=Object.assign({text:e=>e[t.settings.labelField]},e)
|
347 |
+
t.on("item_remove",(function(e){if(""===t.control_input.value.trim()){var s=t.options[e]
|
348 |
+
s&&t.setTextboxValue(i.text.call(t,s))}}))})),J.define("virtual_scroll",(function(){const e=this,t=e.canLoad,i=e.clearActiveOption,s=e.loadCallback
|
349 |
+
var n,o={},r=!1
|
350 |
+
if(!e.settings.firstUrl)throw"virtual_scroll plugin requires a firstUrl() method"
|
351 |
+
function l(t){return!("number"==typeof e.settings.maxOptions&&n.children.length>=e.settings.maxOptions)&&!(!(t in o)||!o[t])}e.settings.sortField=[{field:"$order"},{field:"$score"}],e.setNextUrl=function(e,t){o[e]=t},e.getUrl=function(t){if(t in o){const e=o[t]
|
352 |
+
return o[t]=!1,e}return o={},e.settings.firstUrl(t)},e.hook("instead","clearActiveOption",(()=>{if(!r)return i.call(e)})),e.hook("instead","canLoad",(i=>i in o?l(i):t.call(e,i))),e.hook("instead","loadCallback",((t,i)=>{r||e.clearOptions(),s.call(e,t,i),r=!1})),e.hook("after","refreshOptions",(()=>{const t=e.lastValue
|
353 |
+
var i
|
354 |
+
l(t)?(i=e.render("loading_more",{query:t}))&&i.setAttribute("data-selectable",""):t in o&&!n.querySelector(".no-results")&&(i=e.render("no_more_results",{query:t})),i&&(C(i,e.settings.optionClass),n.append(i))})),e.on("initialize",(()=>{n=e.dropdown_content,e.settings.render=Object.assign({},{loading_more:function(){return'<div class="loading-more-results">Loading more results ... </div>'},no_more_results:function(){return'<div class="no-more-results">No more results</div>'}},e.settings.render),n.addEventListener("scroll",(function(){n.clientHeight/(n.scrollHeight-n.scrollTop)<.95||l(e.lastValue)&&(r||(r=!0,e.load.call(e,e.lastValue)))}))}))})),J}))
|
355 |
+
var tomSelect=function(e,t){return new TomSelect(e,t)}
|
356 |
+
//# sourceMappingURL=tom-select.complete.min.js.map
|
lib/tom-select/tom-select.css
ADDED
@@ -0,0 +1,334 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* tom-select.css (v2.0.0-rc.4)
|
3 |
+
* Copyright (c) contributors
|
4 |
+
*
|
5 |
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
6 |
+
* file except in compliance with the License. You may obtain a copy of the License at:
|
7 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
8 |
+
*
|
9 |
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
10 |
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
11 |
+
* ANY KIND, either express or implied. See the License for the specific language
|
12 |
+
* governing permissions and limitations under the License.
|
13 |
+
*
|
14 |
+
*/
|
15 |
+
.ts-wrapper.plugin-drag_drop.multi > .ts-control > div.ui-sortable-placeholder {
|
16 |
+
visibility: visible !important;
|
17 |
+
background: #f2f2f2 !important;
|
18 |
+
background: rgba(0, 0, 0, 0.06) !important;
|
19 |
+
border: 0 none !important;
|
20 |
+
box-shadow: inset 0 0 12px 4px #fff; }
|
21 |
+
|
22 |
+
.ts-wrapper.plugin-drag_drop .ui-sortable-placeholder::after {
|
23 |
+
content: '!';
|
24 |
+
visibility: hidden; }
|
25 |
+
|
26 |
+
.ts-wrapper.plugin-drag_drop .ui-sortable-helper {
|
27 |
+
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); }
|
28 |
+
|
29 |
+
.plugin-checkbox_options .option input {
|
30 |
+
margin-right: 0.5rem; }
|
31 |
+
|
32 |
+
.plugin-clear_button .ts-control {
|
33 |
+
padding-right: calc( 1em + (3 * 6px)) !important; }
|
34 |
+
|
35 |
+
.plugin-clear_button .clear-button {
|
36 |
+
opacity: 0;
|
37 |
+
position: absolute;
|
38 |
+
top: 8px;
|
39 |
+
right: calc(8px - 6px);
|
40 |
+
margin-right: 0 !important;
|
41 |
+
background: transparent !important;
|
42 |
+
transition: opacity 0.5s;
|
43 |
+
cursor: pointer; }
|
44 |
+
|
45 |
+
.plugin-clear_button.single .clear-button {
|
46 |
+
right: calc(8px - 6px + 2rem); }
|
47 |
+
|
48 |
+
.plugin-clear_button.focus.has-items .clear-button,
|
49 |
+
.plugin-clear_button:hover.has-items .clear-button {
|
50 |
+
opacity: 1; }
|
51 |
+
|
52 |
+
.ts-wrapper .dropdown-header {
|
53 |
+
position: relative;
|
54 |
+
padding: 10px 8px;
|
55 |
+
border-bottom: 1px solid #d0d0d0;
|
56 |
+
background: #f8f8f8;
|
57 |
+
border-radius: 3px 3px 0 0; }
|
58 |
+
|
59 |
+
.ts-wrapper .dropdown-header-close {
|
60 |
+
position: absolute;
|
61 |
+
right: 8px;
|
62 |
+
top: 50%;
|
63 |
+
color: #303030;
|
64 |
+
opacity: 0.4;
|
65 |
+
margin-top: -12px;
|
66 |
+
line-height: 20px;
|
67 |
+
font-size: 20px !important; }
|
68 |
+
|
69 |
+
.ts-wrapper .dropdown-header-close:hover {
|
70 |
+
color: black; }
|
71 |
+
|
72 |
+
.plugin-dropdown_input.focus.dropdown-active .ts-control {
|
73 |
+
box-shadow: none;
|
74 |
+
border: 1px solid #d0d0d0; }
|
75 |
+
|
76 |
+
.plugin-dropdown_input .dropdown-input {
|
77 |
+
border: 1px solid #d0d0d0;
|
78 |
+
border-width: 0 0 1px 0;
|
79 |
+
display: block;
|
80 |
+
padding: 8px 8px;
|
81 |
+
box-shadow: none;
|
82 |
+
width: 100%;
|
83 |
+
background: transparent; }
|
84 |
+
|
85 |
+
.ts-wrapper.plugin-input_autogrow.has-items .ts-control > input {
|
86 |
+
min-width: 0; }
|
87 |
+
|
88 |
+
.ts-wrapper.plugin-input_autogrow.has-items.focus .ts-control > input {
|
89 |
+
flex: none;
|
90 |
+
min-width: 4px; }
|
91 |
+
.ts-wrapper.plugin-input_autogrow.has-items.focus .ts-control > input::-webkit-input-placeholder {
|
92 |
+
color: transparent; }
|
93 |
+
.ts-wrapper.plugin-input_autogrow.has-items.focus .ts-control > input::-ms-input-placeholder {
|
94 |
+
color: transparent; }
|
95 |
+
.ts-wrapper.plugin-input_autogrow.has-items.focus .ts-control > input::placeholder {
|
96 |
+
color: transparent; }
|
97 |
+
|
98 |
+
.ts-dropdown.plugin-optgroup_columns .ts-dropdown-content {
|
99 |
+
display: flex; }
|
100 |
+
|
101 |
+
.ts-dropdown.plugin-optgroup_columns .optgroup {
|
102 |
+
border-right: 1px solid #f2f2f2;
|
103 |
+
border-top: 0 none;
|
104 |
+
flex-grow: 1;
|
105 |
+
flex-basis: 0;
|
106 |
+
min-width: 0; }
|
107 |
+
|
108 |
+
.ts-dropdown.plugin-optgroup_columns .optgroup:last-child {
|
109 |
+
border-right: 0 none; }
|
110 |
+
|
111 |
+
.ts-dropdown.plugin-optgroup_columns .optgroup:before {
|
112 |
+
display: none; }
|
113 |
+
|
114 |
+
.ts-dropdown.plugin-optgroup_columns .optgroup-header {
|
115 |
+
border-top: 0 none; }
|
116 |
+
|
117 |
+
.ts-wrapper.plugin-remove_button .item {
|
118 |
+
display: inline-flex;
|
119 |
+
align-items: center;
|
120 |
+
padding-right: 0 !important; }
|
121 |
+
|
122 |
+
.ts-wrapper.plugin-remove_button .item .remove {
|
123 |
+
color: inherit;
|
124 |
+
text-decoration: none;
|
125 |
+
vertical-align: middle;
|
126 |
+
display: inline-block;
|
127 |
+
padding: 2px 6px;
|
128 |
+
border-left: 1px solid #d0d0d0;
|
129 |
+
border-radius: 0 2px 2px 0;
|
130 |
+
box-sizing: border-box;
|
131 |
+
margin-left: 6px; }
|
132 |
+
|
133 |
+
.ts-wrapper.plugin-remove_button .item .remove:hover {
|
134 |
+
background: rgba(0, 0, 0, 0.05); }
|
135 |
+
|
136 |
+
.ts-wrapper.plugin-remove_button .item.active .remove {
|
137 |
+
border-left-color: #cacaca; }
|
138 |
+
|
139 |
+
.ts-wrapper.plugin-remove_button.disabled .item .remove:hover {
|
140 |
+
background: none; }
|
141 |
+
|
142 |
+
.ts-wrapper.plugin-remove_button.disabled .item .remove {
|
143 |
+
border-left-color: white; }
|
144 |
+
|
145 |
+
.ts-wrapper.plugin-remove_button .remove-single {
|
146 |
+
position: absolute;
|
147 |
+
right: 0;
|
148 |
+
top: 0;
|
149 |
+
font-size: 23px; }
|
150 |
+
|
151 |
+
.ts-wrapper {
|
152 |
+
position: relative; }
|
153 |
+
|
154 |
+
.ts-dropdown,
|
155 |
+
.ts-control,
|
156 |
+
.ts-control input {
|
157 |
+
color: #303030;
|
158 |
+
font-family: inherit;
|
159 |
+
font-size: 13px;
|
160 |
+
line-height: 18px;
|
161 |
+
font-smoothing: inherit; }
|
162 |
+
|
163 |
+
.ts-control,
|
164 |
+
.ts-wrapper.single.input-active .ts-control {
|
165 |
+
background: #fff;
|
166 |
+
cursor: text; }
|
167 |
+
|
168 |
+
.ts-control {
|
169 |
+
border: 1px solid #d0d0d0;
|
170 |
+
padding: 8px 8px;
|
171 |
+
width: 100%;
|
172 |
+
overflow: hidden;
|
173 |
+
position: relative;
|
174 |
+
z-index: 1;
|
175 |
+
box-sizing: border-box;
|
176 |
+
box-shadow: none;
|
177 |
+
border-radius: 3px;
|
178 |
+
display: flex;
|
179 |
+
flex-wrap: wrap; }
|
180 |
+
.ts-wrapper.multi.has-items .ts-control {
|
181 |
+
padding: calc( 8px - 2px - 0) 8px calc( 8px - 2px - 3px - 0); }
|
182 |
+
.full .ts-control {
|
183 |
+
background-color: #fff; }
|
184 |
+
.disabled .ts-control,
|
185 |
+
.disabled .ts-control * {
|
186 |
+
cursor: default !important; }
|
187 |
+
.focus .ts-control {
|
188 |
+
box-shadow: none; }
|
189 |
+
.ts-control > * {
|
190 |
+
vertical-align: baseline;
|
191 |
+
display: inline-block; }
|
192 |
+
.ts-wrapper.multi .ts-control > div {
|
193 |
+
cursor: pointer;
|
194 |
+
margin: 0 3px 3px 0;
|
195 |
+
padding: 2px 6px;
|
196 |
+
background: #f2f2f2;
|
197 |
+
color: #303030;
|
198 |
+
border: 0 solid #d0d0d0; }
|
199 |
+
.ts-wrapper.multi .ts-control > div.active {
|
200 |
+
background: #e8e8e8;
|
201 |
+
color: #303030;
|
202 |
+
border: 0 solid #cacaca; }
|
203 |
+
.ts-wrapper.multi.disabled .ts-control > div, .ts-wrapper.multi.disabled .ts-control > div.active {
|
204 |
+
color: #7d7c7c;
|
205 |
+
background: white;
|
206 |
+
border: 0 solid white; }
|
207 |
+
.ts-control > input {
|
208 |
+
flex: 1 1 auto;
|
209 |
+
min-width: 7rem;
|
210 |
+
display: inline-block !important;
|
211 |
+
padding: 0 !important;
|
212 |
+
min-height: 0 !important;
|
213 |
+
max-height: none !important;
|
214 |
+
max-width: 100% !important;
|
215 |
+
margin: 0 !important;
|
216 |
+
text-indent: 0 !important;
|
217 |
+
border: 0 none !important;
|
218 |
+
background: none !important;
|
219 |
+
line-height: inherit !important;
|
220 |
+
-webkit-user-select: auto !important;
|
221 |
+
-moz-user-select: auto !important;
|
222 |
+
-ms-user-select: auto !important;
|
223 |
+
user-select: auto !important;
|
224 |
+
box-shadow: none !important; }
|
225 |
+
.ts-control > input::-ms-clear {
|
226 |
+
display: none; }
|
227 |
+
.ts-control > input:focus {
|
228 |
+
outline: none !important; }
|
229 |
+
.has-items .ts-control > input {
|
230 |
+
margin: 0 4px !important; }
|
231 |
+
.ts-control.rtl {
|
232 |
+
text-align: right; }
|
233 |
+
.ts-control.rtl.single .ts-control:after {
|
234 |
+
left: 15px;
|
235 |
+
right: auto; }
|
236 |
+
.ts-control.rtl .ts-control > input {
|
237 |
+
margin: 0 4px 0 -2px !important; }
|
238 |
+
.disabled .ts-control {
|
239 |
+
opacity: 0.5;
|
240 |
+
background-color: #fafafa; }
|
241 |
+
.input-hidden .ts-control > input {
|
242 |
+
opacity: 0;
|
243 |
+
position: absolute;
|
244 |
+
left: -10000px; }
|
245 |
+
|
246 |
+
.ts-dropdown {
|
247 |
+
position: absolute;
|
248 |
+
top: 100%;
|
249 |
+
left: 0;
|
250 |
+
width: 100%;
|
251 |
+
z-index: 10;
|
252 |
+
border: 1px solid #d0d0d0;
|
253 |
+
background: #fff;
|
254 |
+
margin: 0.25rem 0 0 0;
|
255 |
+
border-top: 0 none;
|
256 |
+
box-sizing: border-box;
|
257 |
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
258 |
+
border-radius: 0 0 3px 3px; }
|
259 |
+
.ts-dropdown [data-selectable] {
|
260 |
+
cursor: pointer;
|
261 |
+
overflow: hidden; }
|
262 |
+
.ts-dropdown [data-selectable] .highlight {
|
263 |
+
background: rgba(125, 168, 208, 0.2);
|
264 |
+
border-radius: 1px; }
|
265 |
+
.ts-dropdown .option,
|
266 |
+
.ts-dropdown .optgroup-header,
|
267 |
+
.ts-dropdown .no-results,
|
268 |
+
.ts-dropdown .create {
|
269 |
+
padding: 5px 8px; }
|
270 |
+
.ts-dropdown .option, .ts-dropdown [data-disabled], .ts-dropdown [data-disabled] [data-selectable].option {
|
271 |
+
cursor: inherit;
|
272 |
+
opacity: 0.5; }
|
273 |
+
.ts-dropdown [data-selectable].option {
|
274 |
+
opacity: 1;
|
275 |
+
cursor: pointer; }
|
276 |
+
.ts-dropdown .optgroup:first-child .optgroup-header {
|
277 |
+
border-top: 0 none; }
|
278 |
+
.ts-dropdown .optgroup-header {
|
279 |
+
color: #303030;
|
280 |
+
background: #fff;
|
281 |
+
cursor: default; }
|
282 |
+
.ts-dropdown .create:hover,
|
283 |
+
.ts-dropdown .option:hover,
|
284 |
+
.ts-dropdown .active {
|
285 |
+
background-color: #f5fafd;
|
286 |
+
color: #495c68; }
|
287 |
+
.ts-dropdown .create:hover.create,
|
288 |
+
.ts-dropdown .option:hover.create,
|
289 |
+
.ts-dropdown .active.create {
|
290 |
+
color: #495c68; }
|
291 |
+
.ts-dropdown .create {
|
292 |
+
color: rgba(48, 48, 48, 0.5); }
|
293 |
+
.ts-dropdown .spinner {
|
294 |
+
display: inline-block;
|
295 |
+
width: 30px;
|
296 |
+
height: 30px;
|
297 |
+
margin: 5px 8px; }
|
298 |
+
.ts-dropdown .spinner:after {
|
299 |
+
content: " ";
|
300 |
+
display: block;
|
301 |
+
width: 24px;
|
302 |
+
height: 24px;
|
303 |
+
margin: 3px;
|
304 |
+
border-radius: 50%;
|
305 |
+
border: 5px solid #d0d0d0;
|
306 |
+
border-color: #d0d0d0 transparent #d0d0d0 transparent;
|
307 |
+
animation: lds-dual-ring 1.2s linear infinite; }
|
308 |
+
|
309 |
+
@keyframes lds-dual-ring {
|
310 |
+
0% {
|
311 |
+
transform: rotate(0deg); }
|
312 |
+
100% {
|
313 |
+
transform: rotate(360deg); } }
|
314 |
+
|
315 |
+
.ts-dropdown-content {
|
316 |
+
overflow-y: auto;
|
317 |
+
overflow-x: hidden;
|
318 |
+
max-height: 200px;
|
319 |
+
overflow-scrolling: touch;
|
320 |
+
scroll-behavior: smooth; }
|
321 |
+
|
322 |
+
.ts-hidden-accessible {
|
323 |
+
border: 0 !important;
|
324 |
+
clip: rect(0 0 0 0) !important;
|
325 |
+
-webkit-clip-path: inset(50%) !important;
|
326 |
+
clip-path: inset(50%) !important;
|
327 |
+
height: 1px !important;
|
328 |
+
overflow: hidden !important;
|
329 |
+
padding: 0 !important;
|
330 |
+
position: absolute !important;
|
331 |
+
width: 1px !important;
|
332 |
+
white-space: nowrap !important; }
|
333 |
+
|
334 |
+
/*# sourceMappingURL=tom-select.css.map */
|
lib/vis-9.1.2/vis-network.css
ADDED
The diff for this file is too large to render.
See raw diff
|
|
lib/vis-9.1.2/vis-network.min.js
ADDED
The diff for this file is too large to render.
See raw diff
|
|
requirements.txt
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
spacy
|
2 |
+
feedparser
|
3 |
+
beautifulsoup4
|
4 |
+
requests
|
5 |
+
gradio
|
6 |
+
networkx
|
7 |
+
matplotlib
|
8 |
+
pyvis
|
sources.py
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
RSS_FEEDS = {
|
2 |
+
"BBC": "http://feeds.bbci.co.uk/news/rss.xml",
|
3 |
+
"NYTimes - Home": "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml",
|
4 |
+
"Wired": "https://www.wired.com/feed/rss",
|
5 |
+
"CNBC": "https://www.cnbc.com/id/100003114/device/rss/rss.html",
|
6 |
+
"The Guardian": "https://www.theguardian.com/world/rss",
|
7 |
+
"WSJ": "https://feeds.a.dj.com/rss/RSSWorldNews.xml",
|
8 |
+
"AltPress (Music)": "https://www.altpress.com/feed/",
|
9 |
+
"Fortune": "https://fortune.com/feed/fortune-feeds/?id=3230629",
|
10 |
+
"NerdWallet": "https://www.nerdwallet.com/blog/feed/",
|
11 |
+
"Mashable": "http://feeds.mashable.com/Mashable",
|
12 |
+
"The Verge": "https://www.theverge.com/rss/index.xml",
|
13 |
+
"Atlas Obscura": "https://www.atlasobscura.com/feeds/latest",
|
14 |
+
"Mozilla Hacks": "https://hacks.mozilla.org/feed/",
|
15 |
+
"CNET News": "https://www.cnet.com/rss/news/",
|
16 |
+
"Inc.": "https://www.inc.com/rss/",
|
17 |
+
"NYTimes - Fashion": "https://rss.nytimes.com/services/xml/rss/nyt/FashionandStyle.xml",
|
18 |
+
"Bloomberg (YouTube)": "https://www.youtube.com/feeds/videos.xml?user=Bloomberg",
|
19 |
+
"Google Blog": "https://blog.google/rss/",
|
20 |
+
"Stack Overflow Blog": "https://stackoverflow.blog/feed/",
|
21 |
+
"Small Business Trends": "https://feeds2.feedburner.com/SmallBusinessTrends",
|
22 |
+
"The Guardian - Travel": "https://www.theguardian.com/uk/travel/rss",
|
23 |
+
"Smashing Magazine": "https://www.smashingmagazine.com/feed",
|
24 |
+
"NASA": "https://www.nasa.gov/news-release/feed/",
|
25 |
+
"Science-Based Medicine": "https://sciencebasedmedicine.org/feed/"
|
26 |
+
}
|
tutorials/tutorial0.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
tutorials/tutorial1.ipynb
ADDED
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "markdown",
|
5 |
+
"metadata": {},
|
6 |
+
"source": [
|
7 |
+
"Tutorial from https://www.datacamp.com/tutorial/knowledge-graph-rag"
|
8 |
+
]
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"cell_type": "code",
|
12 |
+
"execution_count": 1,
|
13 |
+
"metadata": {},
|
14 |
+
"outputs": [
|
15 |
+
{
|
16 |
+
"name": "stdout",
|
17 |
+
"output_type": "stream",
|
18 |
+
"text": [
|
19 |
+
"\n",
|
20 |
+
"Chunk 1:\n",
|
21 |
+
"Sarah is an employee at prismaticAI, a leading technology company based in Westside Valley. She has been working there for the past three years as a software engineer.\n",
|
22 |
+
"\n",
|
23 |
+
"Chunk 2:\n",
|
24 |
+
"Michael is also an employee at prismaticAI, where he works as a data scientist. He joined the company two years ago after completing his graduate studies.\n",
|
25 |
+
"\n",
|
26 |
+
"Chunk 3:\n",
|
27 |
+
"prismaticAI is a well-known technology company that specializes in developing cutting-edge software solutions and artificial intelligence applications. The company has a diverse workforce of talented\n",
|
28 |
+
"\n",
|
29 |
+
"Chunk 4:\n",
|
30 |
+
"of talented individuals from various backgrounds.\n",
|
31 |
+
"\n",
|
32 |
+
"Chunk 5:\n",
|
33 |
+
"Both Sarah and Michael are highly skilled professionals who contribute significantly to prismaticAI's success. They work closely with their respective teams to develop innovative products and\n",
|
34 |
+
"\n",
|
35 |
+
"Chunk 6:\n",
|
36 |
+
"products and services that meet the evolving needs of the company's clients.\n"
|
37 |
+
]
|
38 |
+
}
|
39 |
+
],
|
40 |
+
"source": [
|
41 |
+
"from langchain.schema import Document\n",
|
42 |
+
"from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
|
43 |
+
"\n",
|
44 |
+
"# Your raw text\n",
|
45 |
+
"text = \"\"\"Sarah is an employee at prismaticAI, a leading technology company based in Westside Valley. She has been working there for the past three years as a software engineer.\n",
|
46 |
+
"Michael is also an employee at prismaticAI, where he works as a data scientist. He joined the company two years ago after completing his graduate studies.\n",
|
47 |
+
"prismaticAI is a well-known technology company that specializes in developing cutting-edge software solutions and artificial intelligence applications. The company has a diverse workforce of talented individuals from various backgrounds.\n",
|
48 |
+
"Both Sarah and Michael are highly skilled professionals who contribute significantly to prismaticAI's success. They work closely with their respective teams to develop innovative products and services that meet the evolving needs of the company's clients.\"\"\"\n",
|
49 |
+
"\n",
|
50 |
+
"# Wrap in a Document object\n",
|
51 |
+
"documents = [Document(page_content=text)]\n",
|
52 |
+
"\n",
|
53 |
+
"# Split\n",
|
54 |
+
"text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20)\n",
|
55 |
+
"texts = text_splitter.split_documents(documents)\n",
|
56 |
+
"\n",
|
57 |
+
"# Show result\n",
|
58 |
+
"for i, t in enumerate(texts):\n",
|
59 |
+
" print(f\"\\nChunk {i+1}:\\n{t.page_content}\")\n"
|
60 |
+
]
|
61 |
+
},
|
62 |
+
{
|
63 |
+
"cell_type": "code",
|
64 |
+
"execution_count": 62,
|
65 |
+
"metadata": {},
|
66 |
+
"outputs": [
|
67 |
+
{
|
68 |
+
"name": "stderr",
|
69 |
+
"output_type": "stream",
|
70 |
+
"text": [
|
71 |
+
"/Users/leandratejedor/miniforge3/envs/agents-py11/lib/python3.11/site-packages/langchain_openai/chat_models/base.py:1660: UserWarning: Cannot use method='json_schema' with model gpt-3.5-turbo since it doesn't support OpenAI's Structured Output API. You can see supported models here: https://platform.openai.com/docs/guides/structured-outputs#supported-models. To fix this warning, set `method='function_calling'. Overriding to method='function_calling'.\n",
|
72 |
+
" warnings.warn(\n"
|
73 |
+
]
|
74 |
+
}
|
75 |
+
],
|
76 |
+
"source": [
|
77 |
+
"from langchain_openai import ChatOpenAI\n",
|
78 |
+
"from langchain_experimental.graph_transformers import LLMGraphTransformer\n",
|
79 |
+
"\n",
|
80 |
+
"import os\n",
|
81 |
+
"from dotenv import load_dotenv\n",
|
82 |
+
"load_dotenv()\n",
|
83 |
+
"\n",
|
84 |
+
"\n",
|
85 |
+
"# Initialize LLM\n",
|
86 |
+
"llm = ChatOpenAI(temperature=0)\n",
|
87 |
+
"\n",
|
88 |
+
"# Extract Knowledge Graph\n",
|
89 |
+
"llm_transformer = LLMGraphTransformer(llm=llm)\n",
|
90 |
+
"graph_documents = llm_transformer.convert_to_graph_documents(texts)"
|
91 |
+
]
|
92 |
+
},
|
93 |
+
{
|
94 |
+
"cell_type": "code",
|
95 |
+
"execution_count": 56,
|
96 |
+
"metadata": {},
|
97 |
+
"outputs": [
|
98 |
+
{
|
99 |
+
"name": "stdout",
|
100 |
+
"output_type": "stream",
|
101 |
+
"text": [
|
102 |
+
"LLM Response: content='Hello! Yes, I am functioning properly. How can I assist you today?' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 17, 'prompt_tokens': 14, 'total_tokens': 31, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': None, 'id': 'chatcmpl-BMkHf9pV37IhPnp53mgu9Aqa2yRmm', 'finish_reason': 'stop', 'logprobs': None} id='run-1b031a01-d933-457f-bfe7-2e05110e9dbf-0' usage_metadata={'input_tokens': 14, 'output_tokens': 17, 'total_tokens': 31, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}}\n",
|
103 |
+
"Test successful! Your LLM is running correctly.\n"
|
104 |
+
]
|
105 |
+
}
|
106 |
+
],
|
107 |
+
"source": [
|
108 |
+
"try:\n",
|
109 |
+
" response = llm.invoke(\"Hello, are you working properly?\")\n",
|
110 |
+
" print(\"LLM Response:\", response)\n",
|
111 |
+
" print(\"Test successful! Your LLM is running correctly.\")\n",
|
112 |
+
"except Exception as e:\n",
|
113 |
+
" print(\"Error connecting to LLM:\", e)\n",
|
114 |
+
" print(\"Check your API key and network connection.\")"
|
115 |
+
]
|
116 |
+
},
|
117 |
+
{
|
118 |
+
"cell_type": "code",
|
119 |
+
"execution_count": null,
|
120 |
+
"metadata": {},
|
121 |
+
"outputs": [],
|
122 |
+
"source": [
|
123 |
+
"from langchain_community.graphs import Neo4jGraph\n",
|
124 |
+
"\n",
|
125 |
+
"# Store Knowledge Graph in Neo4j\n",
|
126 |
+
"graph_store = Neo4jGraph(refresh_schema=False)\n",
|
127 |
+
"#graph_store.add_graph_documents(graph_documents)"
|
128 |
+
]
|
129 |
+
},
|
130 |
+
{
|
131 |
+
"cell_type": "code",
|
132 |
+
"execution_count": 44,
|
133 |
+
"metadata": {},
|
134 |
+
"outputs": [],
|
135 |
+
"source": [
|
136 |
+
"graph_store.refresh_schema()\n"
|
137 |
+
]
|
138 |
+
},
|
139 |
+
{
|
140 |
+
"cell_type": "code",
|
141 |
+
"execution_count": 81,
|
142 |
+
"metadata": {},
|
143 |
+
"outputs": [],
|
144 |
+
"source": [
|
145 |
+
"from langchain.chains import GraphCypherQAChain\n",
|
146 |
+
"from langchain.prompts import PromptTemplate\n",
|
147 |
+
"\n",
|
148 |
+
"\n",
|
149 |
+
"qa_template = \"\"\"\n",
|
150 |
+
"Based on the context: {context}\n",
|
151 |
+
"Answer the question: {question}\n",
|
152 |
+
"\"\"\"\n",
|
153 |
+
"qa_prompt = PromptTemplate(template=qa_template, input_variables=[\"context\", \"question\"])\n",
|
154 |
+
"\n",
|
155 |
+
"chain = GraphCypherQAChain.from_llm(\n",
|
156 |
+
" graph=graph_store,\n",
|
157 |
+
" cypher_llm=llm,\n",
|
158 |
+
" qa_llm=llm,\n",
|
159 |
+
" qa_prompt=qa_prompt,\n",
|
160 |
+
" #cypher_prompt=CYPHER_GENERATION_PROMPT,\n",
|
161 |
+
" verbose=True,\n",
|
162 |
+
" return_intermediate_steps=True,\n",
|
163 |
+
" allow_dangerous_requests=True\n",
|
164 |
+
")"
|
165 |
+
]
|
166 |
+
},
|
167 |
+
{
|
168 |
+
"cell_type": "code",
|
169 |
+
"execution_count": 86,
|
170 |
+
"metadata": {},
|
171 |
+
"outputs": [
|
172 |
+
{
|
173 |
+
"name": "stdout",
|
174 |
+
"output_type": "stream",
|
175 |
+
"text": [
|
176 |
+
"\n",
|
177 |
+
"\n",
|
178 |
+
"\u001b[1m> Entering new GraphCypherQAChain chain...\u001b[0m\n",
|
179 |
+
"Generated Cypher:\n",
|
180 |
+
"\u001b[32;1m\u001b[1;3mMATCH (p1:Person {id: \"Michael\"})-[:EMPLOYEE]->(o:Organization)<-[:EMPLOYEE]-(p2:Person {id: \"Sarah\"})\n",
|
181 |
+
"RETURN o\u001b[0m\n",
|
182 |
+
"Full Context:\n",
|
183 |
+
"\u001b[32;1m\u001b[1;3m[]\u001b[0m\n",
|
184 |
+
"\n",
|
185 |
+
"\u001b[1m> Finished chain.\u001b[0m\n",
|
186 |
+
"It is not possible to determine if Michael works for the same company as Sarah without more information.\n"
|
187 |
+
]
|
188 |
+
}
|
189 |
+
],
|
190 |
+
"source": [
|
191 |
+
"response = chain.invoke({\"query\": \"Does Michael work for the same company as Sarah?\"})\n",
|
192 |
+
"print(response['result'])\n"
|
193 |
+
]
|
194 |
+
},
|
195 |
+
{
|
196 |
+
"cell_type": "code",
|
197 |
+
"execution_count": null,
|
198 |
+
"metadata": {},
|
199 |
+
"outputs": [],
|
200 |
+
"source": []
|
201 |
+
}
|
202 |
+
],
|
203 |
+
"metadata": {
|
204 |
+
"kernelspec": {
|
205 |
+
"display_name": "agents-py11",
|
206 |
+
"language": "python",
|
207 |
+
"name": "python3"
|
208 |
+
},
|
209 |
+
"language_info": {
|
210 |
+
"codemirror_mode": {
|
211 |
+
"name": "ipython",
|
212 |
+
"version": 3
|
213 |
+
},
|
214 |
+
"file_extension": ".py",
|
215 |
+
"mimetype": "text/x-python",
|
216 |
+
"name": "python",
|
217 |
+
"nbconvert_exporter": "python",
|
218 |
+
"pygments_lexer": "ipython3",
|
219 |
+
"version": "3.11.12"
|
220 |
+
}
|
221 |
+
},
|
222 |
+
"nbformat": 4,
|
223 |
+
"nbformat_minor": 2
|
224 |
+
}
|
tutorials/wiki_sentences_v2.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|