PageSourceSearch

https://charluv.com/assets/index-CNCs0cMx.js

js charluv.com collected 2026-10-02 01:25:39 UTC 11,656 bytes, 317 lines download raw bytes

1import { u as useNavigate, m as matchStore, a as useLocalStorage, o as onMount, i as insert, c as createComponent, A, S as Sparkle, b as userStore, d as Show, e as createRenderEffect, s as setAttribute, F as For, t as template, f as createSignal, g as getAssetUrl, h as memo, j as delegateEvents } from "./index-BhA_zdKR.js";
2import { B as Book } from "./discover-Dn5xHN45.js";
3var _tmpl$ = /* @__PURE__ */ template(`<p class=dsc-legend><span class=dsc-legend-chip aria-hidden=true></span><span><strong>Scenario progression</strong> — this companion's relationship grows through stages as you chat.`), _tmpl$2 = /* @__PURE__ */ template(`<div class=dsc-root><header class=dsc-head><div class=dsc-intro><h1 class=dsc-title>Find your <em>someone</em></h1><p class=dsc-tag>Companions who grow with you. Start a conversation — your relationship deepens the more you talk.</p></div></header><div class=dsc-filters role=search><div class=dsc-group role=group aria-label=Gender></div><span class=dsc-label>Style</span><div class=dsc-group role=group aria-label="Art style"></div><button class=dsc-chip>SFW only</button><span class=dsc-spacer></span><input class=dsc-search type=search placeholder="Search by name or tag…"aria-label="Search companions"><div class=dsc-group role=group aria-label=Sort></div></div><div class=dsc-grid>`), _tmpl$3 = /* @__PURE__ */ template(`<button class=dsc-chip>`), _tmpl$4 = /* @__PURE__ */ template(`<div class=dsc-skel>`), _tmpl$5 = /* @__PURE__ */ template(`<div class=dsc-empty><p>No companions match those filters yet. Try widening them — or make your own.`), _tmpl$6 = /* @__PURE__ */ template(`<span class="dsc-badge dsc-badge-progress"title="Scenario progression"aria-label="Scenario progression">`), _tmpl$7 = /* @__PURE__ */ template(`<span class=dsc-badge data-nsfw=true>18+`), _tmpl$8 = /* @__PURE__ */ template(`<img class=dsc-photo loading=lazy>`, true, false, false), _tmpl$9 = /* @__PURE__ */ template(`<span>· `), _tmpl$0 = /* @__PURE__ */ template(`<span class="dsc-pill dsc-pill-lora">LoRA`), _tmpl$1 = /* @__PURE__ */ template(`<div class=dsc-tags>`), _tmpl$10 = /* @__PURE__ */ template(`<div class=dsc-engage><span>♥ </span><span>💬 `), _tmpl$11 = /* @__PURE__ */ template(`<article class=dsc-card tabindex=0><div class=dsc-scrim></div><div class=dsc-meta><div class=dsc-name> </div></div><button class=dsc-cta>Start chatting`), _tmpl$12 = /* @__PURE__ */ template(`<div class=dsc-ph>`), _tmpl$13 = /* @__PURE__ */ template(`<span class=dsc-pill>`);
4const GENDERS = [{
5  value: "",
6  label: "Everyone"
7}, {
8  value: "female",
9  label: "Women"
10}, {
11  value: "male",
12  label: "Men"
13}, {
14  value: "trans",
15  label: "Trans"
16}];
17const STYLES = [{
18  value: "",
19  label: "Any style"
20}, {
21  value: "realistic",
22  label: "Realistic"
23}, {
24  value: "anime",
25  label: "Anime"
26}];
27const SORTS = [{
28  value: "trending",
29  label: "Trending"
30}, {
31  value: "popular",
32  label: "Popular"
33}, {
34  value: "new",
35  label: "New"
36}];
37const Discover = () => {
38  const navigate = useNavigate();
39  const state = matchStore();
40  const [gender, setGender] = useLocalStorage("discover-gender", "");
41  const [style, setStyle] = useLocalStorage("discover-style", "");
42  const [sort, setSort] = useLocalStorage("discover-sort", "trending");
43  const [sfw, setSfw] = useLocalStorage("discover-sfw", true);
44  const [search, setSearch] = useLocalStorage("discover-search", "");
45  const load = () => matchStore.loadDiscover({
46    gender: gender() || void 0,
47    artStyle: style() || void 0,
48    sort: sort(),
49    nsfw: sfw() ? false : void 0,
50    search: search() || void 0
51  });
52  onMount(load);
53  let debounce;
54  const onSearch = (v) => {
55    setSearch(v);
56    clearTimeout(debounce);
57    debounce = setTimeout(load, 300);
58  };
59  const pick = (char) => navigate(`/discover/${char._id}`);
60  return (() => {
61    var _el$ = _tmpl$2(), _el$2 = _el$.firstChild;
62    _el$2.firstChild;
63    var _el$4 = _el$2.nextSibling, _el$5 = _el$4.firstChild, _el$6 = _el$5.nextSibling, _el$7 = _el$6.nextSibling, _el$8 = _el$7.nextSibling, _el$9 = _el$8.firstChild, _el$0 = _el$8.nextSibling, _el$1 = _el$0.nextSibling, _el$10 = _el$1.nextSibling, _el$13 = _el$4.nextSibling;
64    insert(_el$2, createComponent(Show, {
65      get when() {
66        return userStore().loggedIn;
67      },
68      get children() {
69        return createComponent(A, {
70          "class": "dsc-create",
71          href: "/create",
72          get children() {
73            return [createComponent(Sparkle, {
74              size: 17,
75              color: "currentColor"
76            }), " Create your dream date"];
77          }
78        });
79      }
80    }), null);
81    insert(_el$5, createComponent(For, {
82      each: GENDERS,
83      children: (g) => (() => {
84        var _el$14 = _tmpl$3();
85        _el$14.$$click = () => {
86          setGender(g.value);
87          load();
88        };
89        insert(_el$14, () => g.label);
90        createRenderEffect(() => setAttribute(_el$14, "data-on", gender() === g.value));
91        return _el$14;
92      })()
93    }));
94    insert(_el$7, createComponent(For, {
95      each: STYLES,
96      children: (s) => (() => {
97        var _el$15 = _tmpl$3();
98        _el$15.$$click = () => {
99          setStyle(s.value);
100          load();
101        };
102        insert(_el$15, () => s.label);
103        createRenderEffect(() => setAttribute(_el$15, "data-on", style() === s.value));
104        return _el$15;
105      })()
106    }));
107    _el$8.$$click = () => {
108      setSfw(!sfw());
109      load();
110    };
111    insert(_el$8, () => sfw() ? "✓ " : "", _el$9);
112    _el$1.$$input = (e) => onSearch(e.currentTarget.value);
113    insert(_el$10, createComponent(For, {
114      each: SORTS,
115      children: (s) => (() => {
116        var _el$16 = _tmpl$3();
117        _el$16.$$click = () => {
118          setSort(s.value);
119          load();
120        };
121        insert(_el$16, () => s.label);
122        createRenderEffect(() => setAttribute(_el$16, "data-on", sort() === s.value));
123        return _el$16;
124      })()
125    }));
126    insert(_el$, createComponent(Show, {
127      get when() {
128        return state.discover.list.some((c) => c.progression?.archetype);
129      },
130      get children() {
131        var _el$11 = _tmpl$(), _el$12 = _el$11.firstChild;
132        insert(_el$12, createComponent(Book, {
133          size: 13
134        }));
135        return _el$11;
136      }
137    }), _el$13);
138    insert(_el$13, createComponent(Show, {
139      get when() {
140        return !state.discover.loading;
141      },
142      get fallback() {
143        return createComponent(For, {
144          get each() {
145            return Array.from({
146              length: 8
147            });
148          },
149          children: () => _tmpl$4()
150        });
151      },
152      get children() {
153        return createComponent(Show, {
154          get when() {
155            return state.discover.list.length;
156          },
157          get fallback() {
158            return (() => {
159              var _el$18 = _tmpl$5();
160              _el$18.firstChild;
161              insert(_el$18, createComponent(A, {
162                "class": "dsc-create",
163                href: "/create",
164                get children() {
165                  return [createComponent(Sparkle, {
166                    size: 17,
167                    color: "currentColor"
168                  }), " Create your dream date"];
169                }
170              }), null);
171              return _el$18;
172            })();
173          },
174          get children() {
175            return createComponent(For, {
176              get each() {
177                return state.discover.list;
178              },
179              children: (char) => createComponent(Card, {
180                char,
181                onPick: pick
182              })
183            });
184          }
185        });
186      }
187    }));
188    createRenderEffect((_p$) => {
189      var _v$ = sfw(), _v$2 = sfw();
190      _v$ !== _p$.e && setAttribute(_el$8, "data-on", _p$.e = _v$);
191      _v$2 !== _p$.t && setAttribute(_el$8, "aria-pressed", _p$.t = _v$2);
192      return _p$;
193    }, {
194      e: void 0,
195      t: void 0
196    });
197    createRenderEffect(() => _el$1.value = search());
198    return _el$;
199  })();
200};
201const Card = (props) => {
202  const [broken, setBroken] = createSignal(false);
203  const hasProgression = () => !!props.char.progression?.archetype;
204  const tags = () => props.char.category?.slice(0, 3) || [];
205  const eng = () => props.char.engagement;
206  const initial = () => props.char.name?.[0]?.toUpperCase() || "?";
207  return (() => {
208    var _el$20 = _tmpl$11(), _el$24 = _el$20.firstChild, _el$25 = _el$24.nextSibling, _el$26 = _el$25.firstChild, _el$27 = _el$26.firstChild, _el$37 = _el$25.nextSibling;
209    _el$20.$$keydown = (e) => e.key === "Enter" && props.onPick(props.char);
210    _el$20.$$click = () => props.onPick(props.char);
211    insert(_el$20, createComponent(Show, {
212      get when() {
213        return hasProgression();
214      },
215      get children() {
216        var _el$21 = _tmpl$6();
217        insert(_el$21, createComponent(Book, {
218          size: 15
219        }));
220        return _el$21;
221      }
222    }), _el$24);
223    insert(_el$20, createComponent(Show, {
224      get when() {
225        return props.char.nsfw;
226      },
227      get children() {
228        return _tmpl$7();
229      }
230    }), _el$24);
231    insert(_el$20, createComponent(Show, {
232      get when() {
233        return memo(() => !!props.char.avatar)() && !broken();
234      },
235      get fallback() {
236        return (() => {
237          var _el$38 = _tmpl$12();
238          insert(_el$38, initial);
239          return _el$38;
240        })();
241      },
242      get children() {
243        var _el$23 = _tmpl$8();
244        _el$23.addEventListener("error", () => setBroken(true));
245        createRenderEffect((_p$) => {
246          var _v$3 = getAssetUrl(props.char.avatar), _v$4 = props.char.name;
247          _v$3 !== _p$.e && setAttribute(_el$23, "src", _p$.e = _v$3);
248          _v$4 !== _p$.t && setAttribute(_el$23, "alt", _p$.t = _v$4);
249          return _p$;
250        }, {
251          e: void 0,
252          t: void 0
253        });
254        return _el$23;
255      }
256    }), _el$24);
257    insert(_el$26, () => props.char.name, _el$27);
258    insert(_el$26, createComponent(Show, {
259      get when() {
260        return props.char.ageRange;
261      },
262      get children() {
263        var _el$28 = _tmpl$9();
264        _el$28.firstChild;
265        insert(_el$28, () => props.char.ageRange, null);
266        return _el$28;
267      }
268    }), null);
269    insert(_el$25, createComponent(Show, {
270      get when() {
271        return tags().length || props.char.loraName;
272      },
273      get children() {
274        var _el$30 = _tmpl$1();
275        insert(_el$30, createComponent(For, {
276          get each() {
277            return tags();
278          },
279          children: (c) => (() => {
280            var _el$39 = _tmpl$13();
281            insert(_el$39, c);
282            return _el$39;
283          })()
284        }), null);
285        insert(_el$30, createComponent(Show, {
286          get when() {
287            return props.char.loraName;
288          },
289          get children() {
290            return _tmpl$0();
291          }
292        }), null);
293        return _el$30;
294      }
295    }), null);
296    insert(_el$25, createComponent(Show, {
297      get when() {
298        return eng();
299      },
300      get children() {
301        var _el$32 = _tmpl$10(), _el$33 = _el$32.firstChild;
302        _el$33.firstChild;
303        var _el$35 = _el$33.nextSibling;
304        _el$35.firstChild;
305        insert(_el$33, () => eng().favorites ?? 0, null);
306        insert(_el$35, () => eng().chats ?? 0, null);
307        return _el$32;
308      }
309    }), null);
310    _el$37.$$click = (e) => (e.stopPropagation(), props.onPick(props.char));
311    return _el$20;
312  })();
313};
314delegateEvents(["click", "input", "keydown"]);
315export {
316  Discover as default
317};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.