docs: def deserialize(cls, did_doc: dict) -> 'DIDDoc':
          """
          Construct DIDDoc object from dict representation.
  
          Raise BadIdentifier for bad DID.
  
          :param did_doc: DIDDoc dict reprentation.
          :return: DIDDoc from input json.
          """
  
          rv = None
          if 'id' in did_doc:
              rv = DIDDoc(did_doc['id'])
          else:  # get DID to serve as DID document identifier from first public key
              if 'publicKey' not in did_doc:
                  LOGGER.debug('DIDDoc.deserialize <!< no identifier in DID document')
                  raise AbsentDIDDocItem('No identifier in DID document')
              for pubkey in did_doc['publicKey']:
                  pubkey_did = canon_did(resource(pubkey['id']))
                  if ok_did(pubkey_did):
                      rv = DIDDoc(pubkey_did)
                      break
              else:
                  LOGGER.debug('DIDDoc.deserialize <!< no identifier in DID document')
                  raise AbsentDIDDocItem('No identifier in DID document')
  
          for pubkey in did_doc['publicKey']:  # include public keys and authentication keys by reference
              pubkey_type = PublicKeyType.get(pubkey['type'])
              authn = any(
                  canon_ref(rv.did, ak.get('publicKey', '')) == canon_ref(rv.did, pubkey['id'])
                  for ak in did_doc.get('authentication', {}) if isinstance(ak.get('publicKey', None), str))
              key = PublicKey(  # initialization canonicalizes id
                  rv.did,
                  pubkey['id'],
                  pubkey[pubkey_type.specifier],
                  pubkey_type,
                  canon_did(pubkey['controller']),
                  authn)
              rv.pubkey[key.id] = key
  
          for akey in did_doc.get('authentication', {}):  # include embedded authentication keys
              pk_ref = akey.get('publicKey', None)
              if pk_ref:
                  pass  # got it already with public keys
              else:
                  pubkey_type = PublicKeyType.get(akey['type'])
                  key = PublicKey(  # initialization canonicalized id
                      rv.did,
                      akey['id'],
                      akey[pubkey_type.specifier],
                      pubkey_type,
                      canon_did(akey['controller']),
                      True)
                  rv.pubkey[key.id] = key
  
          for service in did_doc.get('service', {}):
              endpoint = service['serviceEndpoint']
              svc = Service(  # initialization canonicalizes id
                  rv.did,
                  service.get('id', canon_ref(rv.did, 'assigned-service-{}'.format(len(rv.service)), ';')),
                  service['type'],
                  rv.add_service_pubkeys(service, 'recipientKeys'),
                  rv.add_service_pubkeys(service, ['mediatorKeys', 'routingKeys']),
                  canon_ref(rv.did, endpoint, ';') if ';' in endpoint else endpoint,
                  service.get('priority', None))
              rv.service[svc.id] = svc
  
          return rv