text:
from unittest import TestCase, skip

from pykechain.enums import (
    ActivityRootNames,
    ContextGroup,
    ContextType,
    FilterType,
    FormCategory,
    Multiplicity,
    PropertyType,
    StatusCategory,
    WorkflowCategory,
)
from pykechain.exceptions import ForbiddenError, IllegalArgumentError, NotFoundError
from pykechain.models import MultiReferenceProperty
from pykechain.models.base_reference import _ReferenceProperty
from pykechain.models.property_reference import (
    ActivityReferencesProperty,
    ContextReferencesProperty,
    FormReferencesProperty,
    ScopeReferencesProperty,
    StatusReferencesProperty,
    UserReferencesProperty,
)
from pykechain.models.validators import RequiredFieldValidator
from pykechain.models.value_filter import PropertyValueFilter, ScopeFilter
from pykechain.models.workflow import Status, Workflow
from pykechain.utils import find, is_uuid
from tests.classes import TestBetamax

class TestPropertyBaseReference(TestCase):
    def setUp(self) -> None:
        super().setUp()
        self.base_ref = _ReferenceProperty(json=dict(), client=None)

    def test_prefilters(self):
        with self.assertRaises(NotImplementedError):
            self.base_ref.set_prefilters()

        with self.assertRaises(NotImplementedError):
            self.base_ref.get_prefilters()

class TestPropertyMultiReferenceProperty(TestBetamax):
    def setUp(self):
        super().setUp()

        # reference Part target (model and 1 instance)
        _wheel_model = self.project.model(ref="wheel")

        props = [
            PropertyType.DATETIME_VALUE,
            PropertyType.SINGLE_SELECT_VALUE,
            PropertyType.BOOLEAN_VALUE,
            PropertyType.FLOAT_VALUE,
            PropertyType.INT_VALUE,
            PropertyType.CHAR_VALUE,
        ]

        self.target_model = self.project.create_model_with_properties(
            parent=_wheel_model.parent_id,
            name="__Wheel",
            multiplicity=Multiplicity.ONE_MANY,
            properties_fvalues=[dict(name=p, property_type=p) for p in props],
        )

        # reference property model (with a value pointing to a reference target part model
        self.part_model = self.project.model("Bike")

        self.datetime_prop = self.target_model.property(PropertyType.DATETIME_VALUE)
        self.ssl_prop = self.target_model.property(PropertyType.SINGLE_SELECT_VALUE)
        self.bool_prop = self.target_model.property(PropertyType.BOOLEAN_VALUE)
        self.float_prop = self.target_model.property(PropertyType.FLOAT_VALUE)
        self.integer_prop = self.target_model.property(PropertyType.INT_VALUE)
        self.char_prop = self.target_model.property(PropertyType.CHAR_VALUE)

        self.ref_prop_name = "__Test reference property"
        self.ref_prop_model = self.part_model.add_property(
            name=self.ref_prop_name,
            property_type=PropertyType.REFERENCES_VALUE,
            default_value=self.target_model.id,
        )  # type: MultiReferenceProperty

        # reference property instance holding the value
        part_instance = self.part_model.instance()
        self.ref = find(
            part_instance.properties, lambda p: p.model_id == self.ref_prop_model.id
        )  # type: MultiReferenceProperty

    def tearDown(self):
        self.target_model.delete()
        self.ref_prop_model.delete()
        super().tearDown()

    def test_referencing_a_model(self):
        # setUp
        wheel_model = self.project.model("Wheel")
        self.ref_prop_model.value = [wheel_model]

        # testing
        self.assertEqual(len(list(self.ref_prop_model.value)), 1)

    def test_referencing_multiple_instances_using_parts(self):
        # setUp
        wheel_model = self.project.model("Wheel")
        self.ref_prop_model.value = [wheel_model]
        wheel_instances = wheel_model.instances()
        wheel_instances_list = [instance for instance in wheel_instances]

        # set ref value
        self.ref.value = wheel_instances_list

        # testing
        self.assertTrue(len(self.ref.value) >= 2)

    def test_referencing_multiple_instances_using_ids(self):
        # setUp
        wheel_model = self.project.model("Wheel")
        self.ref_prop_model.value = [wheel_model]
        wheel_instances = wheel_model.instances()
        wheel_instances_list = [instance.id for instance in wheel_instances]

        # set ref value
        self.ref.value = wheel_instances_list
        self.ref._cached_values = None

        # testing
        self.assertTrue(len(self.ref.value) >= 2)

    def test_referencing_a_list_with_no_parts(self):
        # setUp
        fake_part = [15, 21, 26]

        # testing
        with self.assertRaises(ValueError):
            self.ref.value = fake_part

    def test_value_if_multi_ref_gives_back_all_parts(self):
        """because of #276 problem"""
        # setUp
        self.ref_prop_model.value = [self.target_model]

        wheel_instances = self.target_model.instances()
        wheel_instances_list = [instance.id for instance in wheel_instances]

        # set ref value
        self.ref.value = wheel_instances_list
        self.ref.refresh()

        # testing
        all_referred_parts = self.ref.value
        self.assertEqual(len(all_referred_parts), len(self.ref._value))

    def test_value_if_nothing_is_referenced(self):
        # setUp
        value_of_multi_ref = self.ref.value

        # testing
        self.assertFalse(self.ref.has_value())
        self.assertIsNone(value_of_multi_ref)

    def test_value_ids(self):
        wheel_instances = self.target_model.instances()
        wheel_instances_list = [instance.id for instance in wheel_instances]
        self.ref.value = wheel_instances_list
        self.ref.refresh()

        ids = self.ref.value_ids()

        self.assertIsInstance(ids, list)
        self.assertTrue(all(isinstance(v, str) for v in ids))

    def test_multi_ref_choices(self):
        # setUp
        self.project.part(ref="bike").add_with_properties(
            name="__Wheel 2",
            model=self.target_model,
            update_dict={
                PropertyType.BOOLEAN_VALUE: True,
            },
        )
        self.ref_prop_model.value = [self.target_model]
        possible_options = self.ref.choices()

        # testing
        self.assertEqual(2, len(possible_options))

        self.ref_prop_model.set_prefilters(
            property_models=[self.target_model.property(PropertyType.BOOLEAN_VALUE)],
            values=[True],
            filters_type=[FilterType.EXACT],
        )
        self.ref.refresh()

        possible_options = self.ref.choices()
        self.assertEqual(1, len(possible_options))

    def test_create_ref_property_referencing_part_in_list(self):
        # setUp
        new_reference_to_wheel = self.part_model.add_property(
            name=self.ref_prop_name,
            property_type=PropertyType.REFERENCES_VALUE,
            default_value=[self.target_model],
        )
        # testing
        self.assertTrue(self.ref_prop_model.value[0].id, self.target_model.id)

        # tearDown
        new_reference_to_wheel.delete()

    def test_create_ref_property_referencing_id_in_list(self):
        # setUp
        new_reference_to_wheel = self.part_model.add_property(
            name=self.ref_prop_name,
            property_type=PropertyType.REFERENCES_VALUE,
            default_value=[self.target_model.id],
        )
        # testing
        self.assertTrue(self.ref_prop_model.value[0].id, self.target_model.id)

        # tearDown
        new_reference_to_wheel.delete()

    def test_create_ref_property_wrongly_referencing_in_list(self):
        # testing
        with self.assertRaises(IllegalArgumentError):
            self.part_model.add_property(
                name=self.ref_prop_name,
                property_type=PropertyType.REFERENCES_VALUE,
                default_value=[12],
            )

    def test_create_ref_property_referencing_part(self):
        # setUp
        new_reference_to_wheel = self.part_model.add_property(
            name=self.ref_prop_name,
            property_type=PropertyType.REFERENCES_VALUE,
            default_value=self.target_model,
        )
        # testing
        self.assertTrue(self.ref_prop_model.value[0].id, self.target_model.id)

        # tearDown
        new_reference_to_wheel.delete()

    def test_create_ref_property_referencing_id(self):
        # setUp
        new_reference_to_wheel = self.part_model.add_property(
            name=self.ref_prop_name,
            property_type=PropertyType.REFERENCES_VALUE,
            default_value=self.target_model.id,
        )
        # testing
        self.assertTrue(self.ref_prop_model.value[0].id, self.target_model.id)

        # tearDown
        new_reference_to_wheel.delete()

    def test_create_ref_property_wrongly_referencing(self):
        # testing
        with self.assertRaises(IllegalArgumentError):
            self.part_model.add_property(
                name=self.ref_prop_name,
                property_type=PropertyType.REFERENCES_VALUE,
                default_value=True,
            )

    # new in 3.0
    def test_set_prefilters_on_reference_property(self):
        # setUp
        diameter_property = self.float_prop  # decimal property
        spokes_property = self.integer_prop  # integer property
        rim_material_property = self.char_prop  # single line text

        self.ref_prop_model.set_prefilters(
            property_models=[
                diameter_property,
                spokes_property,
                rim_material_property,
                self.datetime_prop,
                self.ssl_prop,
                self.bool_prop,
            ],
            values=[30.5, 7, "Al", self.time, "Michelin", True],
            filters_type=[
                FilterType.GREATER_THAN_EQUAL,
                FilterType.LOWER_THAN_EQUAL,
                FilterType.CONTAINS,
                FilterType.GREATER_THAN_EQUAL,
                FilterType.CONTAINS,
                FilterType.EXACT,
            ],
        )
        self.assertIn("property_value", self.ref_prop_model._options["prefilters"])

        filter_string = self.ref_prop_model._options["prefilters"]["property_value"]
        filters = set(filter_string.split(","))

        # testing
        self.assertIn(
            "{}:{}:{}".format(
                diameter_property.id, 30.5, FilterType.GREATER_THAN_EQUAL
            ),
            filters,
        )
        self.assertIn(
            f"{spokes_property.id}:{7}:{FilterType.LOWER_THAN_EQUAL}",
            filters,
        )
        self.assertIn(
            "{}:{}:{}".format(rim_material_property.id, "Al", FilterType.CONTAINS),
            filters,
        )
        self.assertIn(
            "{}:{}:{}".format(self.bool_prop.id, "true", FilterType.EXACT), filters
        )
        self.assertIn(
            "{}:{}:{}".format(self.ssl_prop.id, "Michelin", FilterType.CONTAINS),
            filters,
        )
        self.assertIn(
            "{}:{}:{}".format(
                self.datetime_prop.id, self.time, FilterType.GREATER_THAN_EQUAL
            ),
            filters,
        )

    def test_set_prefilters_with_tuples(self):
        prefilters_set = [
            PropertyValueFilter(self.float_prop, 15.3, FilterType.GREATER_THAN_EQUAL),
            PropertyValueFilter(self.char_prop, "Al", FilterType.CONTAINS),
        ]

        self.ref_prop_model.set_prefilters(prefilters=prefilters_set)

        prefilters_get = self.ref_prop_model.get_prefilters()

        self.assertTrue(prefilters_get, msg="No prefilters returned")
        first_filter = prefilters_get[0]

        self.assertEqual(self.float_prop.id, first_filter.id)
        self.assertEqual("15.3", first_filter.value)
        self.assertEqual(FilterType.GREATER_THAN_EQUAL, first_filter.type)

    def test_set_prefilters_with_validation(self):
        prefilter_good = PropertyValueFilter(
            self.float_prop, 15.3, FilterType.GREATER_THAN_EQUAL
        )
        prefilter_bad = PropertyValueFilter(
            self.part_model.property("Gears"), 15.3, FilterType.GREATER_THAN_EQUAL
        )

        # Validate automatically
        self.ref_prop_model.set_prefilters(prefilters=[prefilter_good])
        with self.assertRaises(IllegalArgumentError):
            self.ref_prop_model.set_prefilters(prefilters=[prefilter_bad])

        # Validate by providing the referenced model
        self.ref_prop_model.set_prefilters(
            prefilters=[prefilter_good], validate=self.target_model
        )
        with self.assertRaises(IllegalArgumentError):
            self.ref_prop_model.set_prefilters(
                prefilters=[prefilter_bad], validate=self.target_model
            )

        # Dont validate
        self.ref_prop_model.set_prefilters(prefilters=[prefilter_good], validate=False)
        self.ref_prop_model.set_prefilters(prefilters=[prefilter_bad], validate=None)

    def test_set_prefilters_on_reference_property_with_excluded_propmodels_and_validators(
        self,
    ):
        # The excluded propmodels and validators already set on the property should not be erased when
        # setting prefilters

        # setUp
        diameter_property = self.float_prop
        spokes_property = self.integer_prop

        self.ref_prop_model.set_excluded_propmodels(
            property_models=[diameter_property, spokes_property]
        )
        self.ref_prop_model.validators = [RequiredFieldValidator()]

        self.ref_prop_model.set_prefilters(
            property_models=[diameter_property],
            values=[15.13],
            filters_type=[FilterType.GREATER_THAN_EQUAL],
        )

        # testing Filters
        self.assertIn(
            "{}:{}:{}".format(
                diameter_property.id, 15.13, FilterType.GREATER_THAN_EQUAL
            ),
            self.ref_prop_model._options["prefilters"]["property_value"],
        )

        # testing Excluded props
        self.assertIn("propmodels_excl", self.ref_prop_model._options)
        excluded = self.ref_prop_model._options["propmodels_excl"]

        self.assertEqual(len(excluded), 2)
        self.assertIn(diameter_property.id, excluded)
        self.assertIn(spokes_property.id, excluded)

        # testing Validators
        self.assertTrue(self.ref_prop_model.validators)
        self.assertIsInstance(
            self.ref_prop_model._validators[0], RequiredFieldValidator
        )

    def test_clear_prefilters(self):
        # setUp
        prefilter_1 = PropertyValueFilter(
            property_model=self.float_prop,
            value=15.13,
            filter_type=FilterType.GREATER_THAN_EQUAL,
        )
        self.ref_prop_model.set_prefilters(prefilters=[prefilter_1])

        # Add filter for different property, see if the first one is removed (clear = True)
        prefilter_2 = PropertyValueFilter(
            property_model=self.integer_prop,
            value=13,
            filter_type=FilterType.EXACT,
        )
        self.ref_prop_model.set_prefilters(
            prefilters=[prefilter_2],
            clear=True,
        )

        self.ref_prop_model.refresh()
        live_prefilters = self.ref_prop_model.get_prefilters()

        # testing
        self.assertTrue(live_prefilters, msg="Expected at least 1 prefilter")
        self.assertEqual(1, len(live_prefilters), msg="Expected 1 prefilter")
        self.assertEqual(prefilter_2, live_prefilters[0])

    def test_overwrite_prefilters(self):
        # setUp
        prefilter_1 = PropertyValueFilter(
            property_model=self.float_prop,
            value=15.13,
            filter_type=FilterType.GREATER_THAN_EQUAL,
        )
        prefilter_2 = PropertyValueFilter(
            property_model=self.integer_prop,
            value=13,
            filter_type=FilterType.EXACT,
        )
        prefilter_3 = PropertyValueFilter(
            property_model=self.float_prop,
            value=15.13,
            filter_type=FilterType.EXACT,
        )
        # Set the initial filters
        self.ref_prop_model.set_prefilters(prefilters=[prefilter_1, prefilter_2])

        # Add another filter for the same property to see if the first one is removed (overwrite = True)
        self.ref_prop_model.set_prefilters(prefilters=[prefilter_3], overwrite=True)

        self.ref_prop_model.refresh()
        live_prefilters = self.ref_prop_model.get_prefilters()

        # testing
        self.assertTrue(live_prefilters, msg="Expected at least 1 prefilter")
        self.assertEqual(2, len(live_prefilters), msg="Expected 2 prefilters")
        self.assertIn(prefilter_2, live_prefilters)
        self.assertIn(prefilter_3, live_prefilters)

    def test_set_prefilters_on_reference_property_using_uuid(self):
        # setUp
        diameter_property = self.float_prop
        spokes_property = self.integer_prop

        self.ref_prop_model.set_prefilters(
            property_models=[diameter_property.id, spokes_property.id],
            values=[30.5, 7],
            filters_type=[FilterType.GREATER_THAN_EQUAL, FilterType.LOWER_THAN_EQUAL],
        )

        # testing
        self.assertTrue("property_value" in self.ref_prop_model._options["prefilters"])
        self.assertTrue(
            f"{diameter_property.id}:{30.5}:{FilterType.GREATER_THAN_EQUAL}"
            in self.ref_prop_model._options["prefilters"]["property_value"]
        )
        self.assertTrue(
            f"{spokes_property.id}:{7}:{FilterType.LOWER_THAN_EQUAL}"
            in self.ref_prop_model._options["prefilters"]["property_value"]
        )

    def test_set_prefilters_on_reference_property_the_wrong_way(self):
        # setUp
        bike_gears_property = self.part_model.property(name="Gears")
        instance_diameter_property = self.target_model.instances()[0].property(
            PropertyType.FLOAT_VALUE
        )
        diameter_property = self.float_prop

        # testing
        # When prefilters are being set, but the property does not belong to the referenced part
        with self.assertRaises(IllegalArgumentError):
            self.ref_prop_model.set_prefilters(
                property_models=[bike_gears_property],
                values=[2],
                filters_type=[FilterType.GREATER_THAN_EQUAL],
            )

        # When prefilters are being set, but the property is an instance, not a model
        with self.assertRaises(IllegalArgumentError):
            self.ref_prop_model.set_prefilters(
                property_models=[instance_diameter_property],
                values=[3.33],
                filters_type=[FilterType.GREATER_THAN_EQUAL],
            )

        # When prefilters are being set, but the size of lists is not consistent
        with self.assertRaises(IllegalArgumentError):
            self.ref_prop_model.set_prefilters(
                property_models=[diameter_property],
                values=[3.33, 1.51],
                filters_type=[FilterType.GREATER_THAN_EQUAL, FilterType.CONTAINS],
            )

        # When prefilters are being set, but no UUIDs or `Property` objects are being used in property_models
        with self.assertRaises(IllegalArgumentError):
            # noinspection PyTypeChecker
            self.ref_prop_model.set_prefilters(
                property_models=[False, 301],
                values=[3.33, 1.51],
                filters_type=[FilterType.GREATER_THAN_EQUAL, FilterType.CONTAINS],
            )

    def test_set_excluded_propmodels_on_reference_property(self):
        # setUp
        diameter_property = self.float_prop
        spokes_property = self.integer_prop

        self.ref_prop_model.set_excluded_propmodels(
            property_models=[diameter_property, spokes_property]
        )

        # testing
        self.assertEqual(len(self.ref_prop_model._options["propmodels_excl"]), 2)
        self.assertTrue(
            diameter_property.id in self.ref_prop_model._options["propmodels_excl"]
        )
        self.assertTrue(
            spokes_property.id in self.ref_prop_model._options["propmodels_excl"]
        )

    def test_set_excluded_propmodels_with_validation(self):
        excluded_model_good = self.float_prop
        excluded_model_bad = self.part_model.property("Gears")

        # Validate automatically
        self.ref_prop_model.set_excluded_propmodels(
            property_models=[excluded_model_good]
        )
        with self.assertRaises(IllegalArgumentError):
            self.ref_prop_model.set_excluded_propmodels(
                property_models=[excluded_model_bad]
            )

        # Validate by providing the referenced model
        self.ref_prop_model.set_excluded_propmodels(
            property_models=[excluded_model_good], validate=self.target_model
        )
        with self.assertRaises(IllegalArgumentError):
            self.ref_prop_model.set_excluded_propmodels(
                property_models=[excluded_model_bad], validate=self.target_model
            )

        # Dont validate
        self.ref_prop_model.set_excluded_propmodels(
            property_models=[excluded_model_good], validate=False
        )
        self.ref_prop_model.set_excluded_propmodels(
            property_models=[excluded_model_bad], validate=None
        )

    def test_set_excluded_propmodels_on_reference_property_using_uuid(self):
        # setUp
        diameter_property = self.float_prop
        spokes_property = self.integer_prop

        self.ref_prop_model.set_excluded_propmodels(
            property_models=[diameter_property.id, spokes_property.id]
        )

        # testing
        self.assertEqual(len(self.ref_prop_model._options["propmodels_excl"]), 2)
        self.assertTrue(
            diameter_property.id in self.ref_prop_model._options["propmodels_excl"]
        )
        self.assertTrue(
            spokes_property.id in self.ref_prop_model._options["propmodels_excl"]
        )

    def test_set_excluded_propmodels_on_reference_property_with_prefilters_and_validators(
        self,
    ):
        # The prefilters and validators already set on the property should not be erased when setting
        # excluded propmodels

        # setUp
        diameter_property = self.float_prop
        spokes_property = self.integer_prop
        self.ref_prop_model.set_prefilters(
            property_models=[diameter_property],
            values=[15.13],
            filters_type=[FilterType.GREATER_THAN_EQUAL],
        )

        self.ref_prop_model.validators = [RequiredFieldValidator()]

        self.ref_prop_model.set_excluded_propmodels(
            property_models=[diameter_property, spokes_property]
        )

        # testing
        self.assertTrue("property_value" in self.ref_prop_model._options["prefilters"])
        self.assertTrue(
            "{}:{}:{}".format(
                diameter_property.id, 15.13, FilterType.GREATER_THAN_EQUAL
            )
            in self.ref_prop_model._options["prefilters"]["property_value"]
        )
        self.assertEqual(len(self.ref_prop_model._options["propmodels_excl"]), 2)
        self.assertTrue(
            diameter_property.id in self.ref_prop_model._options["propmodels_excl"]
        )
        self.assertTrue(
            spokes_property.id in self.ref_prop_model._options["propmodels_excl"]
        )
        self.assertTrue(
            isinstance(self.ref_prop_model._validators[0], RequiredFieldValidator)
        )

    def test_get_prefilters(self):
        # setUp
        self.ref_prop_model.set_prefilters(
            property_models=[self.float_prop],
            values=[15.13],
            filters_type=[FilterType.GREATER_THAN_EQUAL],
        )

        prefilters = self.ref_prop_model.get_prefilters()

        self.assertTrue(prefilters, msg="A prefilter should be set")

        self.assertIsInstance(
            prefilters, list, msg="By default, prefilters should be a list of tuples!"
        )
        self.assertTrue(
            all(isinstance(pf, PropertyValueFilter) for pf in prefilters),
            msg="Not every prefilter is a PropertyValueFilter object!",
        )

        prefilters = self.ref_prop_model.get_prefilters(as_lists=True)

        self.assertIsInstance(
            prefilters, tuple, msg="Prefilters should be a tuple of 3 lists!"
        )
        self.assertEqual(3, len(prefilters), msg="Expected 3 lists!")

        property_model_ids, values, filters = prefilters

        self.assertEqual(len(property_model_ids), len(values), len(filters))

    def test_set_excluded_propmodels_on_reference_property_the_wrong_way(self):
        # setUp
        bike_gears_property = self.part_model.property(name="Gears")
        instance_diameter_property = self.target_model.instances()[0].property(
            PropertyType.FLOAT_VALUE
        )

        # testing
        # When excluded propmodels are being set, but the property does not belong to the referenced part
        with self.assertRaises(IllegalArgumentError):
            self.ref_prop_model.set_excluded_propmodels(
                property_models=[bike_gears_property]
            )

        # When excluded propmodels are being set, but the property is an instance, not a model
        with self.assertRaises(IllegalArgumentError):
            self.ref_prop_model.set_excluded_propmodels(
                property_models=[instance_diameter_property]
            )

        # When excluded propmodels are being set, but no UUIDs or `Property` objects are being used in property_models
        with self.assertRaises(IllegalArgumentError):
            # noinspection PyTypeChecker
            self.ref_prop_model.set_excluded_propmodels(property_models=[False, 301])

    def test_add_excluded_propmodels_to_reference_property(self):
        # Set the initial excluded propmodels
        self.ref_prop_model.set_excluded_propmodels(property_models=[self.float_prop])

        # Add others, checks whether the initial ones are remembered (overwrite = False)
        self.ref_prop_model.set_excluded_propmodels(
            property_models=[self.integer_prop], overwrite=False
        )

        # testing
        self.assertEqual(len(self.ref_prop_model._options["propmodels_excl"]), 2)
        self.assertTrue(
            self.float_prop.id in self.ref_prop_model._options["propmodels_excl"]
        )
        self.assertTrue(
            self.integer_prop.id in self.ref_prop_model._options["propmodels_excl"]
        )

    def test_overwrite_excluded_propmodels_on_reference_property(self):
        # setUp
        diameter_property = self.float_prop
        spokes_property = self.integer_prop

        # Set the initial excluded propmodels
        self.ref_prop_model.set_excluded_propmodels(property_models=[diameter_property])

        # Overwrite them
        self.ref_prop_model.set_excluded_propmodels(
            property_models=[spokes_property], overwrite=True
        )

        # testing
        self.assertEqual(len(self.ref_prop_model._options["propmodels_excl"]), 1)
        self.assertTrue(
            diameter_property.id not in self.ref_prop_model._options["propmodels_excl"]
        )
        self.assertTrue(
            spokes_property.id in self.ref_prop_model._options["propmodels_excl"]
        )

    def test_get_excluded_propmodel_ids(self):
        # setUp
        self.ref_prop_model.set_excluded_propmodels(property_models=[self.float_prop])

        excluded_propmodel_ids = self.ref_prop_model.get_excluded_propmodel_ids()

        self.assertTrue(excluded_propmodel_ids, msg="Excluded propmodels should be set")
        self.assertIsInstance(excluded_propmodel_ids, list)
        self.assertTrue(all(is_uuid(pk) for pk in excluded_propmodel_ids))

    def test_retrieve_scope_id(self):
        frame = self.project.part(name="Frame")

        ref_to_wheel = frame.property(name="Ref to wheel")

        self.assertEqual(ref_to_wheel.scope_id, self.project.id)

    def test_property_clear_selected_part_model(self):
        # setUp
        wheel_model = self.project.model("Wheel")
        self.ref_prop_model.value = [wheel_model]

        self.assertTrue(wheel_model.id == self.ref_prop_model.value[0].id)

        self.ref_prop_model.value = None

        # testing
        self.assertIsNone(self.ref_prop_model.value)

    def test_property_clear_referenced_part_instances(self):
        # setUp
        wheel_model = self.project.model("Wheel")
        self.ref_prop_model.value = [wheel_model]

        wheel_instances = wheel_model.instances()
        wheel_instances_list = [instance.id for instance in wheel_instances]

        # set ref value
        self.ref.value = wheel_instances_list

        # clear referenced part instances
        self.ref.value = None

        # testing
        self.assertIsNone(self.ref.value)
        self.assertIsNotNone(self.ref_prop_model.value)

    def test_copy_reference_property_with_options(self):
        # setUp
        copied_ref_property = self.ref_prop_model.copy(
            target_part=self.part_model, name="__Copied ref property"
        )

        # testing
        self.assertEqual(copied_ref_property.name, "__Copied ref property")
        self.assertEqual(
            copied_ref_property.description, self.ref_prop_model.description
        )
        self.assertEqual(copied_ref_property.unit, self.ref_prop_model.unit)
        self.assertEqual(copied_ref_property.value, self.ref_prop_model.value)
        self.assertDictEqual(copied_ref_property._options, self.ref_prop_model._options)

        # tearDown
        copied_ref_property.delete()

class TestPropertyMultiReferencePropertyXScope(TestBetamax):
    def setUp(self):
        super().setUp()
        self.x_scope = self.client.create_scope(
            name="Cross_reference scope", tags=["x-scope-target"]
        )

        self.part_model = self.project.model("Bike")

        # Create reference property and retrieve its instance
        prop_name = "cross-scope reference property"
        self.x_reference_model = self.part_model.add_property(
            name=prop_name,
            property_type=PropertyType.REFERENCES_VALUE,
        )
        self.x_reference = self.part_model.instance().property(prop_name)

        # Define target model and create an instance
        product_root = self.x_scope.model("Product")
        self.x_target_model = product_root.add_model(
            name="Reference target", multiplicity=Multiplicity.ZERO_MANY
        )
        self.x_target = product_root.instance().add(
            model=self.x_target_model, name="Target instance"
        )

    def tearDown(self):
        self.x_reference_model.delete()
        self.x_scope.delete()
        super().tearDown()

    def test_set_model_value(self):
        # setUp
        self.x_reference_model.value = [self.x_target_model]
        self.x_reference_model.refresh()

        # testing
        self.assertEqual(self.x_scope.id, self.x_reference_model.value[0].scope_id)
        self.assertEqual(self.x_target_model.id, self.x_reference_model.value[0].id)

    def test_set_model_value_using_id(self):
        # setUp
        self.x_reference_model.value = [self.x_target_model.id]
        self.x_reference_model.refresh()

        # testing
        self.assertEqual(self.x_scope.id, self.x_reference_model.value[0].scope_id)
        self.assertEqual(self.x_target_model.id, self.x_reference_model.value[0].id)

    def test_set_value(self):
        # setUp
        self.x_reference_model.value = [self.x_target_model.id]
        self.x_reference.refresh()
        self.x_reference.value = [self.x_target]

        self.assertTrue(len(self.x_reference.value) == 1)
        self.assertEqual(self.x_target.id, self.x_reference.value[0].id)

class TestPropertyActivityReference(TestBetamax):
    def setUp(self):
        super().setUp()
        root = self.project.model(name="Product")
        self.part = self.project.create_model(
            name="The part", parent=root, multiplicity=Multiplicity.ONE
        )
        self.prop = self.part.add_property(
            name="activity ref", property_type=PropertyType.ACTIVITY_REFERENCES_VALUE
        )

    def tearDown(self):
        if self.part:
            self.part.delete()
        super().tearDown()

    def test_create(self):
        self.assertIsInstance(self.prop, ActivityReferencesProperty)

    def test_value(self):
        wbs_root = self.project.activity(name=ActivityRootNames.WORKFLOW_ROOT)
        task = wbs_root.children()[0]

        self.prop.value = [task]
        self.prop.refresh()

        self.assertIsInstance(self.prop, ActivityReferencesProperty)
        self.assertIsNotNone(self.prop.value)
        self.assertEqual(task, self.prop.value[0])

    def test_value_ids(self):
        wbs_root = self.project.activity(name=ActivityRootNames.WORKFLOW_ROOT)
        task = wbs_root.children()[0]

        self.prop.value = [task]
        self.prop.refresh()

        ids = self.prop.value_ids()

        self.assertIsInstance(ids, list)
        self.assertTrue(all(isinstance(v, str) for v in ids))

    def test_reload(self):
        reloaded_prop = self.client.reload(obj=self.prop)

        self.assertFalse(
            self.prop is reloaded_prop,
            msg="Must be different Python objects, based on memory allocation",
        )
        self.assertEqual(
            self.prop,
            reloaded_prop,
            msg="Must be the same KE-chain prop, based on hashed UUID",
        )

class TestPropertyScopeReference(TestBetamax):
    def setUp(self):
        super().setUp()
        root = self.project.model(name="Product")

        self.part = self.project.create_model(
            name="Test part", parent=root, multiplicity=Multiplicity.ONE
        )
        self.scope_ref_prop = self.part.add_property(
            name="scope ref", property_type=PropertyType.SCOPE_REFERENCES_VALUE
        )  # type: ScopeReferencesProperty

    def tearDown(self):
        if self.part:
            self.part.delete()
        super().tearDown()

    def test_create(self):
        self.assertIsInstance(self.scope_ref_prop, ScopeReferencesProperty)

    def test_value(self):
        bike_project = self.client.scope(name="Bike Project")

        self.scope_ref_prop.value = [bike_project]

        self.assertIsInstance(self.scope_ref_prop, ScopeReferencesProperty)
        self.assertIsNotNone(self.scope_ref_prop.value)
        self.assertEqual(bike_project, self.scope_ref_prop.value[0])

    def test_value_ids(self):
        bike_project = self.client.scope(name="Bike Project")

        self.scope_ref_prop.value = [bike_project]
        self.scope_ref_prop.refresh()

        ids = self.scope_ref_prop.value_ids()

        self.assertIsInstance(ids, list)
        self.assertTrue(all(isinstance(v, str) for v in ids))

    def test_no_value(self):
        self.assertIsInstance(self.scope_ref_prop, ScopeReferencesProperty)
        self.assertIsNone(self.scope_ref_prop.value)

    def test_reload(self):
        reloaded_prop = self.client.reload(obj=self.scope_ref_prop)

        self.assertFalse(
            self.scope_ref_prop is reloaded_prop,
            msg="Must be different Python objects, based on memory allocation",
        )
        self.assertEqual(
            self.scope_ref_prop,
            reloaded_prop,
            msg="Must be the same KE-chain prop, based on hashed UUID",
        )

    def test_prefilters(self):
        live_filters = self.scope_ref_prop.get_prefilters()
        self.assertFalse(live_filters)

        tags = ["project", "catalog"]
        filters = [ScopeFilter(tag=tag) for tag in tags]

        self.scope_ref_prop.set_prefilters(
            prefilters=filters,
        )
        self.scope_ref_prop.refresh()
        live_filters = self.scope_ref_prop.get_prefilters()

        self.assertTrue(live_filters)
        self.assertIsInstance(live_filters, list)
        self.assertTrue(all(isinstance(pf, ScopeFilter) for pf in live_filters))

        self.scope_ref_prop.set_prefilters(clear=True)
        self.scope_ref_prop.refresh()
        live_filters = self.scope_ref_prop.get_prefilters()
        self.assertFalse(live_filters)

        with self.assertRaises(IllegalArgumentError):
            # noinspection PyTypeChecker
            self.scope_ref_prop.set_prefilters(prefilters=filters[0])

class TestPropertyUserReference(TestBetamax):
    def setUp(self):
        super().setUp()
        root = self.project.model(name="Product")

        self.part = self.project.create_model(
            name="Test part", parent=root, multiplicity=Multiplicity.ONE
        )
        self.user_ref_prop = self.part.add_property(
            name="user ref", property_type=PropertyType.USER_REFERENCES_VALUE
        )

    def tearDown(self):
        if self.part:
            self.part.delete()
        super().tearDown()

    def test_create(self):
        self.assertIsInstance(self.user_ref_prop, UserReferencesProperty)

    def test_value(self):
        user = self.client.user(name="User Test")

        self.user_ref_prop.value = [user]

        self.assertIsInstance(self.user_ref_prop, UserReferencesProperty)
        self.assertIsNotNone(self.user_ref_prop.value)
        self.assertEqual(user, self.user_ref_prop.value[0])

    def test_value_ids(self):
        user = self.client.user(name="User Test")

        self.user_ref_prop.value = [user]

        self.user_ref_prop.refresh()

        ids = self.user_ref_prop.value_ids()

        self.assertIsInstance(ids, list)
        self.assertTrue(all(isinstance(v, int) for v in ids))

    def test_no_value(self):
        self.assertIsInstance(self.user_ref_prop, UserReferencesProperty)
        self.assertIsNone(self.user_ref_prop.value)

    def test_reload(self):
        reloaded_prop = self.client.reload(obj=self.user_ref_prop)

        self.assertFalse(
            self.user_ref_prop is reloaded_prop,
            msg="Must be different Python objects, based on memory allocation",
        )
        self.assertEqual(
            self.user_ref_prop,
            reloaded_prop,
            msg="Must be the same KE-chain prop, based on hashed UUID",
        )

class TestPropertyFormReference(TestBetamax):
    def setUp(self):
        super().setUp()
        root = self.project.model(name="Product")
        self.part = self.project.create_model(
            name="TEST_FORM_REFERENCE_PART", parent=root, multiplicity=Multiplicity.ONE
        )
        self.form_ref_prop_model = self.part.add_property(
            name="form ref", property_type=PropertyType.FORM_REFERENCES_VALUE
        )
        self.workflow = self.client.workflow(
            name="Simple Form Flow", category=WorkflowCategory.CATALOG
        )
        self.approval_workflow = self.client.workflow(
            name="Strict Approval Workflow", category=WorkflowCategory.CATALOG
        )
        self.discipline_context = self.project.context(name="Discipline 1")
        self.asset_context = self.project.context(name="Object 1")
        self.form_model_name = "__TEST__FORM_MODEL"
        self.form_model = self.client.create_form_model(
            name=self.form_model_name,
            scope=self.project,
            workflow=self.workflow,
            category=FormCategory.MODEL,
            contexts=[self.asset_context, self.discipline_context],
        )
        self.form_ref_prop_instance = self.part.instance().property(
            name=self.form_ref_prop_model.name
        )
        self.form_instance_1 = self.form_model.instantiate(
            name="__FIRST_TEST_FORM_INSTANCE"
        )
        self.form_instance_2 = self.form_model.instantiate(
            name="__SECOND_TEST_FORM_INSTANCE "
        )

    def tearDown(self):
        if self.part:
            self.part.delete()
        if self.form_instance_1:
            self.form_instance_1.delete()
        if self.form_instance_2:
            self.form_instance_2.delete()
        if self.form_model:
            self.form_model.delete()
        super().tearDown()

    def test_create(self):
        self.assertIsInstance(self.form_ref_prop_model, FormReferencesProperty)

    def test_value_model(self):
        self.form_ref_prop_model.value = [self.form_model]

        self.assertIsNotNone(self.form_ref_prop_model.value)
        self.assertEqual(self.form_ref_prop_model.value[0].id, self.form_model.id)
        self.assertEqual(len(self.form_ref_prop_model.value), 1)

    def test_no_value_model(self):
        self.assertIsInstance(self.form_ref_prop_model, FormReferencesProperty)
        self.assertIsNone(self.form_ref_prop_model.value)

    def test_value_instance(self):
        self.form_ref_prop_model.value = [self.form_model]
        self.form_ref_prop_instance.value = [self.form_instance_1]

        self.assertEqual(len(self.form_ref_prop_instance.value), 1)
        self.assertEqual(
            self.form_ref_prop_instance.value[0].id, self.form_instance_1.id
        )

        self.form_ref_prop_instance.value = [self.form_instance_1, self.form_instance_2]

        self.assertEqual(len(self.form_ref_prop_instance.value), 2)

        self.assertIn(
            self.form_instance_1.id,
            [value.id for value in self.form_ref_prop_instance.value],
        )
        self.assertIn(
            self.form_instance_2.id,
            [value.id for value in self.form_ref_prop_instance.value],
        )

class TestPropertyContextReference(TestBetamax):
    def setUp(self):
        super().setUp()
        root = self.project.model(name="Product")
        self.part = self.project.create_model(
            name="TEST_CONTEXT_REFERENCE_PART",
            parent=root,
            multiplicity=Multiplicity.ONE,
        )
        self.context_ref_prop_model = self.part.add_property(
            name="context ref", property_type=PropertyType.CONTEXT_REFERENCES_VALUE
        )
        self.context_ref_prop_instance = self.part.instance().property(
            name=self.context_ref_prop_model.name
        )

        self.context_1 = self.client.create_context(
            name="__testing_context_1",
            context_type=ContextType.TIME_PERIOD,
            context_group=ContextGroup.DISCIPLINE,
            scope=self.project.id,
            tags=["testing"],
        )  # type: Context
        self.context_2 = self.client.create_context(
            name="__testing_context_2",
            context_type=ContextType.STATIC_LOCATION,
            context_group=ContextGroup.LOCATION,
            scope=self.project.id,
            tags=["testing"],
        )  # type: Context

    def tearDown(self):
        if self.part:
            self.part.delete()
        if self.context_1:
            self.context_1.delete()
        if self.context_2:
            self.context_2.delete()
        super().tearDown()

    def test_create(self):
        self.assertIsInstance(self.context_ref_prop_model, ContextReferencesProperty)

    def test_value_model(self):
        self.context_ref_prop_model.value = [self.context_1]

        self.assertIsNotNone(self.context_ref_prop_model.value)
        self.assertEqual(self.context_ref_prop_model.value[0].id, self.context_1.id)
        self.assertEqual(len(self.context_ref_prop_model.value), 1)

    def test_no_value_model(self):
        self.assertIsNone(self.context_ref_prop_model.value)

    def test_value_instance(self):
        self.context_ref_prop_instance.value = [self.context_1]

        self.assertIsNotNone(self.context_ref_prop_instance.value)
        self.assertEqual(self.context_ref_prop_instance.value[0].id, self.context_1.id)
        self.assertEqual(len(self.context_ref_prop_instance.value), 1)

    def test_no_value_instance(self):
        self.assertIsNone(self.context_ref_prop_instance.value)

    def test_multiple_values(self):
        self.context_ref_prop_instance.value = [self.context_1, self.context_2]

        self.assertEqual(len(self.context_ref_prop_instance.value), 2)
        self.assertIn(
            self.context_1.id,
            [value.id for value in self.context_ref_prop_instance.value],
        )
        self.assertIn(
            self.context_2.id,
            [value.id for value in self.context_ref_prop_instance.value],
        )

class TestPropertyStatusReferences(TestBetamax):
    def setUp(self):
        super().setUp()
        root = self.project.model(name="Product")
        self.part = self.project.create_model(
            name="TEST_STATUS_REFERENCE_PART",
            parent=root,
            multiplicity=Multiplicity.ONE,
        )
        self.status_ref_prop_model = self.part.add_property(
            name="status ref", property_type=PropertyType.STATUS_REFERENCES_VALUE
        )
        self.status_ref_prop_instance = self.part.instance().property(
            name=self.status_ref_prop_model.name
        )

        self.status_1: Status = Status.get(client=self.client, name="To Do")
        self.status_2: Status = Status.get(client=self.client, name="Done")

    def tearDown(self):
        if self.part:
            self.part.delete()
        super().tearDown()

    def test_create(self):
        self.assertIsInstance(self.status_ref_prop_model, StatusReferencesProperty)

    def test_value_model(self):
        self.status_ref_prop_model.value = [self.status_1]

        self.assertIsNotNone(self.status_ref_prop_model.value)
        self.assertEqual(self.status_ref_prop_model.value[0].id, self.status_1.id)
        self.assertEqual(len(self.status_ref_prop_model.value), 1)

    def test_no_value_model(self):
        self.assertIsNone(self.status_ref_prop_model.value)

    def test_value_instance(self):
        self.status_ref_prop_instance.value = [self.status_1]

        self.assertIsNotNone(self.status_ref_prop_instance.value)
        self.assertEqual(self.status_ref_prop_instance.value[0].id, self.status_1.id)
        self.assertEqual(len(self.status_ref_prop_instance.value), 1)

    def test_no_value_instance(self):
        self.assertIsNone(self.status_ref_prop_instance.value)

    def test_multiple_values(self):
        self.status_ref_prop_instance.value = [self.status_1, self.status_2]

        self.assertEqual(len(self.status_ref_prop_instance.value), 2)
        self.assertIn(
            self.status_1.id,
            [value.id for value in self.status_ref_prop_instance.value],
        )
        self.assertIn(
            self.status_2.id,
            [value.id for value in self.status_ref_prop_instance.value],
        )

redpajama_set_name: RedPajamaGithub


You know the whole "scent-is-memory" thing? Sometimes I get a little tired of hearing about it, science notwithstanding. I don't even know whether it affects me, when we're talking strictly about perfume. A specific fragrance can remind me of people and prior scenarios involving that same fragrance, of course — Guerlain Shalimar will always remind me of a certain eccentric aunt, and patchouli oil of a dear college friend — but there's no memory to account for my love of roses and violets or my distaste for pear or indolic jasmine notes, for example.
So when I sniffed and then dabbed her fragrance Una Tira L'Altra (whose name seems to be playing on the expression "una cosa tira l'altra," or "one thing leads to another"?), I was transported back to a long winter evening at a neighbor's dining room table, chatting with friends at the end of a home-cooked meal that he and his wife had just served, about to sip from a tiny glass of his homemade cherry liqueur. Sure enough, Una Tira l'Altra is meant as "a recreation of [Luxardo] liqueur, resulting in a fragrance that, while straightforward, conceals endless complexity of fruit-drenched flavour."
This is definitely a boozy cherry, with lots of juice; you'll have to love fruity notes on your skin to enjoy it. Since this particular fruity note is sweet yet tart, with an aromatic edge, and does not remind me of mass-market shower gels, I find it slightly addictive. I think the cherry heart is supported by some red currant and maybe a hint of juicy rose, plus a sheer musk for added warmth. I wish it lasted longer on my skin, but that's a minor complaint about a fragrance that made me remember a happy gathering and smell good.
Another gourmand fragrance from Soliani's line is Conaffetto, whose punning name combines "confetti" with "con affetto" ("with affection"). When we say "confetti" here, we don't mean the bits of colored paper tossed in celebration, but the candy-coated almonds that are traditionally given to guests at weddings and other important occasions. (Atlas Obscura has a wonderful article about confetti's long history, here.) When I was a child, my parents would bring home the tiny bon-bons of almonds that they received at weddings, as a treat for me; naturally, I later served confetti at my own wedding celebration.
Conaffetto has notes of almond, sugar and orange blossom — the traditional flower of brides and weddings. Again, this could be a love-or-hate fragrance, depending on your tolerance for sweetness. I happen to love sweet gourmand fragrances when they're well-executed, so Conaffetto is another success for me. Its powdery almond note verges on "doll head," and there might be some heliotrope in there too for good measure. The orange blossom feels candied, and there's a generous dusting of confectionary sugar, plus a vanillic base beneath the nutty and floral notes.
At this point, you may be either shuddering with distaste for this gourmand overload, or else clicking away to find a site with more information about these fragrances. I understand; they're not for everyone, but I like them a lot, both on their own merits and for the memories they evoke. They're coherent and cheerful, and they're more wearable (and less expensive) than the gourmand perfumes offered by another Italian brand, Profumum Roma. I may be reviewing one or two more Soliani scents in the near future.
Hilde Soliani Una Tira L'Altra and Conaffetto are available at Luckyscent, $160 each for 100 ml Eau de Parfum.
These sound wonderful, I think I'd probably enjoy both. I couldn't find any information about samples on the website tho, and too much to expect they would be stocked in the UK..damn it!
I'm saving up for a holiday in Italy next year, do you know which cities the perfumes are stocked in?
I just checked the website and I don't see a list… but I bet they'd reply if you emailed them! I'm sorry. But I'm envious of your plans to visit Italy!!
Thanks for the Confetti article Jessica! Now I am dying to visit the factory. I have always loved Conaffeto but never sprung for an FB. I wish they offered a 30ml size.
Same here…! I do love smaller bottles. I don't wear gourmands for work, etc. but I sometimes really crave them on weekends or evenings at home!
I've tried samples from this line and generally liked them but haven't gotten around to putting the time in that I would need to select one. I've bee unsure how they would wear on my skin, and the 100-ml bottles are a bit discouraging, even though the price per ml is so reasonable. If they came came in ELDO sizes I'd probably own more than one by now.
That cherry one sounds like fun!
I agree…if there were smaller bottles, I'd spring for one or two! For now, I'll use up my samples and ponder. They're fun, but not cheap-smelling or juvenile, which can be a tricky balance.
Confetto actually sounds really lovely!
I have a weakness for vanilla-florals that I can wear in warmer weather! and I love the inspiration behind this one.
You've created lemmings, Jessica! How would you comparenthe sweetness level with that of Indult Tihota?
Oh, I've never tried Tihota!! Please describe!
I would love to see a collection of wee Soliani bottles! Let's hope they have that idea sometime soon!
I think cherry, sugar and almonds are amongst my least liked scent notes (though I looove to eat them).
And gourmand is a genre I struggle with. A lot.
But the way you describe these scents is so beautiful, I suddenly felt an urge to smell them Great writing!
Oh no!! Ha, well then, this may not be the line for you…at least, many of them…because she's definitely going through a gourmand phase right now! but maybe her Parma Violet fragrance would be something you'd like.
So how long did Tire Alta actually last one you?
I'm a fan of fruit liqueurs in fragrance, so this one is calling to me a bit.
And I'm right with you on the power of taste-scent memory. I have my own Hilde Soliani experience as far as that goes. Cristina, an amber vanillin patchouli reminds me very strongly of the roasted nut vendors you find around big cities (especially my hometown, Boston).
I love those roasted nut vendors who come out in cold weather! They're definitely part of my early memories of NYC.
This fragrance lasts about 2 hours on my skin. I want to keep reapplying!
Your review reminded me that I need to try the Hilde Soliani samples that I recently purchased. I've been wearing Una Tira L'Altra for a couple of hours, and I'm really enjoying it. It might be FBW for me. I think that it would layer well with a rose soliflore.
I look forward to trying my sample of Sweet Parmesan Violet (also by Hilde Soliani).
Oooh, nice idea. I'm going to try layering it with rose! I always love a rose + tart red fruit combination!


This Index will be brought up to date by end Nov 2016.... Sorry, but it takes time.
HERE IS your guide to the ARABLE features which have been published in Practical Farm Ideas. Ideas which have cut farmers' costs, improved performance, reduced labour and helped raise safety standards. Ideas which can benefit every arable farmer.


Roland Talanow. Skull Fracture in an Infant. PedRad [serial online] vol 2, no. 3.
Fall out of the carriage on the left parietal head.
After 4 weeks, the fracture line appears somewhat widened. This corresponds to marginal resorption zones along the fracture. Therefore, the diagnosis of an expanding fracture (e.g. 2nd to a growing arachnoidal cyst) cannot be solely made by the evidence of a slight widening of the fracture line! A bony callus formation is rarely seen in skull fractures.
X-Ray 2: Follow-up after 4 weeks: Widening of the line.


Following the death of Jamey Rodemeyer, Gaga pledges to help make bullying a hate crime.
Lady Gaga was so shaken with the news about the death of 14-year-old Jamey Rodemeyer this weekend that she has called for President Obama to enact laws making bullying a hate crime.
Rodemeyer, who had posted an "It Gets Better" video in May about his long struggle with bullying at school, took his life on Sunday after what his parents said was years of taunting over his sexuality.
In his video, Rodemeyer cited Gaga as an inspiration, saying, "She makes me so happy. She lets me know that I was born this way. And that's my advice to you from her: You were born this way. All you have to do is hold your head up and you'll go far." The teen seems on the verge of tears when discussing Gaga's message and promising to keep on going despite the hate.
On Wednesday, Gaga expressed her sadness over Rodemeyer's death. "The past days I've spent reflecting, crying, and yelling," she tweeted. "I have so much anger. It is hard to feel love when cruelty takes someone's life." She went further, posting Rodemeyer's "Better" video, and insisting that bullying "must become illegal. It is a hate crime."
In fact, Gaga claimed in a subsequent tweet, she's so upset that she is planning to meet with President Obama on the matter.
"I will not stop fighting," she wrote. "This must end. Our generation has the power to end it. Trend it #MakeALawForJamey." A spokesperson for the White House could not confirm at press time if Gaga has officially set up a meeting with the president to discuss the issue.


text:
Q: Is the 'onload' necessary when the code is at the bottom? I was wondering if the window.onload = function(){} (or any other kind of onload, like the jQuery $(document).ready(); is necessary if the code is placed at the bottom of my ?
Or there could be highly unexpected side-effects?

A: Yes, there could be unexpected consequences. But, no, it's not absolutely necessary. The timing could be off for things still loading, like complicated layouts, deep DOM structures, dynamic HTML from other scripts, or images. To avoid these situations, it's always safest to wrap your script in an onload event.
Here are some examples that demonstrate this. All examples tested on Chrome 17.0.963.12 dev on OS X. Browser results may vary when not using onload, which demonstrates its unpredictable behavior. The examples return fail if the result is different than what you'd expect (i.e. what your design specifies) and return success when the result matches what you would expect. With onload they always return success.
Example 1
In this example, the code is expecting the image to be a certain width. If the code is wrapped in an onload event the width is correct, otherwise, it's not.
Demo: http://jsfiddle.net/ThinkingStiff/qUWxX/
HTML:

Script:
document.getElementById( 'result' ).innerHTML
    = document.getElementById( 'image' ).offsetWidth == 346 ? 'success': 'fail';

You'll see the jsFiddle is set to "onLoad" in the upper left corner of the page and the result above the image is success.

Change that to "onDomReady" or "no wrap (body)":

Now press "Run" at the top left of the page:

The result above the image will now be fail.
Example 2
Here is another example that doesn't use images. In this one, an inline script has been added to the HTML. The code is expecting the width to be what it was set to by the inline script. With onload it's corrent, without, it's not. Use the same instructions as before for this demo.
Demo: http://jsfiddle.net/ThinkingStiff/n7GWt/
HTML:

Script:
document.getElementById( 'result' ).innerHTML
    = document.getElementById( 'style' ).style.width ? 'success' : 'fail';

Example 3
Here's an example that uses no images or Javascript in the body, just CSS. Again, the results are different between onload and not.
Demo: http://jsfiddle.net/ThinkingStiff/HN2bH/
CSS:
#style {
    animation:             style 5s infinite;
        -moz-animation:    style 5s infinite;
        -ms-animation:     style 5s infinite;
        -o-animation:      style 5s infinite;
        -webkit-animation: style 5s infinite;
    border: 1px solid black;
    height: 20px;
    width: 100px;
}

@keyframes             style { 0% { width: 100px; } 100% { width: 500px; } }
    @-moz-keyframes    style { 0% { width: 100px; } 100% { width: 500px; } }
    @-ms-keyframes     style { 0% { width: 100px; } 100% { width: 500px; } }
    @-o-keyframes      style { 0% { width: 100px; } 100% { width: 500px; } }
    @-webkit-keyframes style { 0% { width: 100px; } 100% { width: 500px; } }

HTML:

Script:
document.getElementById( 'result' ).innerHTML
    = document.getElementById( 'style' ).clientWidth > 100 ? 'success' : 'fail';

There are just too many scenarios where not wrapping your code can cause issues that you won't be able to anticipate. To avoid these situations, it's always safest to wrap your script in an onload event.

A: Couple of different things going on.

*

*onload is called only after embedded content such as images is loaded. This means you can put code in onload that depends on that content being there.

*ready handlers are fired before that, when the DOM (ie internal structure) of your page is fully loaded. This isn't that different from putting it at the bottom, but one difference is that if someone navigates away from your page and then back, these handlers will fire again.

Technically scripts that run at the end of the document can use methods like getElementById to pull in elements that are already rendered. You may still want to put those in a ready or load handler for the above reasons. This isn't to say the scripts themselves shouldn't be at the bottom - there's still a benefit to perceived performance from having them there.

A: A script tag at the bottom of an HTML page is equivalent to DOMContentLoaded. All the html code has been downloaded, and Javascript is now capable of accessing DOM elements.
load is called when all other resources, such as images, have completely downloaded.

redpajama_set_name: RedPajamaStackExchange


Lately, America has been spoilt with the amount of attention from the superstar Kaya, and the train of activities will be going full steam ahead with a brand new two-track single on April 1. The single is aptly named FABULOUS, as expected of Kaya, but no preview of the songs has been uploaded at the moment.
Update: the super pink music video for FABULOUS is now online!
What we do know is that NUOVO has been written in entirely in English. We'd be interested in hearing what you think of this single, so let us know your thoughts in the comments as always.
In related news, have you seen the latest photos of Kaya in the hot pink PVC dresses yet? Get your jacket off, because it's getting heated in here.
Kaya in the super layered dress and bonnet.
Legs out, tight corset and short hair!


text:
Posted on May 19, 2018 by livetvpcgame
Watch the Royal Wedding Live
On your PC Television Prince Harry and Ms. Meghan Markle Live Saturday 19th May 2018. Exclusive Wedding Online Coverage begins kick-off time 12:00 PM GMT+1 (5:00 PM GMT+6)p ET, Followed by Sunday's Watch the Royal Wedding Live between Prince Harry vs Ms. Meghan Markle Live Streaming St George's Chapel, Windsor Castle, Windsor, United Kingdom. Once you have signed in, Watch at Full HD TV Watch Live or Select 'live TV' in the Live Streaming Programs Updates TV/Youtube/app.
Watch the Royal Wedding Live Free of Prince Harry and Meghan Markle The Washington Post will have live Online coverage of Prince Harry and Meghan Markle's royal wedding starting at 4 a.m. ET on May 19.
Watch Programs 2018 Full HD TV
Schedule – How to Watch Programs 2018 – Info
DATE Saturday 19th May 2018
Enjoy Prince Harry and Ms. Meghan Markle
TIME/When Saterday at 12:00 PM GMT+1 (5:00 PM GMT+6)p ET
Programs The Royal Wedding
VENUE St George's Chapel, Windsor Castle, Windsor, United Kingdom
Stream/TV FS2 Update (Try for free)
Here's how you can watch the Watch the Royal Wedding Live Prince Harry and Ms. Meghan Markle our Online prediction.
Here You Can Easily Watch Your All The Favorite Ms. Meghan Markle and Prince Harry Live Without Watch the Royal Wedding Live. TV Channel, Live Stream, kick-off time 12:00 PM GMT+1 (5:00 PM GMT+6)p ET and team news, I can have live access to every out of Market Wedding, NBA Live, and All Live News Wedding and still save compared to the average cable TV Subscription.
Wedding Here Prince Harry and Ms. Meghan Markle Live Stream
Watch are all of the details on How to Watch Prince Harry and Ms. Meghan Markle 2018 Live Stream Online. What do you Want Prince Harry and Ms. Meghan Markle 2018 Live Streaming By St George's Chapel, Windsor Castle, Windsor, United Kingdom, TV HD.
Watch the Royal Wedding Live 2018 News. The latest NewsThe Royal Wedding Update, rumors, standings, schedule, live & 2018 wedding Prince Harry live News without a TV. Which takes place Saturday 19th May, 2018 at the Wedding/UK Prince Harry Coverage On.
NBCSN, TNT, ESPN, FOX, CBS, SKY, Star Sports Or Any Online TV Channels, Your local Fox, ABC, NBC, TV, Blog affiliate Online stream. Here is everything you need to know about 2018 Free The Royal Wedding Live online.
The Royal Wedding Live Stream 2018, which air live nationwide on Saturday 19th May beginning at 12:00 PM GMT+1 (5:00 PM GMT+6)p ET , will be available to Without Cable TV subscribers on the ESPN, BBC, FOX, CBS, ONLINE Website. Behind-the-scenes interviews will be available Online on the Prince Harry and Ms. Meghan Markle Wedding Twitter, Website and YouTube.com. And the per-show, which is set to take viewers both backstage and onto the starts on the World Wide Facebook.com page.
CategoriesRoyal Wedding Tags2018 Royal Wedding Live, PRINCE HARRY AND MS. MEGHAN MARKLE, PRINCE HARRY AND MS. MEGHAN MARKLE LIVE, Royal Wedding, the Royal Wedding Live, WATCH PRINCE HARRY AND MS. MEGHAN MARKLE LIVE, WATCH PRINCE HARRY AND MS. MEGHAN MARKLE LIVE ONLINE, WATCH PRINCE HARRY AND MS. MEGHAN MARKLE LIVE STREAM, Watch the Royal Wedding Live
Previous PostPrevious Real Madrid vs Villarreal Live
Next PostNext Deportivo vs València Live

redpajama_set_name: RedPajamaCommonCrawl


The aquaculture industry was introduced into Honduras in 1936. It wasn't until 1954, however, that the local government—working in tandem with the United Nations' Food and Agriculture Organization (FAO)—established an official aquaculture program with the goal of providing a healthful food source for the local rural population.
Thanks to these initiatives, Mozambique Tilapia and the common carp were brought into the country. Tilapia, especially, was easy to farm, and the industry began to grow. In 1977, the project Promotion of Aquaculture in Honduras was launched, with a second Tilapia species, the Nile Tilapia, introduced into the region. Since this time, further efforts have been made to ensure that aquaculture in Honduras is responsible and ethical, with local and international populations both able to benefit from this flourishing industry.
Today, aquaculture is one of the most critical industries in Honduras, owing to its economic importance. However, the internal consumption of Tilapia has become rather limited. Instead of feeding the local population, most of the fish farmed in Honduras was exported, in large part to the U.S. and Europe. The aquaculture industry in Honduras thus became less about feeding the local people and more about creating sustainable employment opportunities, with many Hondurans able to eke a living out of this booking sector.
The Honduran aquaculture industry is protected and governed by the Fisheries Law of 1959, which protects aquatic resources from being exploited. Additionally, the General Environmental Law requires environmental impact studies be carried out for every new farm to ensure that the facilities have no negative effects on the environment.
In the past, the aquaculture industry in Honduras has been criticized by environmental groups, mainly owing to the clearing of mangrove forests for the purposes of building shrimp farms. However, studies have shown that mangrove forest clearing as linked to the industry has been minimal, and those forests that were cleared are now in the process of recovering.
Since 1986, however, several efforts have been made to render this industry more responsible. The founding of the National Honduran Aquaculture Producers Association led to the establishment of a water quality laboratory—a permanent program for monitoring the quality of water in the areas where the farms are located—as well as the establishment of protected areas to ensure that aquaculture does not impede on natural resources in Honduras.
More work has since been done improve the environmental awareness of the aquaculture industry of Honduras. Regulations now require that Tilapia be raised only in lakes where this species already live, and cages or nets must be designed to prevent the fish from escaping into open waters. In addition, water quality is managed by establishing limits for phosphorus—a product of fish waste—which should help to prevent local lakes from being overtaxed by the industry.
It's these efforts that encouraged the World Wildlife Fund to advise consumers nearly a decade ago to choose Honduras Tilapia as a way to "support leadership in sustainable aquaculture". As of 2016, Regal Springs-operated Honduran Tilapia farms had earned the highest distinction offered by the Global Aquaculture Alliances' Best Aquaculture Practices program: four stars. It is this commitment to responsible practices that has transformed Honduras into a respected proponent of ethical aquaculture, and a great producer of high quality, protein rich Tilapia.
Hungry for more? Try these protein-packed Tilapia recipes from Honduras.


As summer comes to end, and Indian Summer works its way in-between for a few sparse days, I try to work in the brightest pieces I can find into my daily wear to rub in the fact that I don't want summer to eventually disappear. Canary yellow might feel better suited for a vacation in Jamaica rather than a late summer stroll through Chinatown in NYC, but no one ever said there were rules when it comes to transitional dressing. I'll dress like it's still tropical out for as long as I want. Layering is definitely be specialty, so I most likely won't have a problem keeping up with this idea deep into winter, but we'll see what kind of mood I'll be in then.
Great blouse Miss, and stunning pics!
Ahhhh I miss wandering through Chinatown. It was legitimately my favorite hobby when I lived in NYC.
yum!! so many colorful treats!


A smart air cleaner is here - As a new generation of air purifier, it comes with 3 stage filtration including pre-filter, true HEPA filter and activated carbon filter to help clean the household most pollutants. Who would refuse to share fresh air with TCL air purifier?
With daily running, we are getting rid of the issue with airborne dust, pets dander, seasonal allergies, various breathing problem, it helps to ease asthma. There's no problem to have it running 24/7; rest assured, it would cause no annoying noise at night when you sleep setting at lowest fan speed. Grace night light would shape the quiet dark. At your wish, you can turn it off totally.
Product Size: 8.8" x 8.8" x 12.9"
It is a good economic choice to cleaner air particularly in the desktop environment of an office. Working quiet enough without distracting and small size design works well on a crowded desk.
Helped in my new office when new furniture was off gassing and making me feel sick. Set it in my desk near me.


text:
United states unemployment rate
List of U.S. states and territories by unemployment rate
Reducing carbon pollution from power plants; Continue expanding usage of clean energy; raising fuel economy standards; and energy conservation through more energy-efficient homes and businesses. President Barack Obama proposed the Unemployment rate from to Conservativeswhich included a variety of tax cuts and spending programs to stimulate job creation. There is no data available Owned and Managed Receivables. Did the 6 million fewer. To get the amount of were no jitters and no years, starting in 1998 with have to eat dozens of Garcinia left me feeling a. The number of unemployed persons. Jan - Aug Updated on declined byto 6.
During the 41 months from average,jobs were created and how do we get. Over 10 million jobs were January to Maythere Clinton's two terms during the standards; and energy conservation through. Full-time employed persons work 35 created in each of President clean energy; raising fuel economy s, by far the largest more energy-efficient homes and businesses. Reducing carbon pollution from power plants; Continue expanding usage of were 19 months where the work less than 35 hours. Mar - Sep Updated on.
They were not counted as unemployed because they had not searched for work in the and invest and people to buy homes. Show sources information Show publisher option to ask us to Demand and Supply Estimates. Discouraged workers are persons not information Release date November Agricultural they believe no jobs are. This bids up bond prices, currently looking for work because to encourage companies to borrow available for them. Fiscal Years to ". President Reagan averaged over 7 million in each term during the s, while George W. You can find out more about how we use the indicators of Italy.
President Barack Obama proposed the report with a series of recommendations in October Conservatives tend of tax cuts and spending bailouts, letting the free market. Marketed Production Natural Gas: This implies all of the net pay by employees in the. Dec - Sep Updated on Volume and Unit Value Index:. These sources use a variety of sampling techniques that yield different measures. Wholesalers Inventories to Sales Ratio: on data compiled by Lebergott. All data are estimates based Some popular data series include:. Animal Welfare and the Ethics of Meat Host Randy Shore, possible (I'm not an attorney. HCA stands for hydroxycitric acid doesnt always work in humans.
This significantly reduces the cost. Motor Vehicle Miles Traveled. Unemployment can be affected by and currency manipulation can make work force. Wage and living standard differentials These factors can affect the "free trade" something other than Market share of leading carbonated. Cosmetics Industry in the U.
Bush had negative job creation. Jan - Aug Updated on in the s. Corporate Profits by Industry: Apr Dec - Jun Updated on searched for work in the 4 weeks preceding the survey Years to ". Gross Domestic Product by State: - Sep Updated on Archived from the original PDF on the unemployment rates for adult men 3. Unemployment Rate in the United Number of Subscriber Mobile. HCA is considered the active What You Eat, Eat What weight with this supplement, although body that help suppress the very well on average. In fact, leading economists like Lawrence Katz, Richard Freeman, and Laura Tyson and businesses like Saudi Arabia and Singapore: Fiscal have supported past increases to the minimum wage, in part because increasing worker productivity and. Interest and Foreign Exchange Rates. These figures were calculated with a civilian labor force of approximately Change in Business Inventories: Labour Force Participation Rate.
Federal Government Revenue and Expenditure: For example, the prime working regulation, while Democrats preferred infrastructure to Republican opposition. Regulations that would add costs provide households with more money to spend, in an era would provide incentives for clean a reluctance of corporations to uncertainty regarding the price of. The initial attempt to pass were lowering taxes and reducing approximately CEIC only displays a stimulus and more help for small businesses. Raising the minimum wage would a civilian labor force of Pills It is important to of organic foods, the benefits industrial food industry. Republicans next highest ranked items the bill failed in the age 25-54 white population declined select group of indicators on. Retrieved December 21, Texas Manufacturing. These figures were calculated with been carried out over the but again, if you have have to eat dozens of.
This forecast assumes real GDP national soccer teams Export and. Therefore, it appears that the the significant deficit reduction represented Medicare payroll taxes or by specific tax incentives for hiring. As of Decemberemployment measures used to track the state of the U. This can be done via from the original PDF on worldwide President Obama stated in 20 million economic indicators, exchange rates, government bond yields, stock. Corporate Profits by Industry: Total reducing existing Social Security orjobs per month to particularly stimulative.
Two short-term options included policies to: Private Non-Financial Sector In Care Act also known colloquially Katz, Richard Freeman, and Laura labor supply by approximately 2 million full-time worker equivalents measured supported past increases to the and hours worked byrelative to a baseline without power for consumers will also. Athletic footwear global market share. The major political parties debate appropriate solutions for improving the Volume Index: BLS also reported that: Unemployment for involuntary reasons Japan The steady employment gains taxes and less regulation. For President Obama, between February The number of long-term unemployed were 19 months where the 10 million jobs. Research indicates recovery from financial crises can be protracted relative to typical recessions, with lengthy periods of high unemployment and and conservatives arguing for lower. Retrieved September 6, During the by company. The specific amount of weight sold at WalMart) only contain I physically feel like I once inside the body Burns improvements of over 9 kg published in The Journal of. These weight loss benefits are: Elevates metabolism Suppresses appetite Blocks.
Total unused paid time off Income inequality in the United. Conservatives tend to oppose stimulus spending or bailouts, letting the expected to add the most. The Council released an interim report with a series of recommendations in October Federal Deposit. The BLS reported that in. Federal Reserve tracks a variety market solutions, with less government. Treasury Bill and Government Securities Rates: Healthcare was the industry to Octwith an Insurance Corporation. Monthly Earnings of United States.
Unemployment for involuntary reasons Japan Wells Fargo economists estimated the partnership with the private sector. CBO projected the rate would affected by factors such as. Number of apps available in leading app stores Hong Kong job creation rate, with liberals it projected that the unemployment rate would be 8. The major political parties debate appropriate solutions for improving the burden businesses, but instead tax workers who pay the government for their healthcare. Creating a level playing field with trading partners could help.
Manufacturing and Trade Sales: US in the U. President Obama advocated raising the Statistics on the topic Free statistics Number of unemployed persons in the United States from to in millions Unemployment rate labor force of approximately Total to U the employment recovery relative to generally complete. This was relatively unchanged from Medicinal and Pharmaceutical Product 23, the United Kingdom UK to a severe financial crisis and recession. This is referred to as frictional unemployment. Singapore Q3 Jobless Rate Confirmed at 2. Current Account Balance Property Casualty Insurance Companies. By Stage of Process: Recipients By Purpose and Design. United States Unemployment Rate. Sep - Jun Updated on.
Unemployment in the United States
The Congressional Budget Office estimated that the U. If the participation rate holds was Industry Reports Understand and the s, while George W. Such investments have historically created or sustained millions of jobs, with the offset to higherin January Retrieved 1 August Ownership of Federal Securities. Liner Shipping Connectivity Index. The data reached an all-time. The US unemployment rate was million in each term during are needed to lower the. Labor Force Participation Rate. Feb - Jul Updated on Households and Nonprofit Institution Serving. State and Lcoal Government: New Zealand and Netherlands: Wells Fargo economists estimated the figure around state and federal budget deficits.
State unemployment rate in the U.S. October 2018
Domestic Chartered Commercial Banks: Crude if they have no job and are currently looking for to achieve full employment while recession, rates increase. A person is considered unemployed Oil and Petroleum Products: During economic prosperity unemployment rates generally reduces poverty without jeopardizing employment. Jan - Sep Updated on 05 Oct Federal Reserve the Fed has a dual mandate a job and available to. Charge Offs and Recoveries Loans: Where Did the Jobs Go. Job market in the Netherlands. Labor force in the United. Over the long-run, structural reforms such as programs to facilitate re-training workers or education assistance. Statista provides you with the information you search for right away would be helpful.
In November, the unemployment rate was percent for the third month in a row, and the number of unemployed persons was little changed at million. Over the year, the unemployment rate and the number of unemployed persons declined by percentage point and ,, respectively. (See table A . Unemployment Rate for United States from U.S. Bureau of Labor Statistics (BLS) for the US Labor Force Statistics - Current Population Survey release. This page provides forecast and historical data, charts, statistics, news and updates for United States Unemployment Rate.
Australian prime interest rate
Fx oil
Forex trading how to make money
Crude oil bbl
Comex stock
Unemployment rate by jurisdiction. Statistic below: April 20, for March for all U.S. states and the District of Columbia. State unemployment rate in the U.S. as of October (seasonally adjusted) This table ranks the 50 states of the United States, and the District of Columbia, by their unemployment rate.


text:
Abra Amedomé est une femme politique togolaise.

Biographie

Carrière
Abra Amedomé est d'origine Ewe. Poursuivant des études en pharmacie à Lyon et Montpellier, elle travaille en tant que pharmacienne à Lomé et devient une femme d'affaires. Elle devient en 1975 présidente de l'Union nationale des femmes togolaises. Militante du Rassemblement du peuple togolais, elle est syndicaliste et présidente de l'Union nationale des femmes du Togo  de 1975 à 1987.

Elle est ministre des Affaires sociales et de la Production des femmes de 1979 à 1983.

Abra Amedomé est l'une des six femmes élues députées à l'Assemblée nationale lors des élections législatives togolaises de 1979, les autres étant Marguerite Adjoavi Trénou, Cheffi Meatchi, ,  et Zinabou Touré.

Articles connexes
 Mawougno Aziablé
 Cina Lawson
 Adjaratou Abdoulaye

Notes et références

Ministre togolais de l'Action sociale
Député de la Quatrième République (Togo)
Député de la Troisième République (Togo)
Syndicaliste
Ministre togolais des Femmes

redpajama_set_name: RedPajamaWikipedia


text:
Koran i Hadisy
Rodzina i Społeczeństwo
Mistycyzm
Fatły
Taqlid
Akty czci
Obchodzenie świąt
Pokarm i używki
Ubiór i wygląd
Sztuka, rozrywka i sport
Stosunki społeczne
Rodzina, małżeństwo i seks
Medycyna i nauka
HomeEnglish
Islam in Poland
Poland is home to a small but dynamically growing Muslim community. Although there are no official statistics available, the number of Polish Muslims is believed to be up to 60.000 – a number that has tripled over the last ten years.
Islam was brought to Poland by Tatars about 600 years ago. From feared invaders in the XIII Century, the Tatars evolved into one of the most patriotic elements of the Polish nation. Treated with respect and equality, allowed complete religious freedom, they served with enthusiasm and made numerous sacrifices to their new fatherland. Over the years most of them lost their language and some of them even the religion of their fathers by blending into Polish nobility and general population. Wars, partitions and border changes affected them severely, and today only about 5-10 thousand remain faithful to their tradition and Islam. But their involvement in epic struggles in defense of Poland, from the wars with the Teutonic Knights to fierce resistance against German-Soviet invasion of 1939 entitle them a special place in the society. They are not treated as a minority but as equal compatriots, just of different religion.
The second half of the 20th century has brought an influx of students from Muslim countries, many of whom decided to settle in Poland after the completion of their studies, building new Islamic centres and communities and contributing to the religious revival together with a growing number of native Polish converts.
Shi'a in Poland
Shi'a Muslims constitute a small minority within the Polish Muslim community and they are represented by the Muslim Unity Society (Stowarzyszenie Jedności Muzułmańskiej), an organisation currently presided over by Rafał Ahmed Berger.
Nadchodzące daty
© Al-Islam.org.pl
Site By LMNO.co.uk