# Path: modeltrans/conf.py
# def get_available_languages(include_default=True):
#     """
#     Returns a tuple of available languages for django-modeltrans.
#     """
#     MODELTRANS_AVAILABLE_LANGUAGES = get_available_languages_setting()
# 
#     if include_default:
#         return tuple(
#             set(itertools.chain(MODELTRANS_AVAILABLE_LANGUAGES, (get_default_language(),)))
#         )
#     else:
#         return MODELTRANS_AVAILABLE_LANGUAGES
# 
# def get_default_language():
#     return settings.LANGUAGE_CODE
# 
# Path: modeltrans/fields.py
# SUPPORTED_FIELDS = (fields.CharField, fields.TextField)
# DEFAULT_LANGUAGE = get_default_language()
# def translated_field_factory(original_field, language=None, *args, **kwargs):
#     def __init__(self, original_field, language=None, *args, **kwargs):
#     def original_name(self):
#     def help_text(self):
#     def contribute_to_class(self, cls, name):
#     def db_type(self, connection):
#     def get_instance_fallback_chain(self, instance, language):
#     def __get__(self, instance, instance_type=None):
#     def __set__(self, instance, value):
#     def get_field_name(self):
#     def get_language(self):
#     def output_field(self):
#     def _localized_lookup(self, language, bare_lookup):
#     def as_expression(self, bare_lookup, fallback=True):
#     def __init__(
#         self,
#         fields=None,
#         required_languages=None,
#         virtual_fields=True,
#         fallback_language_field=None,
#         *args,
#         **kwargs,
#     ):
#     def deconstruct(self):
#     def get_translated_fields(self):
#     def contribute_to_class(self, cls, name):
#     class Specific(TranslatedVirtualField, original_field.__class__):
# class TranslatedVirtualField:
# class TranslationField(JSONField):
# 
# Path: modeltrans/translator.py
# def get_i18n_field(Model):
#     """
#     Return the i18n field if the model has it, else None.
#     """
#     try:
#         i18n_field = Model._meta.get_field("i18n")
#     except FieldDoesNotExist:
#         return
# 
#     if not isinstance(i18n_field, TranslationField):
#         return
# 
#     return i18n_field
# 
# Path: modeltrans/utils.py
# def build_localized_fieldname(field_name, lang, ignore_default=False):
#     if lang == "id":
#         # The 2-letter Indonesian language code is problematic with the
#         # current naming scheme as Django foreign keys also add "id" suffix.
#         lang = "ind"
#     if ignore_default and lang == get_default_language():
#         return field_name
#     return "{}_{}".format(field_name, lang.replace("-", "_"))
# 
# def get_language():
#     """
#     Return an active language code that is guaranteed to be in settings.LANGUAGES
# 
#     (Django does not seem to guarantee this for us.)
#     """
#     lang = _get_language()
#     if lang in get_available_languages():
#         return lang
#     return get_default_language()


import itertools
from django import forms
from django.utils.translation import gettext_lazy as _
from .conf import get_available_languages, get_default_language
from .fields import get_instance_field_value
from .translator import get_i18n_field
from .utils import build_localized_fieldname, get_language
    def __new__(mcs, name, bases, attrs):
        """
        Include all translation fields for translatable fields declared in the form.

        We use the standard ModelForm field declaration procedure of the ModelFormMetaClass,
        so that all fields are declared during creation of the new object.

        Different actions are required for different Meta class options:
        1) fields - if fields are declared explicitly with the fields option, the related i18n fields will not be
        included, and these have to be added to base_fields.
        2) exclude - if fields are declared implicitly with the exclude option, the i18n translation fields, as well as
        the i18n field itself, will be included. We will remove the i18n field.

        Here all languages are included, so that in the form we can curate which fields are available according to
        settings of the form instance (e.g. kwarg overrides, or model instance fallbacks).
        """
        new_class = super().__new__(mcs, name, bases, attrs)

        # from ModelFormMetaClass, needed for calling fields for model
        base_formfield_callback = None
        for b in bases:
            if hasattr(b, "Meta") and hasattr(b.Meta, "formfield_callback"):
                base_formfield_callback = b.Meta.formfield_callback
                break
        formfield_callback = attrs.pop("formfield_callback", base_formfield_callback)

        # get options, with extra translation form options
        opts = new_class._meta = TranslationModelFormOptions(getattr(new_class, "Meta", None))
        model_class = opts.model


# Path: modeltrans/conf.py
# def get_available_languages(include_default=True):
#     """
#     Returns a tuple of available languages for django-modeltrans.
#     """
#     MODELTRANS_AVAILABLE_LANGUAGES = get_available_languages_setting()
# 
#     if include_default:
#         return tuple(
#             set(itertools.chain(MODELTRANS_AVAILABLE_LANGUAGES, (get_default_language(),)))
#         )
#     else:
#         return MODELTRANS_AVAILABLE_LANGUAGES
# 
# def get_default_language():
#     return settings.LANGUAGE_CODE
# 
# Path: modeltrans/fields.py
# SUPPORTED_FIELDS = (fields.CharField, fields.TextField)
# DEFAULT_LANGUAGE = get_default_language()
# def translated_field_factory(original_field, language=None, *args, **kwargs):
#     def __init__(self, original_field, language=None, *args, **kwargs):
#     def original_name(self):
#     def help_text(self):
#     def contribute_to_class(self, cls, name):
#     def db_type(self, connection):
#     def get_instance_fallback_chain(self, instance, language):
#     def __get__(self, instance, instance_type=None):
#     def __set__(self, instance, value):
#     def get_field_name(self):
#     def get_language(self):
#     def output_field(self):
#     def _localized_lookup(self, language, bare_lookup):
#     def as_expression(self, bare_lookup, fallback=True):
#     def __init__(
#         self,
#         fields=None,
#         required_languages=None,
#         virtual_fields=True,
#         fallback_language_field=None,
#         *args,
#         **kwargs,
#     ):
#     def deconstruct(self):
#     def get_translated_fields(self):
#     def contribute_to_class(self, cls, name):
#     class Specific(TranslatedVirtualField, original_field.__class__):
# class TranslatedVirtualField:
# class TranslationField(JSONField):
# 
# Path: modeltrans/translator.py
# def get_i18n_field(Model):
#     """
#     Return the i18n field if the model has it, else None.
#     """
#     try:
#         i18n_field = Model._meta.get_field("i18n")
#     except FieldDoesNotExist:
#         return
# 
#     if not isinstance(i18n_field, TranslationField):
#         return
# 
#     return i18n_field
# 
# Path: modeltrans/utils.py
# def build_localized_fieldname(field_name, lang, ignore_default=False):
#     if lang == "id":
#         # The 2-letter Indonesian language code is problematic with the
#         # current naming scheme as Django foreign keys also add "id" suffix.
#         lang = "ind"
#     if ignore_default and lang == get_default_language():
#         return field_name
#     return "{}_{}".format(field_name, lang.replace("-", "_"))
# 
# def get_language():
#     """
#     Return an active language code that is guaranteed to be in settings.LANGUAGES
# 
#     (Django does not seem to guarantee this for us.)
#     """
#     lang = _get_language()
#     if lang in get_available_languages():
#         return lang
#     return get_default_language()


# Path: modeltrans/forms.py
import itertools
from django import forms
from django.utils.translation import gettext_lazy as _
from .conf import get_available_languages, get_default_language
from .fields import get_instance_field_value
from .translator import get_i18n_field
from .utils import build_localized_fieldname, get_language

    def __new__(mcs, name, bases, attrs):
        """
        Include all translation fields for translatable fields declared in the form.

        We use the standard ModelForm field declaration procedure of the ModelFormMetaClass,
        so that all fields are declared during creation of the new object.

        Different actions are required for different Meta class options:
        1) fields - if fields are declared explicitly with the fields option, the related i18n fields will not be
        included, and these have to be added to base_fields.
        2) exclude - if fields are declared implicitly with the exclude option, the i18n translation fields, as well as
        the i18n field itself, will be included. We will remove the i18n field.

        Here all languages are included, so that in the form we can curate which fields are available according to
        settings of the form instance (e.g. kwarg overrides, or model instance fallbacks).
        """
        new_class = super().__new__(mcs, name, bases, attrs)

        # from ModelFormMetaClass, needed for calling fields for model
        base_formfield_callback = None
        for b in bases:
            if hasattr(b, "Meta") and hasattr(b.Meta, "formfield_callback"):
                base_formfield_callback = b.Meta.formfield_callback
                break
        formfield_callback = attrs.pop("formfield_callback", base_formfield_callback)

        # get options, with extra translation form options
        opts = new_class._meta = TranslationModelFormOptions(getattr(new_class, "Meta", None))
        model_class = opts.model


        languages = get_available_languages()