Get the schema type for the fact
@param DOMXPathNavigator $fact
@return string|bool
@throws \Exception
422988
public static function getType( $fact )
	{
		if ( ! $fact instanceof DOMXPathNavigator )
		{
			throw new \Exception( "Invalid fact variable passed to FactValues::isItem" );
		}

		return \XBRL_Types::getInstance()->getTypeForDOMNode( $fact->getUnderlyingObject() );
	}
271205
private function getTypeFromTitle($title)
    {
        $title_types = array(
            'stylesheet'    => 'UserStylesheet',
            'script'        => 'UserScript',
            'title'         => 'StoryTitle',
        );

        foreach ($title_types as $type => $name) {
            if ($title == $name) {
                return $type;
            }
        }

        // Let's assume if the title isn't on the list, the entity is a passage
        return 'passage';
    }
395018
public static function isNull( $fact )
	{
		if ( ! $fact instanceof DOMXPathNavigator )
		{
			throw new \Exception( "Invalid fact variable passed to FactValues::isNull" );
		}

		if ( ! $fact->getHasAttributes() ) return false;

		$attributes = $fact->CloneInstance();
		return $attributes->MoveToAttribute( "nil", \XBRL_Constants::$standardPrefixes[ STANDARD_PREFIX_SCHEMA_INSTANCE ] );
	}
664919
private function getVersion(stdClass $schema)
    {
        return property_exists($schema, '$schema') && is_string($schema->{'$schema'}) ?
            $schema->{'$schema'} :
            Registry::VERSION_CURRENT;
    }
616831
public function getContentType()
		{

			foreach (self::$contentTypeMap as $ct => $type) {
				if ($type == $this->type) {
					return $ct;
				}
			}
			return false;

		}
400439
public function Filter( $facts, $variableSet )
	{
		// Look for the variable
		$vars = $variableSet->getBindingsAsVars();
		$clark = str_replace( "{}", "", "{{$this->variable['namespace']}}{$this->variable['name']}" );
		if ( ! isset( $vars[ $clark ] ) )
		{
			// Should probably throw some kind of error here
			throw XPath2Exception::withErrorCodeAndParam( "XPST0008", Resources::XPST0008, $clark );
		}

		/**
		 * @var \DOMNode[] $candidates
		 */
		$candidate = null;
		$var = $vars[ $clark ];
		if ( $var instanceof XPath2NodeIterator )
		{
			$node = reset( $var->ToList() );
			if ( is_null( $node ) )
			{
				throw XPath2Exception::withErrorCodeAndParam( "XPST0008", Resources::XPST0008, $clark );
			}

			$candidate = $node->getUnderlyingObject();
		}
		else
		{
			$candidate = $var->getUnderlyingObject();
		}

		$matched = array();
		$notMatched = array();

		$candidateParent = $candidate->parentNode;

		// The fact can be an
		foreach ( $facts as $fact )
		{
			$node = $fact->getUnderlyingObject();
			$factParent = $node->parentNode;

			if ( $candidateParent->isSameNode( $factParent ) )
			{
				$matched[] = $fact->CloneInstance();
			}
			else
			{
				$notMatched[] = $fact->CloneInstance();
			}
		}

		return DocumentOrderNodeIterator::fromItemset( $this->complement ? $notMatched : $matched );

		return $facts;
	}
221285
public function getValueType()
	{
		$xmlType =SchemaTypes::getInstance()->getTypeForDOMNode( $this->domNode );
		// $xmlType = $this->types->getType( $this->domNode->localName, $this->domNode->prefix );
		if ( $xmlType )
		{
			$type = Type::XmlTypeToPHPType( $xmlType );
			if ( $type ) return $type;
		}
		return Type::string;
	}
1340770
public function isDRSValidForFact( $fact,  $drs)
	{
		foreach ( $drs as $hypercube => $roles )
		{
			foreach ( $roles as $role => $hypercubeItems )
			{
				if ( ! isset( $hypercubes[ $hypercube ][ $role ] ) )
				{
					$closed = isset( $hypercubeItems['parents'][ $fact['label'] ]['closed'] ) && $hypercubeItems['parents'][ $fact['label'] ]['closed'];

					if ( ! $this->isHypercubeDimensionallyValid( $fact['contextRef'], $hypercubeItems, $closed ) ) continue;

					return true;
				}
			}
		}

		return false;
	}
377754
public function pastableFactsOfType(GedcomRecord $record, Collection $types): Collection
    {
        // The facts are stored in the session.
        return (new Collection(Session::get('clipboard', [])))
            ->flatten(1)
            ->reverse()
            ->map(static function (array $clipping) use ($record): Fact {
                return new Fact($clipping['factrec'], $record, md5($clipping['factrec']));
            })
            ->filter(static function (Fact $fact) use ($types): bool {
                return $types->contains($fact->getTag());
            });
    }
1344946
private function getFactDetails( $variableSet, $types, $fact )
	{
		$factHash = spl_object_hash( $fact );

		if ( ! isset( $this->factCache[ $factHash ] ) )
		{
			// Record the QName and other cache information if not defined
			if ( ! isset( $this->factQNameCache[ $factHash ] ) )
			{
				// Look up the namespace to find the schema prefix
				$factNamespace = $fact->getNamespaceURI();
				if ( ! isset( $this->factNamespaceCache[ $factNamespace ] ) )
				{
					$factTaxonomy = $variableSet->xbrlTaxonomy->getTaxonomyForNamespace( $fact->getNamespaceURI() );
					// Record the mapping
					$this->factNamespaceCache[ $factNamespace ] = $factTaxonomy->getPrefix();
				}
				// Retrieve the prefix to create a QName
				$factPrefix = $this->factNamespaceCache[ $factNamespace ];
				$factQName = new QName( $factPrefix, $fact->getNamespaceURI(), $fact->getLocalName() );

				// And record it against the fact hash
				$this->factQNameCache[ $factHash ] = $factQName;
				// If there is no element cached for the QName get it can record it
				if ( ! isset( $this->factElementCache[ $factQName->clarkNotation() ] ) )
				{
					$this->factElementCache[ $factQName->clarkNotation() ] = $types->getElement( $factQName->localName, $factQName->prefix );
				}
			}

			$factQName = $this->factQNameCache[ $factHash ];

			if ( ! isset( $this->factComponentsCache[ $factHash ] ) )
			{
				$this->factComponentsCache[ $factHash ] = $this->getFactComponents( $variableSet, $fact );
			}

			$factComponents = $this->factComponentsCache[ $factHash ];
			$factComponents['factHash'] = $factHash;
			$factComponents['qname'] = $factQName;
			$factComponents['fact'] = $fact;

			$this->factCache[ $factHash ] = $factComponents;
		}

		return $this->factCache[ $factHash ];
	}
16825
public static function GetXmlTypeCodeFromType( $type )
	{
		/**
		 * @var TypeCode
		 */
		switch ( $type->getTypeCode() )
		{
			case TypeCode::Boolean:
				return XmlTypeCode::Boolean;
			case TypeCode::Int16:
				return XmlTypeCode::Short;
			case TypeCode::Int32:
				return XmlTypeCode::Int;
			case TypeCode::Int64:
				return XmlTypeCode::Long;
			case TypeCode::UInt16:
				return XmlTypeCode::UnsignedShort;
			case TypeCode::UInt32:
				return XmlTypeCode::UnsignedInt;
			case TypeCode::UInt64:
				return XmlTypeCode::UnsignedLong;
			case TypeCode::SByte:
				return XmlTypeCode::Byte;
			case TypeCode::Byte:
				return XmlTypeCode::UnsignedByte;
			case TypeCode::Single:
				return XmlTypeCode::Float;
			case TypeCode::Decimal:
				return XmlTypeCode::Decimal;
			case TypeCode::Double:
				return XmlTypeCode::Double;
			case TypeCode::Char:
			case TypeCode::String:
				return XmlTypeCode::String;
			default:
				$typeName = $type->getTypeName();
				if ($typeName == DOMXPathNavigator::$CLASSNAME )
					return XmlTypeCode::Node;
				if ($typeName == UntypedAtomic::$CLASSNAME )
					return XmlTypeCode::UntypedAtomic;
				if ($typeName == Integer::$CLASSNAME )
					return XmlTypeCode::Integer;
				if ($typeName == DateTimeValue::$CLASSNAME )
					return XmlTypeCode::DateTime;
				if ($typeName == DateValue::$CLASSNAME )
					return XmlTypeCode::Date;
				if ($typeName == TimeValue::$CLASSNAME )
					return XmlTypeCode::Time;
				if ($typeName == DurationValue::$CLASSNAME )
					return XmlTypeCode::Duration;
				if ($typeName == YearMonthDurationValue::$CLASSNAME)
					return XmlTypeCode::YearMonthDuration;
				if ($typeName == DayTimeDurationValue::$CLASSNAME )
					return XmlTypeCode::DayTimeDuration;
				if ($typeName == GYearMonthValue::$CLASSNAME )
					return XmlTypeCode::GYearMonth;
				if ($typeName == GYearValue::$CLASSNAME )
					return XmlTypeCode::GYear;
				if ($typeName == GDayValue::$CLASSNAME )
					return XmlTypeCode::GDay;
				if ($typeName == GMonthValue::$CLASSNAME )
					return XmlTypeCode::GMonth;
				if ($typeName == GMonthDayValue::$CLASSNAME )
					return XmlTypeCode::GMonthDay;
				if ($typeName == QNameValue::$CLASSNAME )
					return XmlTypeCode::QName;
				if ($typeName == AnyUriValue::$CLASSNAME )
					return XmlTypeCode::AnyUri;
				if ($typeName == HexBinaryValue::$CLASSNAME )
					return XmlTypeCode::HexBinary;
				if ($typeName == Base64BinaryValue::$CLASSNAME )
					return XmlTypeCode::Base64Binary;
				if ($typeName == IDREFSValue::$CLASSNAME )
					return XmlTypeCode::Idref;
				if ($typeName == ENTITIESValue::$CLASSNAME )
					return XmlTypeCode::Entity;
				if ($typeName == NMTOKENSValue::$CLASSNAME )
					return XmlTypeCode::NmToken;
				return XmlTypeCode::Item;
		}
	}
184056
public function copyFact(Fact $fact): void
    {
        $clipboard   = Session::get('clipboard', []);
        $record_type = $fact->record()::RECORD_TYPE;
        $fact_id     = $fact->id();

        // If we are copying the same fact twice, make sure the new one is at the end.
        unset($clipboard[$record_type][$fact_id]);

        $clipboard[$record_type][$fact_id] = [
            'factrec' => $fact->gedcom(),
            'fact'    => $fact->getTag(),
        ];

        // The clipboard only holds a limited number of facts.
        $clipboard[$record_type] = array_slice($clipboard[$record_type], -self::CLIPBOARD_SIZE);

        Session::put('clipboard', $clipboard);
    }
1301739
protected function getContentType($type, $version)
    {
        if ($type === 'css') {
            return 'text/css';
        } else if ($type === 'js') {
            return 'text/javascript';
        } else if ($type === 'image') {
            $fileExtension = pathinfo($version, PATHINFO_EXTENSION);
            
            if ($fileExtension === 'svg') {
                return 'image/svg+xml';
            } else if ($fileExtension === 'jpg') {
                return 'image/jpeg';
            } else if ($fileExtension === 'gif') {
                return 'image/gif';
            } else if ($fileExtension === 'png') {
                return 'image/png';
            }
        }
    }
163667
public function getDocumentClass()
    {
        $documentClass = false;
        if (isset($this->schema->{'x-documentClass'})) {
            $documentClass = $this->schema->{'x-documentClass'};
        }
        return $documentClass;
    }
438228
public function getBindingsAsVars( $vars = array() )
	{
		// $vars = array_merge( $existingVars, $this->parameters );
		$vars = $this->getParametersAsVars( $vars );

		foreach( $this->factVariableBindings as $bindingQName => /** @var \XBRL\Formulas\factVariableBinding $varBinding */ $varBinding )
		{
			if ( $varBinding->isFallback )
			{
				$current = $varBinding->yieldedFact;
			}
			else
			{
				// Using current makes sure the fact is set and the binding variables are correct
				if ( ! $varBinding->valid() ) $varBinding->rewind();
				$current = $varBinding->current();
			}
			if ( $current instanceof XPath2NodeIterator ) $current->Reset();
			$vars[ $bindingQName ] = $current;
			$vars = array_merge( $vars, $varBinding->getAdditionalVars() );
		}

		foreach( $this->generalVariableBindings as $bindingQName => /** @var VariableBinding $varBinding */ $varBinding )
		{
			// Using current makes sure the fact is set and the binding variables are correct
			// $vars[ $bindingQName ] = $this->variablesByQName[ $bindingQName ]->bindAsSequence ? $varBinding->facts : $varBinding->current();
			if ( ! $varBinding->valid() ) $varBinding->rewind();
			$current = $varBinding->current();
			if ( $current instanceof XPath2NodeIterator )
			{
				// BMS 2018-04-04 Test 0023 V-03 fails because the vars are being reset presumably because a var is not a clone
				$current = $current->CloneInstance();
				$current->Reset();
			}
			else if ( $current instanceof XPathNavigator)
			{
				$current = $current->CloneInstance();
			}
			$vars[ $bindingQName ] = $current;
		}

		return $vars;
	}
397229
public function current()
	{
		$fact = parent::current();
		if ( $fact )
		{
			if ( ! $this->uncoveredAspectFacts )
			{
				$coveredFact = $fact;

				if ( $this->var->bindAsSequence )
				{
					if ( $coveredFact instanceof XPath2NodeIterator )
					{
						// Get the first item
						$coveredFact->rewind();
						$coveredFact = $coveredFact->current();  // Should be DOMXPathNavigator
					}
				}

				$this->uncoveredAspectFacts = array_fill_keys( $this->aspectsDefined, $coveredFact );
				$this->uncoveredAspectFacts = array_merge( $this->uncoveredAspectFacts, array_fill_keys( $this->aspectsCovered, null ) );
			}
		}

		return $fact;
	}
1041441
private function getFactComponents( $variableSet, $fact )
	{
		// Lookup the contextRef and unitRef
		$contextRef = FactValues::getContextRef( $fact );
		$unitRef = FactValues::getUnitRef( $fact );

		return array(
			'contextRef' => $contextRef,
			'unitRef' => $unitRef,
		);
	}