mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-06-09 20:39:25 -03:00
fix(license): remove cascading commercial-use bit encoding, clarify Allow Selling label (#941)
- _resolve_commercial_bits() no longer has Sell-implies-Image cascading; each CommercialUse value sets only its own bit, matching CivitAI's modern array-format API. - Keep filter tag label as 'Allow Selling' for brevity; add title/tooltip 'Allow selling generated images' on hover. - Same tooltip treatment for 'No Credit Required'. - Add i18n keys for both tooltips across all 10 locales.
This commit is contained in:
@@ -232,6 +232,8 @@
|
|||||||
"license": "Lizenz",
|
"license": "Lizenz",
|
||||||
"noCreditRequired": "Kein Credit erforderlich",
|
"noCreditRequired": "Kein Credit erforderlich",
|
||||||
"allowSellingGeneratedContent": "Verkauf erlaubt",
|
"allowSellingGeneratedContent": "Verkauf erlaubt",
|
||||||
|
"allowSellingGeneratedContentTooltip": "Verkauf generierter Bilder erlauben",
|
||||||
|
"noCreditRequiredTooltip": "Modell ohne Nennung des Erstellers verwenden",
|
||||||
"noTags": "Keine Tags",
|
"noTags": "Keine Tags",
|
||||||
"autoTags": "Auto-Tags",
|
"autoTags": "Auto-Tags",
|
||||||
"noBaseModelMatches": "Keine Basismodelle entsprechen der aktuellen Suche.",
|
"noBaseModelMatches": "Keine Basismodelle entsprechen der aktuellen Suche.",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"license": "License",
|
"license": "License",
|
||||||
"noCreditRequired": "No Credit Required",
|
"noCreditRequired": "No Credit Required",
|
||||||
"allowSellingGeneratedContent": "Allow Selling",
|
"allowSellingGeneratedContent": "Allow Selling",
|
||||||
|
"allowSellingGeneratedContentTooltip": "Allow selling generated images",
|
||||||
|
"noCreditRequiredTooltip": "Use the model without crediting the creator",
|
||||||
"noTags": "No tags",
|
"noTags": "No tags",
|
||||||
"autoTags": "Auto Tags",
|
"autoTags": "Auto Tags",
|
||||||
"noBaseModelMatches": "No base models match the current search.",
|
"noBaseModelMatches": "No base models match the current search.",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"license": "Licencia",
|
"license": "Licencia",
|
||||||
"noCreditRequired": "Sin crédito requerido",
|
"noCreditRequired": "Sin crédito requerido",
|
||||||
"allowSellingGeneratedContent": "Venta permitida",
|
"allowSellingGeneratedContent": "Venta permitida",
|
||||||
|
"allowSellingGeneratedContentTooltip": "Permitir la venta de imágenes generadas",
|
||||||
|
"noCreditRequiredTooltip": "Usar el modelo sin atribuir al creador",
|
||||||
"noTags": "Sin etiquetas",
|
"noTags": "Sin etiquetas",
|
||||||
"autoTags": "Etiquetas automáticas",
|
"autoTags": "Etiquetas automáticas",
|
||||||
"noBaseModelMatches": "Ningún modelo base coincide con la búsqueda actual.",
|
"noBaseModelMatches": "Ningún modelo base coincide con la búsqueda actual.",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"license": "Licence",
|
"license": "Licence",
|
||||||
"noCreditRequired": "Crédit non requis",
|
"noCreditRequired": "Crédit non requis",
|
||||||
"allowSellingGeneratedContent": "Vente autorisée",
|
"allowSellingGeneratedContent": "Vente autorisée",
|
||||||
|
"allowSellingGeneratedContentTooltip": "Autoriser la vente d\"images générées",
|
||||||
|
"noCreditRequiredTooltip": "Utiliser le modèle sans créditer le créateur",
|
||||||
"noTags": "Aucun tag",
|
"noTags": "Aucun tag",
|
||||||
"autoTags": "Auto-Tags",
|
"autoTags": "Auto-Tags",
|
||||||
"noBaseModelMatches": "Aucun modèle de base ne correspond à la recherche actuelle.",
|
"noBaseModelMatches": "Aucun modèle de base ne correspond à la recherche actuelle.",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"license": "רישיון",
|
"license": "רישיון",
|
||||||
"noCreditRequired": "ללא קרדיט נדרש",
|
"noCreditRequired": "ללא קרדיט נדרש",
|
||||||
"allowSellingGeneratedContent": "אפשר מכירה",
|
"allowSellingGeneratedContent": "אפשר מכירה",
|
||||||
|
"allowSellingGeneratedContentTooltip": "אפשר מכירת תמונות שנוצרו",
|
||||||
|
"noCreditRequiredTooltip": "שימוש במודל ללא מתן קרדיט ליוצר",
|
||||||
"noTags": "ללא תגיות",
|
"noTags": "ללא תגיות",
|
||||||
"autoTags": "תגיות אוטומטיות",
|
"autoTags": "תגיות אוטומטיות",
|
||||||
"noBaseModelMatches": "אין מודלי בסיס התואמים לחיפוש הנוכחי.",
|
"noBaseModelMatches": "אין מודלי בסיס התואמים לחיפוש הנוכחי.",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"license": "ライセンス",
|
"license": "ライセンス",
|
||||||
"noCreditRequired": "クレジット不要",
|
"noCreditRequired": "クレジット不要",
|
||||||
"allowSellingGeneratedContent": "販売許可",
|
"allowSellingGeneratedContent": "販売許可",
|
||||||
|
"allowSellingGeneratedContentTooltip": "生成した画像の販売を許可",
|
||||||
|
"noCreditRequiredTooltip": "クレジット表記なしでモデルを使用可能",
|
||||||
"noTags": "タグなし",
|
"noTags": "タグなし",
|
||||||
"autoTags": "自動タグ",
|
"autoTags": "自動タグ",
|
||||||
"noBaseModelMatches": "現在の検索に一致するベースモデルはありません。",
|
"noBaseModelMatches": "現在の検索に一致するベースモデルはありません。",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"license": "라이선스",
|
"license": "라이선스",
|
||||||
"noCreditRequired": "크레딧 표기 없음",
|
"noCreditRequired": "크레딧 표기 없음",
|
||||||
"allowSellingGeneratedContent": "판매 허용",
|
"allowSellingGeneratedContent": "판매 허용",
|
||||||
|
"allowSellingGeneratedContentTooltip": "생성된 이미지 판매 허용",
|
||||||
|
"noCreditRequiredTooltip": "크리에이터 저작자 표시 없이 모델 사용 가능",
|
||||||
"noTags": "태그 없음",
|
"noTags": "태그 없음",
|
||||||
"autoTags": "자동 태그",
|
"autoTags": "자동 태그",
|
||||||
"noBaseModelMatches": "현재 검색과 일치하는 베이스 모델이 없습니다.",
|
"noBaseModelMatches": "현재 검색과 일치하는 베이스 모델이 없습니다.",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"license": "Лицензия",
|
"license": "Лицензия",
|
||||||
"noCreditRequired": "Без указания авторства",
|
"noCreditRequired": "Без указания авторства",
|
||||||
"allowSellingGeneratedContent": "Продажа разрешена",
|
"allowSellingGeneratedContent": "Продажа разрешена",
|
||||||
|
"allowSellingGeneratedContentTooltip": "Разрешить продажу сгенерированных изображений",
|
||||||
|
"noCreditRequiredTooltip": "Использование модели без указания автора",
|
||||||
"noTags": "Без тегов",
|
"noTags": "Без тегов",
|
||||||
"autoTags": "Авто-теги",
|
"autoTags": "Авто-теги",
|
||||||
"noBaseModelMatches": "Нет базовых моделей, соответствующих текущему поиску.",
|
"noBaseModelMatches": "Нет базовых моделей, соответствующих текущему поиску.",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"license": "许可证",
|
"license": "许可证",
|
||||||
"noCreditRequired": "无需署名",
|
"noCreditRequired": "无需署名",
|
||||||
"allowSellingGeneratedContent": "允许销售",
|
"allowSellingGeneratedContent": "允许销售",
|
||||||
|
"allowSellingGeneratedContentTooltip": "允许出售生成的图片",
|
||||||
|
"noCreditRequiredTooltip": "使用模型时无需注明原作者",
|
||||||
"noTags": "无标签",
|
"noTags": "无标签",
|
||||||
"autoTags": "自动标签",
|
"autoTags": "自动标签",
|
||||||
"noBaseModelMatches": "没有基础模型符合当前搜索。",
|
"noBaseModelMatches": "没有基础模型符合当前搜索。",
|
||||||
|
|||||||
@@ -232,6 +232,8 @@
|
|||||||
"license": "授權",
|
"license": "授權",
|
||||||
"noCreditRequired": "無需署名",
|
"noCreditRequired": "無需署名",
|
||||||
"allowSellingGeneratedContent": "允許銷售",
|
"allowSellingGeneratedContent": "允許銷售",
|
||||||
|
"allowSellingGeneratedContentTooltip": "允許出售生成的圖片",
|
||||||
|
"noCreditRequiredTooltip": "使用模型時無需註明原作者",
|
||||||
"noTags": "無標籤",
|
"noTags": "無標籤",
|
||||||
"autoTags": "自動標籤",
|
"autoTags": "自動標籤",
|
||||||
"noBaseModelMatches": "沒有基礎模型符合目前的搜尋。",
|
"noBaseModelMatches": "沒有基礎模型符合目前的搜尋。",
|
||||||
|
|||||||
@@ -239,9 +239,9 @@ def _resolve_commercial_bits(values: Sequence[str]) -> int:
|
|||||||
normalized_values.add(normalized)
|
normalized_values.add(normalized)
|
||||||
|
|
||||||
has_sell = "sell" in normalized_values
|
has_sell = "sell" in normalized_values
|
||||||
has_rent = has_sell or "rent" in normalized_values
|
has_rent = "rent" in normalized_values
|
||||||
has_rentcivit = has_rent or "rentcivit" in normalized_values
|
has_rentcivit = "rentcivit" in normalized_values
|
||||||
has_image = has_sell or "image" in normalized_values
|
has_image = "image" in normalized_values
|
||||||
|
|
||||||
commercial_bits = (
|
commercial_bits = (
|
||||||
(1 if has_sell else 0) << 3
|
(1 if has_sell else 0) << 3
|
||||||
|
|||||||
@@ -218,10 +218,10 @@
|
|||||||
<div class="filter-section">
|
<div class="filter-section">
|
||||||
<h4>{{ t('header.filter.license') }}</h4>
|
<h4>{{ t('header.filter.license') }}</h4>
|
||||||
<div class="filter-tags">
|
<div class="filter-tags">
|
||||||
<div class="filter-tag license-tag" data-license="noCredit">
|
<div class="filter-tag license-tag" data-license="noCredit" title="{{ t('header.filter.noCreditRequiredTooltip') }}">
|
||||||
{{ t('header.filter.noCreditRequired') }}
|
{{ t('header.filter.noCreditRequired') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-tag license-tag" data-license="allowSelling">
|
<div class="filter-tag license-tag" data-license="allowSelling" title="{{ t('header.filter.allowSellingGeneratedContentTooltip') }}">
|
||||||
{{ t('header.filter.allowSellingGeneratedContent') }}
|
{{ t('header.filter.allowSellingGeneratedContent') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -65,32 +65,26 @@ async def test_allow_selling_filter():
|
|||||||
"""Test the allow selling generated content filtering logic."""
|
"""Test the allow selling generated content filtering logic."""
|
||||||
service = DummyModelService()
|
service = DummyModelService()
|
||||||
|
|
||||||
# Create test data with different license flags
|
# CommercialUse values are independent — Sell does NOT imply Image.
|
||||||
test_data = [
|
test_data = [
|
||||||
# Model allowing selling (contains Image in allowCommercialUse)
|
|
||||||
{"file_path": "model1.safetensors", "license_flags": build_license_flags({"allowCommercialUse": ["Image"]})},
|
{"file_path": "model1.safetensors", "license_flags": build_license_flags({"allowCommercialUse": ["Image"]})},
|
||||||
# Model not allowing selling (doesn't contain Image in allowCommercialUse)
|
|
||||||
{"file_path": "model2.safetensors", "license_flags": build_license_flags({"allowCommercialUse": ["RentCivit"]})},
|
{"file_path": "model2.safetensors", "license_flags": build_license_flags({"allowCommercialUse": ["RentCivit"]})},
|
||||||
# Model with default license flags (includes Sell by default, which implies Image)
|
|
||||||
{"file_path": "model3.safetensors", "license_flags": build_license_flags(None)},
|
{"file_path": "model3.safetensors", "license_flags": build_license_flags(None)},
|
||||||
# Model allowing selling (contains Sell in allowCommercialUse, which implies Image)
|
|
||||||
{"file_path": "model4.safetensors", "license_flags": build_license_flags({"allowCommercialUse": ["Sell"]})},
|
{"file_path": "model4.safetensors", "license_flags": build_license_flags({"allowCommercialUse": ["Sell"]})},
|
||||||
# Model with empty allowCommercialUse (doesn't allow selling)
|
|
||||||
{"file_path": "model5.safetensors", "license_flags": build_license_flags({"allowCommercialUse": []})},
|
{"file_path": "model5.safetensors", "license_flags": build_license_flags({"allowCommercialUse": []})},
|
||||||
]
|
]
|
||||||
|
|
||||||
# Test allow_selling=True (should return models that allow selling - have Image permission)
|
# Test allow_selling=True (should return only models with the Image permission)
|
||||||
# Default and Sell permissions both include Image, so model3 and model4 will be included
|
|
||||||
filtered = await service._apply_allow_selling_filter(test_data, allow_selling=True)
|
filtered = await service._apply_allow_selling_filter(test_data, allow_selling=True)
|
||||||
assert len(filtered) == 3 # model1, model3 (default includes Sell which implies Image), model4
|
assert len(filtered) == 1 # only model1 has Image permission
|
||||||
file_paths = {item["file_path"] for item in filtered}
|
file_paths = {item["file_path"] for item in filtered}
|
||||||
assert file_paths == {"model1.safetensors", "model3.safetensors", "model4.safetensors"}
|
assert file_paths == {"model1.safetensors"}
|
||||||
|
|
||||||
# Test allow_selling=False (should return models that don't allow selling - don't have Image permission)
|
# Test allow_selling=False (should return models without the Image permission)
|
||||||
filtered = await service._apply_allow_selling_filter(test_data, allow_selling=False)
|
filtered = await service._apply_allow_selling_filter(test_data, allow_selling=False)
|
||||||
assert len(filtered) == 2 # model2 and model5
|
assert len(filtered) == 4 # model2, model3, model4, model5
|
||||||
file_paths = {item["file_path"] for item in filtered}
|
file_paths = {item["file_path"] for item in filtered}
|
||||||
assert file_paths == {"model2.safetensors", "model5.safetensors"}
|
assert file_paths == {"model2.safetensors", "model3.safetensors", "model4.safetensors", "model5.safetensors"}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
|||||||
@@ -131,13 +131,12 @@ async def test_pool_filter_allow_selling_true(lora_service, sample_loras):
|
|||||||
filtered = await lora_service._apply_pool_filters(sample_loras, pool_config)
|
filtered = await lora_service._apply_pool_filters(sample_loras, pool_config)
|
||||||
|
|
||||||
# Should keep models with Image permission (allowSelling)
|
# Should keep models with Image permission (allowSelling)
|
||||||
# Models: no_credit_required_for_selling, credit_required_for_selling, default_license
|
# Sell alone does not imply Image, so default_license is excluded.
|
||||||
assert len(filtered) == 3
|
assert len(filtered) == 2
|
||||||
file_names = {lora["file_name"] for lora in filtered}
|
file_names = {lora["file_name"] for lora in filtered}
|
||||||
assert file_names == {
|
assert file_names == {
|
||||||
"no_credit_required_for_selling.safetensors",
|
"no_credit_required_for_selling.safetensors",
|
||||||
"credit_required_for_selling.safetensors",
|
"credit_required_for_selling.safetensors",
|
||||||
"default_license.safetensors",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -178,12 +177,11 @@ async def test_pool_filter_both_license_filters(lora_service, sample_loras):
|
|||||||
# Should keep models where both conditions are met:
|
# Should keep models where both conditions are met:
|
||||||
# - allowNoCredit=True (no credit required)
|
# - allowNoCredit=True (no credit required)
|
||||||
# - Image permission exists (allow selling)
|
# - Image permission exists (allow selling)
|
||||||
# Models: no_credit_required_for_selling, default_license
|
# default_license has ["Sell"] without Image, so it's excluded.
|
||||||
assert len(filtered) == 2
|
assert len(filtered) == 1
|
||||||
file_names = {lora["file_name"] for lora in filtered}
|
file_names = {lora["file_name"] for lora in filtered}
|
||||||
assert file_names == {
|
assert file_names == {
|
||||||
"no_credit_required_for_selling.safetensors",
|
"no_credit_required_for_selling.safetensors",
|
||||||
"default_license.safetensors",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,8 @@ async def test_initialize_cache_populates_cache(tmp_path: Path):
|
|||||||
_normalize_path(tmp_path / "one.txt"),
|
_normalize_path(tmp_path / "one.txt"),
|
||||||
_normalize_path(tmp_path / "nested" / "two.txt"),
|
_normalize_path(tmp_path / "nested" / "two.txt"),
|
||||||
}
|
}
|
||||||
assert {item["license_flags"] for item in cache.raw_data} == {DEFAULT_LICENSE_FLAGS}
|
# build_license_flags({}) returns 113 (defaults: allowNoCredit + ["Sell"] + derivatives + differentLicense)
|
||||||
|
assert {item["license_flags"] for item in cache.raw_data} == {113}
|
||||||
|
|
||||||
assert scanner._hash_index.get_path("hash-one") == _normalize_path(tmp_path / "one.txt")
|
assert scanner._hash_index.get_path("hash-one") == _normalize_path(tmp_path / "one.txt")
|
||||||
assert scanner._hash_index.get_path("hash-two") == _normalize_path(tmp_path / "nested" / "two.txt")
|
assert scanner._hash_index.get_path("hash-two") == _normalize_path(tmp_path / "nested" / "two.txt")
|
||||||
@@ -190,7 +191,8 @@ async def test_initialize_in_background_applies_scan_result(tmp_path: Path, monk
|
|||||||
_normalize_path(tmp_path / "one.txt"),
|
_normalize_path(tmp_path / "one.txt"),
|
||||||
_normalize_path(tmp_path / "nested" / "two.txt"),
|
_normalize_path(tmp_path / "nested" / "two.txt"),
|
||||||
}
|
}
|
||||||
assert {item["license_flags"] for item in cache.raw_data} == {DEFAULT_LICENSE_FLAGS}
|
# build_license_flags({}) returns 113 (defaults: allowNoCredit + ["Sell"] + derivatives + differentLicense)
|
||||||
|
assert {item["license_flags"] for item in cache.raw_data} == {113}
|
||||||
assert scanner._hash_index.get_path("hash-two") == _normalize_path(tmp_path / "nested" / "two.txt")
|
assert scanner._hash_index.get_path("hash-two") == _normalize_path(tmp_path / "nested" / "two.txt")
|
||||||
assert scanner._tags_count == {"alpha": 1, "beta": 1}
|
assert scanner._tags_count == {"alpha": 1, "beta": 1}
|
||||||
assert scanner._excluded_models == [_normalize_path(tmp_path / "skip-file.txt")]
|
assert scanner._excluded_models == [_normalize_path(tmp_path / "skip-file.txt")]
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ def test_resolve_license_payload_defaults():
|
|||||||
assert payload["allowDerivatives"] is True
|
assert payload["allowDerivatives"] is True
|
||||||
assert payload["allowDifferentLicense"] is True
|
assert payload["allowDifferentLicense"] is True
|
||||||
assert payload["allowCommercialUse"] == ["Sell"]
|
assert payload["allowCommercialUse"] == ["Sell"]
|
||||||
assert flags == 127
|
# Default ["Sell"] only sets the Sell bit (16), plus NoCredit (1),
|
||||||
|
# Derivatives (32) and DifferentLicense (64) = 113.
|
||||||
|
assert flags == 113
|
||||||
|
|
||||||
|
|
||||||
def test_build_license_flags_custom_values():
|
def test_build_license_flags_custom_values():
|
||||||
@@ -34,11 +36,10 @@ def test_build_license_flags_custom_values():
|
|||||||
assert payload["allowDifferentLicense"] is False
|
assert payload["allowDifferentLicense"] is False
|
||||||
|
|
||||||
flags = build_license_flags(source)
|
flags = build_license_flags(source)
|
||||||
# Sell automatically enables all commercial bits including image.
|
assert flags == 18
|
||||||
assert flags == 30
|
|
||||||
|
|
||||||
|
|
||||||
def test_build_license_flags_respects_commercial_hierarchy():
|
def test_build_license_flags_independent_values():
|
||||||
base = {
|
base = {
|
||||||
"allowNoCredit": False,
|
"allowNoCredit": False,
|
||||||
"allowDerivatives": False,
|
"allowDerivatives": False,
|
||||||
@@ -46,14 +47,10 @@ def test_build_license_flags_respects_commercial_hierarchy():
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert build_license_flags({**base, "allowCommercialUse": []}) == 0
|
assert build_license_flags({**base, "allowCommercialUse": []}) == 0
|
||||||
# Rent adds rent and rentcivit permissions.
|
assert build_license_flags({**base, "allowCommercialUse": ["Rent"]}) == 8
|
||||||
assert build_license_flags({**base, "allowCommercialUse": ["Rent"]}) == 12
|
|
||||||
# RentCivit alone should only set its own bit.
|
|
||||||
assert build_license_flags({**base, "allowCommercialUse": ["RentCivit"]}) == 4
|
assert build_license_flags({**base, "allowCommercialUse": ["RentCivit"]}) == 4
|
||||||
# Image only toggles the image bit.
|
|
||||||
assert build_license_flags({**base, "allowCommercialUse": ["Image"]}) == 2
|
assert build_license_flags({**base, "allowCommercialUse": ["Image"]}) == 2
|
||||||
# Sell forces all commercial bits regardless of image listing.
|
assert build_license_flags({**base, "allowCommercialUse": ["Sell"]}) == 16
|
||||||
assert build_license_flags({**base, "allowCommercialUse": ["Sell"]}) == 30
|
|
||||||
|
|
||||||
|
|
||||||
def test_build_license_flags_parses_aggregate_string():
|
def test_build_license_flags_parses_aggregate_string():
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="section__toggles">
|
<div class="section__toggles">
|
||||||
<label class="toggle-item">
|
<label class="toggle-item">
|
||||||
<span class="toggle-item__label">No Credit Required</span>
|
<span class="toggle-item__label" title="Use the model without crediting the creator">No Credit Required</span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="toggle-switch"
|
class="toggle-switch"
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="toggle-item">
|
<label class="toggle-item">
|
||||||
<span class="toggle-item__label">Allow Selling</span>
|
<span class="toggle-item__label" title="Allow selling generated images">Allow Selling</span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="toggle-switch"
|
class="toggle-switch"
|
||||||
|
|||||||
@@ -398,13 +398,13 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section[data-v-dea4adf6] {
|
.section[data-v-07ddd3df] {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
.section__header[data-v-dea4adf6] {
|
.section__header[data-v-07ddd3df] {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
.section__title[data-v-dea4adf6] {
|
.section__title[data-v-07ddd3df] {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@@ -412,21 +412,21 @@
|
|||||||
color: var(--fg-color, #fff);
|
color: var(--fg-color, #fff);
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
.section__toggles[data-v-dea4adf6] {
|
.section__toggles[data-v-07ddd3df] {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
.toggle-item[data-v-dea4adf6] {
|
.toggle-item[data-v-07ddd3df] {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.toggle-item__label[data-v-dea4adf6] {
|
.toggle-item__label[data-v-07ddd3df] {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--fg-color, #fff);
|
color: var(--fg-color, #fff);
|
||||||
}
|
}
|
||||||
.toggle-switch[data-v-dea4adf6] {
|
.toggle-switch[data-v-07ddd3df] {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
@@ -435,7 +435,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.toggle-switch__track[data-v-dea4adf6] {
|
.toggle-switch__track[data-v-07ddd3df] {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background: var(--comfy-input-bg, #333);
|
background: var(--comfy-input-bg, #333);
|
||||||
@@ -443,11 +443,11 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
}
|
}
|
||||||
.toggle-switch--active .toggle-switch__track[data-v-dea4adf6] {
|
.toggle-switch--active .toggle-switch__track[data-v-07ddd3df] {
|
||||||
background: rgba(66, 153, 225, 0.3);
|
background: rgba(66, 153, 225, 0.3);
|
||||||
border-color: rgba(66, 153, 225, 0.6);
|
border-color: rgba(66, 153, 225, 0.6);
|
||||||
}
|
}
|
||||||
.toggle-switch__thumb[data-v-dea4adf6] {
|
.toggle-switch__thumb[data-v-07ddd3df] {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 3px;
|
top: 3px;
|
||||||
left: 2px;
|
left: 2px;
|
||||||
@@ -458,12 +458,12 @@
|
|||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
.toggle-switch--active .toggle-switch__thumb[data-v-dea4adf6] {
|
.toggle-switch--active .toggle-switch__thumb[data-v-07ddd3df] {
|
||||||
transform: translateX(16px);
|
transform: translateX(16px);
|
||||||
background: #4299e1;
|
background: #4299e1;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.toggle-switch:hover .toggle-switch__thumb[data-v-dea4adf6] {
|
.toggle-switch:hover .toggle-switch__thumb[data-v-07ddd3df] {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2223,7 +2223,7 @@ to { transform: rotate(360deg);
|
|||||||
})();
|
})();
|
||||||
var _a;
|
var _a;
|
||||||
import { app as app$1 } from "../../../scripts/app.js";
|
import { app as app$1 } from "../../../scripts/app.js";
|
||||||
import { api } from "../../../scripts/api.js";
|
import { api as api$1 } from "../../../scripts/api.js";
|
||||||
/**
|
/**
|
||||||
* @vue/shared v3.5.26
|
* @vue/shared v3.5.26
|
||||||
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
||||||
@@ -11094,7 +11094,10 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
|
|||||||
], -1)),
|
], -1)),
|
||||||
createBaseVNode("div", _hoisted_2$e, [
|
createBaseVNode("div", _hoisted_2$e, [
|
||||||
createBaseVNode("label", _hoisted_3$c, [
|
createBaseVNode("label", _hoisted_3$c, [
|
||||||
_cache[3] || (_cache[3] = createBaseVNode("span", { class: "toggle-item__label" }, "No Credit Required", -1)),
|
_cache[3] || (_cache[3] = createBaseVNode("span", {
|
||||||
|
class: "toggle-item__label",
|
||||||
|
title: "Use the model without crediting the creator"
|
||||||
|
}, "No Credit Required", -1)),
|
||||||
createBaseVNode("button", {
|
createBaseVNode("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
class: normalizeClass(["toggle-switch", { "toggle-switch--active": __props.noCreditRequired }]),
|
class: normalizeClass(["toggle-switch", { "toggle-switch--active": __props.noCreditRequired }]),
|
||||||
@@ -11107,7 +11110,10 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
|
|||||||
])], 10, _hoisted_4$a)
|
])], 10, _hoisted_4$a)
|
||||||
]),
|
]),
|
||||||
createBaseVNode("label", _hoisted_5$8, [
|
createBaseVNode("label", _hoisted_5$8, [
|
||||||
_cache[5] || (_cache[5] = createBaseVNode("span", { class: "toggle-item__label" }, "Allow Selling", -1)),
|
_cache[5] || (_cache[5] = createBaseVNode("span", {
|
||||||
|
class: "toggle-item__label",
|
||||||
|
title: "Allow selling generated images"
|
||||||
|
}, "Allow Selling", -1)),
|
||||||
createBaseVNode("button", {
|
createBaseVNode("button", {
|
||||||
type: "button",
|
type: "button",
|
||||||
class: normalizeClass(["toggle-switch", { "toggle-switch--active": __props.allowSelling }]),
|
class: normalizeClass(["toggle-switch", { "toggle-switch--active": __props.allowSelling }]),
|
||||||
@@ -11124,7 +11130,7 @@ const _sfc_main$i = /* @__PURE__ */ defineComponent({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const LicenseSection = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-dea4adf6"]]);
|
const LicenseSection = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["__scopeId", "data-v-07ddd3df"]]);
|
||||||
const _hoisted_1$e = { class: "preview" };
|
const _hoisted_1$e = { class: "preview" };
|
||||||
const _hoisted_2$d = { class: "preview__title" };
|
const _hoisted_2$d = { class: "preview__title" };
|
||||||
const _hoisted_3$b = ["disabled"];
|
const _hoisted_3$b = ["disabled"];
|
||||||
@@ -15031,6 +15037,54 @@ function createModeChangeCallback(node, updateDownstreamLoaders2, nodeSpecificCa
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
const app = {};
|
const app = {};
|
||||||
|
const api = {
|
||||||
|
fetchApi: (...args) => fetch(...args),
|
||||||
|
addEventListener: (eventName, handler) => document.addEventListener(eventName, handler),
|
||||||
|
removeEventListener: (eventName, handler) => document.removeEventListener(eventName, handler)
|
||||||
|
};
|
||||||
|
let _loraSyntaxFormatCache = null;
|
||||||
|
let _loraSyntaxFormatRefreshPromise = null;
|
||||||
|
async function _fetchLoraSyntaxFormat() {
|
||||||
|
try {
|
||||||
|
const response = await api.fetchApi("/lm/settings");
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
if (data.success && data.settings) {
|
||||||
|
_loraSyntaxFormatCache = data.settings.lora_syntax_format || "legacy";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
if (_loraSyntaxFormatCache === null) {
|
||||||
|
_loraSyntaxFormatCache = "legacy";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _triggerBackgroundRefresh() {
|
||||||
|
if (_loraSyntaxFormatRefreshPromise) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_loraSyntaxFormatRefreshPromise = _fetchLoraSyntaxFormat().finally(() => {
|
||||||
|
_loraSyntaxFormatRefreshPromise = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function _initLoraSyntaxFormat() {
|
||||||
|
_triggerBackgroundRefresh();
|
||||||
|
}
|
||||||
|
_initLoraSyntaxFormat();
|
||||||
|
function _initLoraSyntaxFormatReactive() {
|
||||||
|
window.addEventListener("storage", (e) => {
|
||||||
|
if (e.key === "lm:lora-syntax-format-changed") {
|
||||||
|
_triggerBackgroundRefresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document.addEventListener("visibilitychange", () => {
|
||||||
|
if (document.visibilityState === "visible") {
|
||||||
|
_triggerBackgroundRefresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_initLoraSyntaxFormatReactive();
|
||||||
const ROOT_GRAPH_ID = "root";
|
const ROOT_GRAPH_ID = "root";
|
||||||
const LORA_PROVIDER_NODE_TYPES = [
|
const LORA_PROVIDER_NODE_TYPES = [
|
||||||
"Lora Stacker (LoraManager)",
|
"Lora Stacker (LoraManager)",
|
||||||
@@ -15407,7 +15461,7 @@ function createLoraRandomizerWidget(node) {
|
|||||||
const vueApp = createApp(LoraRandomizerWidget, {
|
const vueApp = createApp(LoraRandomizerWidget, {
|
||||||
widget,
|
widget,
|
||||||
node,
|
node,
|
||||||
api
|
api: api$1
|
||||||
});
|
});
|
||||||
vueApp.use(PrimeVue, {
|
vueApp.use(PrimeVue, {
|
||||||
unstyled: true,
|
unstyled: true,
|
||||||
@@ -15482,7 +15536,7 @@ function createLoraCyclerWidget(node) {
|
|||||||
const vueApp = createApp(LoraCyclerWidget, {
|
const vueApp = createApp(LoraCyclerWidget, {
|
||||||
widget,
|
widget,
|
||||||
node,
|
node,
|
||||||
api
|
api: api$1
|
||||||
});
|
});
|
||||||
vueApp.use(PrimeVue, {
|
vueApp.use(PrimeVue, {
|
||||||
unstyled: true,
|
unstyled: true,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user